Introduction
The texture mapping implementation in OpenGL is a tiresome procedure. And sometimes it is worth it to have some simple operation just calling the name of the image file for texture mapping without a lot of stages with the conditions implementation required.
Background
The procedure of texture mapping implementation in OpenGL just calling the name of the image file has been developed with the application of the class CImage
. The demo project ImgTexture has been derived from the standard MFC Cube Sample project renamed with the CodeProject ProjRename program.
Using the Code
The global procedure LoadImgTexture(LPCTSTR fName)
and two related procedures GetImgBitmap(CImage * pImg)
and LoadGLTexture(BITMAP * pBm)
are located in the GlobGLTexture.cpp file inserted into ImgTexture project with the menu PROJECT->Add Existing Item... command.
The procedure for texture mapping:
GLuint LoadImgTexture(LPCTSTR fName)
{
CImage img;
HRESULT hResult = img.Load(fName);
if (FAILED(hResult)) {
CString fmt;
fmt.Format(_T("Error %d\n%s"), hResult, _com_error(hResult).ErrorMessage());
MessageBox(NULL, fmt + _T("\nin file:\n") + (CString)fName, _T("Error:"), MB_OK | MB_ICONERROR);
return FALSE;
}
CBitmap * pBm = NULL;
if (img.GetBPP() != 24)
{
CImage tmg;
tmg.Create(img.GetWidth(), img.GetHeight(), 24);
img.BitBlt(tmg.GetDC(), CPoint(0, 0));
pBm = GetImgBitmap(&tmg);
}
else
pBm = GetImgBitmap(&img);
BITMAP BMP;
pBm->GetBitmap(&BMP);
return LoadGLTexture(&BMP);
}
The image from the image file loaded with standard CImage procedure
. The default format of the image 24 bit per pixel expected. If the format of the image differes from the default then 24 bit per pixel environment created and the original image is copied into the new one.
And the CBitmap
class draws upon the CImage
class:
CBitmap * GetImgBitmap(CImage * pImg)
{
if (pImg == NULL)
return NULL;
CDC * pDC = new CDC;
if (!pDC->CreateCompatibleDC(CDC::FromHandle(pImg->GetDC())))
return NULL;
CBitmap * pBm = new CBitmap;
pBm->CreateCompatibleBitmap(CDC::FromHandle(pImg->GetDC()), pImg->GetWidth(), pImg->GetHeight());
CBitmap * pBmOld = pDC->SelectObject(pBm);
pImg->BitBlt(pDC->m_hDC, CPoint(0, 0));
pDC->DeleteDC();
return pBm;
}
The BITMAP
structure draws upon the CBitmap
class and implemetnted into texture with the standard OpenGL procedures with the format GL_BGR_EXT
corresponding to 24 bit per pixel format in BITMAP structure
:
GLuint LoadGLTexture(BITMAP * pBm)
{
GLuint texi;
glGenTextures(1, &texi);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glBindTexture(GL_TEXTURE_2D, texi);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pBm->bmWidth, pBm->bmHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, pBm->bmBits);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
return texi;
}
In the original project just CImgTextureView
class has a few changes:
three variables inserted:
int m_texNum;
CWordArray m_globTexture;
int m_view_type;
enum VIEW_TYPE
{
VIEW_DEFAULT,
VIEW_TEXTURE,
};
the original CImgTextureView::Init()
procedure with the procedures related remains unchanged; in CImgTextureView::OnCreate
procedure in demo purposes the two lines of the texture implemetation from the image files in the Data folder of the root directory located:
int CImgTextureView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
Init();
m_globTexture.Add((WORD)LoadImgTexture(_T("Data/MSUN.bmp")));
m_globTexture.Add((WORD)LoadImgTexture(_T("Data/famrt.bmp")));
return 0;
} ;
you may insert here any image files in any pathway valid and as much as you like; in the original CImgTextureView::DrawScene
procedure the block of texture handling inserted:
case VIEW_TEXTURE:
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, (GLuint)m_globTexture.GetAt(m_texNum));
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(2.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f);
glTexCoord2f(2.0f, 2.0f); glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 2.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(2.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(2.0f, 2.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 2.0f); glVertex3f(1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glEnd();
glDisable(GL_TEXTURE_2D);
break;
all the follows Menu and Accelerator Commands has been done with standard AppWizard technologies.
Application Demo Menu and Keyboard Commands
Some menu and some special Accelerator keys arranged in order to demonstrate the ImgTexture project implementation:
- Menu File->Open - selecting the file with the image for texture mapping;
- Menu View->Default - original Cube performance;
- Menu View->Texture - current texture performance;
- Menu View->Next Texture - next texture performance(also Right Arrow click);
- Menu View->Prev Texture - previous texture performance(also Left Arrow click);
Points of Interest
The technology provided above is an attempt to demonstrate one of the simple texture implementation possibilities. The project has been developed in MFC platform. Nevertheless the GlobGLTexture.cpp procedures are also valid in Win32 and are acceptable for use in the Mobile applications.