五彩的箱子(NEHE经典教程MFC下的实现:LESSON12)

不再多说,首先按《基于MFCOpenGL编程》Part 2 Setting up OpenGL on Windows中的介绍,把所有该做的东西都先做好。 这一课讲的是LIST的使用,LIST是在初始化函数里面生成的,也就是说在渲染之前生成的。生成之后是不可改变的,当然,通过下文,大家应该了解到这个“不可改变”是相对的。纹理的生成、光照、颜色还是可以在调用LIST的时候使用的。LIST虽然在程序运行之初生成,但是并不是完全一层不变的东西。

1.增加变量。topcol和boxcol都存储了3X5组数据,用来表示箱顶和除顶部以外的面得5种颜色。

GLuint texture[1]; // Storage For 1 Texture
GLuint box; // Storage For The Box Display List
GLuint top; // Storage For The Top Display List
GLuint xloop; // Loop For X Axis
GLuint yloop; // Loop For Y Axis

GLfloat xrot;
// Rotates Cube On The X Axis
GLfloat yrot; // Rotates Cube On The Y Axis
GLfloat boxcol[5][3];
GLfloat topcol[
5][3];

2.纹理的绑定和生成,贴上代码,具体的就不多说了。

AUX_RGBImageRec* CdemoView::LoadBMP(char* Filename)
{
FILE
*File=NULL; // File Handle

if (!Filename) // Make Sure A Filename Was Given
{
return NULL; // If Not Return NULL
}

File
=fopen(Filename,"r"); // Check To See If The File Exists

if (File) // Does The File Exist?
{
fclose(File);
// Close The Handle
return auxDIBImageLoad(Filename); // Load The Bitmap And Return A Pointer
}

return NULL; // If Load Failed Return NULL
}

int CdemoView::LoadGLTextures(void)
{
int Status=FALSE; // Status Indicator

AUX_RGBImageRec
*TextureImage[1]; // Create Storage Space For The Texture

memset(TextureImage,
0,sizeof(void*)*1); // Set The Pointer To NULL

// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
if (TextureImage[0]=LoadBMP("Data/Cube.bmp"))
{
Status
=TRUE; // Set The Status To TRUE

glGenTextures(
1, &texture[0]); // Create The Texture

// Typical Texture Generation Using Data From The Bitmap
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexImage2D(GL_TEXTURE_2D,
0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}

if (TextureImage[0]) // If Texture Exists
{
if (TextureImage[0]->data) // If Texture Image Exists
{
free(TextureImage[
0]->data); // Free The Texture Image Memory
}

free(TextureImage[
0]); // Free The Image Structure
}

return Status; // Return The Status

}

3.List的生成,这部分是比较重要的。关于什么事List,不知道的就自己查查吧,是个很好用的东西。不要忘记把它放到初始化函数里面去,否则程序不会运行。

void CdemoView::BuildLists(void)
{
box
=glGenLists(2); // Generate 2 Different Lists
glNewList(box,GL_COMPILE); // Start With The Box List
glBegin(GL_QUADS);
// Bottom Face
glNormal3f( 0.0f,-1.0f, 0.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);
// Front Face
glNormal3f( 0.0f, 0.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);
// Back Face
glNormal3f( 0.0f, 0.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);
// Right face
glNormal3f( 1.0f, 0.0f, 0.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);
// Left Face
glNormal3f(-1.0f, 0.0f, 0.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();
glEndList();
top
=box+1; // Storage For "Top" Is "Box" Plus One
glNewList(top,GL_COMPILE); // Now The "Top" Display List
glBegin(GL_QUADS);
// Top Face
glNormal3f( 0.0f, 1.0f, 0.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);
glEnd();
glEndList();

}

4.直接到RenderScene了。注意这个双循环,外面是从1到5,里面依次运行1,2,3,4,5次。

void CdemoView::RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer

glBindTexture(GL_TEXTURE_2D, texture[
0]);
for (yloop=1;yloop<6;yloop++)
{
for (xloop=0;xloop<yloop;xloop++)
{
glLoadIdentity();
// Reset The View
glTranslatef(1.4f+(float(xloop)*2.8f)-(float(yloop)*1.4f),((6.0f-float(yloop))*2.4f)-7.0f,-20.0f);
glRotatef(
45.0f-(2.0f*yloop)+xrot,1.0f,0.0f,0.0f);
glRotatef(
45.0f+yrot,0.0f,1.0f,0.0f);
glColor3fv(boxcol[yloop
-1]);
glCallList(box);
glColor3fv(topcol[yloop
-1]);
glCallList(top);
}
}
}

5.加些用来控制的代码。

void CdemoView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
switch(nChar)
{
case VK_RIGHT:
yrot
+=0.3f;
break;
case VK_LEFT:
yrot
-=0.3f;
break;
case VK_UP:
xrot
-=0.3f;
break;
case VK_DOWN:
xrot
+=0.3f;
break;
}
InvalidateRect(NULL,FALSE);
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

6.看看运行的结果吧。

原文地址:https://www.cnblogs.com/unsigned/p/1703412.html