OpenGL Study 5

原创 2007年10月15日 22:23:00

 

 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

OpenGL学习之路(一)

1 引子 虽然是计算机科班出身,但从小对几何方面的东西就不太感冒,空间想象能力也较差,所以从本科到研究生,基本没接触过《计算机图形学》。为什么说基本没学过呢?因为好奇(尤其是惊叹于三维游戏的逼真,如...
  • three_bird
  • three_bird
  • 2016年05月07日 10:58
  • 3279

OpenGL(一)《OpenGL超级宝典第五版》Windows + VS2013配置

最近开始研究OpenGL,于是在网上搜索了相关书籍,适合我这种小白来说,找到本合适的书籍不容易,有人就推荐了OpenGL蓝宝书《OpenGL超级宝典》和OpenGL红宝书《OpenGL编程指南》。为什...
  • fjdmy001
  • fjdmy001
  • 2016年12月02日 11:46
  • 3866

VS2012 中完整配置OpenGL超级宝典(第五版)编译环境

在接触OpenGL中,配置显得相当麻烦,特别是在VS2012下配置时,存在许多问题,而网上的很多方法仅仅适用于VS2008,甚至仅适用于VC6.0,笔者经过自身的实践,参考了许多网上的资料,总结了一下...
  • w540982016044
  • w540982016044
  • 2014年03月15日 15:58
  • 2445

opengl study

  • 2012年11月04日 19:30
  • 644KB
  • 下载

(Computer Graphics) A 3D Case Study Using Opengl.zip

  • 2008年07月02日 11:20
  • 1015KB
  • 下载

opencv & qt study-(5)-操作图像中的像素

在(3)中我们已经初步的了解了Mat这个类,在这个类中存储了图像的所有信息及图像的数据。在这里通过一些方法来访问图像中的像素,可以了解到cv::Mat类中的一些成员变量的使用和成员函数的使用,可以对c...
  • chengfei609
  • chengfei609
  • 2015年06月17日 21:16
  • 1094

Daily-C-Study(5):C语言extern关键字

Daily-C-Study(5):C语言extern关键字 成于坚持,败于止步 extern,外面的、外来的意思。那它有什么作用呢?举个例子:假设你在大街上看到一个黑皮肤绿眼睛红头发的美女(外星人...
  • xinyuwuxian
  • xinyuwuxian
  • 2013年05月30日 19:28
  • 7025

转载于 http://mylinux.5d6d.com/study/27.htm

转载于 http://mylinux.5d6d.com/study/27.htm Perl基础 脚本 Perl 是一种脚本语言,它在每次运行前都需要编译。在unix/linux下,通常p...
  • bigliu819
  • bigliu819
  • 2012年08月14日 13:43
  • 2820

Vim Tutorial Study(5)

Chapter 5 Windows Split the screen into multiple windows and edit more than one file simultaneously...
  • xuxinhui
  • xuxinhui
  • 2011年02月01日 10:34
  • 197

Study 3D《5、演算齐次坐标的变换》

齐次坐标,别忘了哦!以3D中,它可是如意棒棒哦 设有以下关系: P = |x y z 1| 则(中间过程自己算吧^_^): 设有下关系: 则(中间过程自己算吧^_^): 由...
  • jiangdragon
  • jiangdragon
  • 2012年05月17日 14:03
  • 787
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OpenGL Study 5
举报原因:
原因补充:

(最多只允许输入30个字)