OpenGL Study 5

来源:互联网 发布:电信网络拓扑图 编辑:程序博客网 时间:2024/06/05 01:11

 

 Lesson07

使用三种映射滤镜给立方体添加纹理:线性映射(LINEAR),NEAREST映射,MipMap映射;三者的效果渐增,处理速度递减。

添加通过键盘控制立方体的旋转速度,距离屏幕的距离和映射方法的选择。

在模型中添加光照:环境光(Ambient)和散射光(Diffuse),通过键盘来打开和关闭光照。

创建纹理:

//all setup for OpenGL goes here
bool InitGL(GLvoid)
{
    
if(!CreateTextures(_T("Data/CrateSmall.bmp")))
        
return false;

    glEnable(GL_TEXTURE_2D);
    
//enable smooth shading
    glShadeModel(GL_SMOOTH);
    
    
//black background
    glClearColor(0.0f,0.0f,0.0f,0.5f);
    
    
//setup the depth buffer
    glClearDepth(1.0f);
    
//enable depth testing
    glEnable(GL_DEPTH_TEST);
    
//the type of depth test to do
    glDepthFunc(GL_LEQUAL);

    
//really nice perspective calculation
    glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);

    
//Set up the lighting
    
//set the amount of ambient light that light1 will give off
    glLightfv(GL_LIGHT1,GL_AMBIENT,LightAmbient);
    
//set the amount of diffues light that light1 will give off
    glLightfv(GL_LIGHT1,GL_DIFFUSE,LightDiffuse);
    
//set the position of the light
    glLightfv(GL_LIGHT1,GL_POSITION,LightPosition);
    
//Enable the light but it does not start work until GL_LIGHTING is enabled
    glEnable(GL_LIGHT1);

    
return true;
}

在创建纹理时,开始使用的图片是256×256大小的,运行时总是在glTexImage2D()这个函数出出现越界访问错误,分析一下越界信息,发现程序要访问BMP.bmBits[256][256]处的值,这当然越界,可是为什么呢?无奈之下,把图片缩小为128×128的以后,程序就可以正常运行,晕!查看有关glTexImage2D()的函数,纹理大小都只要no more than 256就可以,为什么,自己的程序就不能使用256的?一直没有搞懂,如果那位高手,知道希望多多指教,谢谢!

加载纹理:

bool CreateTextures(LPTSTR szFileName)                    // Creates Texture From A Bitmap File
{
    HBITMAP hBMP;                                                        
// Handle Of The Bitmap
    BITMAP    BMP;                                                        // Bitmap Structure

    glGenTextures(
3&texture[0]);                                            // Create The Texture
    hBMP=(HBITMAP)LoadImage(GetModuleHandle(NULL), szFileName, IMAGE_BITMAP, 00, LR_CREATEDIBSECTION | LR_LOADFROMFILE );

    
if (!hBMP)                                                            // Does The Bitmap Exist?
        return false;                                                    // If Not Return False

    GetObject(hBMP, 
sizeof(BMP), &BMP);                                    // Get The Object
                                                                        
// hBMP:        Handle To Graphics Object
                                                                        
// sizeof(BMP): Size Of Buffer For Object Information
                                                                        
// &BMP:        Buffer For Object Information

    glPixelStorei(GL_UNPACK_ALIGNMENT, 
4);                                // Pixel Storage Mode (Word Alignment / 4 Bytes)

    
// Typical Texture Generation Using Data From The Bitmap
    
//Create Nearest Filtered Texture
    glBindTexture(GL_TEXTURE_2D, texture[0]);                                // Bind To The Texture ID
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);    // Linear Min Filter
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);    // Linear Mag Filter
    glTexImage2D(GL_TEXTURE_2D, 03, BMP.bmWidth, BMP.bmHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, BMP.bmBits);

    
//Create Linear Filtered Texture
    glBindTexture(GL_TEXTURE_2D,texture[1]);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D,
0,3,BMP.bmWidth,BMP.bmHeight,0,GL_RGB,GL_UNSIGNED_BYTE,BMP.bmBits);

    
//Create MipMapped Texture
    glBindTexture(GL_TEXTURE_2D,texture[2]);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
    gluBuild2DMipmaps(GL_TEXTURE_2D,
3,BMP.bmWidth,BMP.bmHeight,GL_RGB,GL_UNSIGNED_BYTE,BMP.bmBits);


    DeleteObject(hBMP);                                                    
// Delete The Object

    
return true;                                                        // Loading Was Successful
}

显示立方体:

//here we do all the drawings
bool DrawGLScene(GLvoid)
{
    
//clear the screen and the depth buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
//reset the current modelview matrix
    glLoadIdentity();

    
//position and rotate the texture mapped cube
    glTranslatef(0.0f,0.0f,z);
    glRotatef(xrot,
1.0f,0.0f,0.0f);
    glRotatef(yrot,
0.0f,1.0f,0.0f);

    
//bind texture to the cube
    glBindTexture(GL_TEXTURE_2D,texture[filter]);
    glBegin(GL_QUADS);
        
// Front Face
        glNormal3f( 0.0f0.0f1.0f);                    // Normal Pointing Towards Viewer
        glTexCoord2f(0.0f0.0f); glVertex3f(-1.0f-1.0f,  1.0f);    // Point 1 (Front)
        glTexCoord2f(1.0f0.0f); glVertex3f( 1.0f-1.0f,  1.0f);    // Point 2 (Front)
        glTexCoord2f(1.0f1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);    // Point 3 (Front)
        glTexCoord2f(0.0f1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);    // Point 4 (Front)
        
// Back Face
        glNormal3f( 0.0f0.0f,-1.0f);                    // Normal Pointing Away From Viewer
        glTexCoord2f(1.0f0.0f); glVertex3f(-1.0f-1.0f-1.0f);    // Point 1 (Back)
        glTexCoord2f(1.0f1.0f); glVertex3f(-1.0f,  1.0f-1.0f);    // Point 2 (Back)
        glTexCoord2f(0.0f1.0f); glVertex3f( 1.0f,  1.0f-1.0f);    // Point 3 (Back)
        glTexCoord2f(0.0f0.0f); glVertex3f( 1.0f-1.0f-1.0f);    // Point 4 (Back)
        
// Top Face
        glNormal3f( 0.0f1.0f0.0f);                    // Normal Pointing Up
        glTexCoord2f(0.0f1.0f); glVertex3f(-1.0f,  1.0f-1.0f);    // Point 1 (Top)
        glTexCoord2f(0.0f0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);    // Point 2 (Top)
        glTexCoord2f(1.0f0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);    // Point 3 (Top)
        glTexCoord2f(1.0f1.0f); glVertex3f( 1.0f,  1.0f-1.0f);    // Point 4 (Top)
        
// Bottom Face
        glNormal3f( 0.0f,-1.0f0.0f);                    // Normal Pointing Down
        glTexCoord2f(1.0f1.0f); glVertex3f(-1.0f-1.0f-1.0f);    // Point 1 (Bottom)
        glTexCoord2f(0.0f1.0f); glVertex3f( 1.0f-1.0f-1.0f);    // Point 2 (Bottom)
        glTexCoord2f(0.0f0.0f); glVertex3f( 1.0f-1.0f,  1.0f);    // Point 3 (Bottom)
        glTexCoord2f(1.0f0.0f); glVertex3f(-1.0f-1.0f,  1.0f);    // Point 4 (Bottom)
        
// Right face
        glNormal3f( 1.0f0.0f0.0f);                    // Normal Pointing Right
        glTexCoord2f(1.0f0.0f); glVertex3f( 1.0f-1.0f-1.0f);    // Point 1 (Right)
        glTexCoord2f(1.0f1.0f); glVertex3f( 1.0f,  1.0f-1.0f);    // Point 2 (Right)
        glTexCoord2f(0.0f1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);    // Point 3 (Right)
        glTexCoord2f(0.0f0.0f); glVertex3f( 1.0f-1.0f,  1.0f);    // Point 4 (Right)
        
// Left Face
        glNormal3f(-1.0f0.0f0.0f);                    // Normal Pointing Left
        glTexCoord2f(0.0f0.0f); glVertex3f(-1.0f-1.0f-1.0f);    // Point 1 (Left)
        glTexCoord2f(1.0f0.0f); glVertex3f(-1.0f-1.0f,  1.0f);    // Point 2 (Left)
        glTexCoord2f(1.0f1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);    // Point 3 (Left)
        glTexCoord2f(0.0f1.0f); glVertex3f(-1.0f,  1.0f-1.0f);    // Point 4 (Left)
    glEnd();

    
//increase the rotation angle
    xrot+=xspeed;
    yrot
+=yspeed;

    
return true;
}

处理键盘响应:

////////////////win32 functions
//the entry point of our windows application
int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     
int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

     
// TODO: Place code here.
    MSG msg;
    HACCEL hAccelTable;
    
bool done=false;
    
bool vkF1=false;

    
if(!CreateGLWindow(_T("Lesson01"),640,480,16,fullscreen))
    {
        
return 0;
    }

    hAccelTable 
= LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_LESSON01));
    
while(!done)
    {
        
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
        {
            
if(msg.message==WM_QUIT)
            {
                
if(vkF1)
                    vkF1
=false;
                
else
                    done
=true;
            }
            
else
            {
                TranslateMessage(
&msg);
                DispatchMessage(
&msg);
            }
        }
else
        {
            
if(active)
            {
                
if(keys[VK_ESCAPE])
                {
                    keys[VK_ESCAPE]
=false;
                    done
=true;
                }
else
                {
                    DrawGLScene();
                    SwapBuffers(hDC);

                    
//use lp to avoid when you hold key 'L' that light will change from on to off and off to on all the time during holding
                    if(keys['L']&& !lp)
                    {
                        lp
=true;
                        light
=!light;
                        
if(!light)
                        {
                            glDisable(GL_LIGHTING);
                        }
else
                        {
                            glEnable(GL_LIGHTING);
                        }
                    }
                    
if(!keys['L'])
                    {
                        lp
=false;
                    }

                    
//the same reason for fp
                    if(keys['F'&& !fp)
                    {
                        fp
=true;
                        filter
+=1;
                        
if(filter>2)filter=0;
                    }
                    
if(!keys['F'])
                    {
                        fp
=false;
                    }

                    
//if 'Page Up' pressed,move into the screen
                    if(keys[VK_PRIOR])
                    {
                        z
-=0.02f;
                    }

                    
//if 'Page down' pressed ,move near the user
                    if(keys[VK_NEXT])
                    {
                        z
+=0.02f;
                    }

                    
//checking the arrow keys
                    if(keys[VK_UP])
                        xspeed
-=0.01f;
                    
if(keys[VK_DOWN])
                        xspeed
+=0.01f;
                    
if(keys[VK_RIGHT])
                        yspeed
+=0.01f;
                    
if(keys[VK_LEFT])
                        yspeed
-=0.01f;
                }
            }

            
if(keys[VK_F1])
            {
                keys[VK_F1]
=false;
                vkF1
=true;
                KillGLWindow();
                fullscreen
=!fullscreen;
                
if(!CreateGLWindow(_T("Textures,Lighting & Keyboard Tutorial"),640,480,16,fullscreen))
                {
                    
return 0;
                }
            }
        }
    }

    KillGLWindow();
    
return (msg.wParam);
}

 

全部源码:Lesson07.rar

原创粉丝点击