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;
}
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
}
{
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;
}
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);
}
//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 Study 5
- OpenGL study
- Study OpenGL
- OpenGL Study
- OpenGL Study 1
- OpenGL Study 2
- OpenGL Study 3
- OpenGL Study 4
- OpenGL Study 6
- opengl study resource
- How to study Android OpenGL ES
- How to study Android OpenGL ES
- awk study(5)
- Vim Tutorial Study(5)
- vc-study-5
- php study 5 object
- OC-study-5-NSNumber
- study-5系统优化
- 用javascript调用运行本地程序
- something about thread(c#)
- [我学网]如何提高睡眠质量
- 一篇值得你疯狂操练的经典演讲!
- BCB ADO 备份 恢复 任何类型 数据库 文件
- OpenGL Study 5
- 关于MySQL的自增
- asp获取客户端IP地址函数
- 必须知道的社会生活中十二大著名法则
- window.event.srcElement的FF兼容问题
- 英语中的双关
- asp建立文件夹的函数
- eclipse快捷键大全
- asp删除文件夹的函数