OpenGL Study 5

 

 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,  0 0 , 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,  0 3 , 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.0f 0.0f 1.0f );                     //  Normal Pointing Towards Viewer
        glTexCoord2f( 0.0f 0.0f ); glVertex3f( - 1.0f - 1.0f ,   1.0f );     //  Point 1 (Front)
        glTexCoord2f( 1.0f 0.0f ); glVertex3f(  1.0f - 1.0f ,   1.0f );     //  Point 2 (Front)
        glTexCoord2f( 1.0f 1.0f ); glVertex3f(  1.0f ,   1.0f ,   1.0f );     //  Point 3 (Front)
        glTexCoord2f( 0.0f 1.0f ); glVertex3f( - 1.0f ,   1.0f ,   1.0f );     //  Point 4 (Front)
        
//  Back Face
        glNormal3f(  0.0f 0.0f , - 1.0f );                     //  Normal Pointing Away From Viewer
        glTexCoord2f( 1.0f 0.0f ); glVertex3f( - 1.0f - 1.0f - 1.0f );     //  Point 1 (Back)
        glTexCoord2f( 1.0f 1.0f ); glVertex3f( - 1.0f ,   1.0f - 1.0f );     //  Point 2 (Back)
        glTexCoord2f( 0.0f 1.0f ); glVertex3f(  1.0f ,   1.0f - 1.0f );     //  Point 3 (Back)
        glTexCoord2f( 0.0f 0.0f ); glVertex3f(  1.0f - 1.0f - 1.0f );     //  Point 4 (Back)
        
//  Top Face
        glNormal3f(  0.0f 1.0f 0.0f );                     //  Normal Pointing Up
        glTexCoord2f( 0.0f 1.0f ); glVertex3f( - 1.0f ,   1.0f - 1.0f );     //  Point 1 (Top)
        glTexCoord2f( 0.0f 0.0f ); glVertex3f( - 1.0f ,   1.0f ,   1.0f );     //  Point 2 (Top)
        glTexCoord2f( 1.0f 0.0f ); glVertex3f(  1.0f ,   1.0f ,   1.0f );     //  Point 3 (Top)
        glTexCoord2f( 1.0f 1.0f ); glVertex3f(  1.0f ,   1.0f - 1.0f );     //  Point 4 (Top)
        
//  Bottom Face
        glNormal3f(  0.0f , - 1.0f 0.0f );                     //  Normal Pointing Down
        glTexCoord2f( 1.0f 1.0f ); glVertex3f( - 1.0f - 1.0f - 1.0f );     //  Point 1 (Bottom)
        glTexCoord2f( 0.0f 1.0f ); glVertex3f(  1.0f - 1.0f - 1.0f );     //  Point 2 (Bottom)
        glTexCoord2f( 0.0f 0.0f ); glVertex3f(  1.0f - 1.0f ,   1.0f );     //  Point 3 (Bottom)
        glTexCoord2f( 1.0f 0.0f ); glVertex3f( - 1.0f - 1.0f ,   1.0f );     //  Point 4 (Bottom)
        
//  Right face
        glNormal3f(  1.0f 0.0f 0.0f );                     //  Normal Pointing Right
        glTexCoord2f( 1.0f 0.0f ); glVertex3f(  1.0f - 1.0f - 1.0f );     //  Point 1 (Right)
        glTexCoord2f( 1.0f 1.0f ); glVertex3f(  1.0f ,   1.0f - 1.0f );     //  Point 2 (Right)
        glTexCoord2f( 0.0f 1.0f ); glVertex3f(  1.0f ,   1.0f ,   1.0f );     //  Point 3 (Right)
        glTexCoord2f( 0.0f 0.0f ); glVertex3f(  1.0f - 1.0f ,   1.0f );     //  Point 4 (Right)
        
//  Left Face
        glNormal3f( - 1.0f 0.0f 0.0f );                     //  Normal Pointing Left
        glTexCoord2f( 0.0f 0.0f ); glVertex3f( - 1.0f - 1.0f - 1.0f );     //  Point 1 (Left)
        glTexCoord2f( 1.0f 0.0f ); glVertex3f( - 1.0f - 1.0f ,   1.0f );     //  Point 2 (Left)
        glTexCoord2f( 1.0f 1.0f ); glVertex3f( - 1.0f ,   1.0f ,   1.0f );     //  Point 3 (Left)
        glTexCoord2f( 0.0f 1.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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值