VC++课程设计报告
题目:OPENGL 绘制茶杯
设 计 人:
指导教师:
需求说明
问题描述:
OPENGL 绘制茶杯
要求:
任意茶杯模型
需求分析:
1、界面要求:
提供全屏和窗口两种显示模式,仅显示图形,界面简单。
2、功能要求:
提供基本的旋转操作,便于观察。
3、性能要求
显示平滑,操作响应及时。
4、异常处理要求
提供基本的出错信息。
5、将来可能提出的要求
建模,照明,材质的提高,提供缩放等功能
设计思想
1、建立 windows 应用程序框架。
2、模型的绘制。
3、灯光,材质,纹理的添加。
主要函数功能描述:
unsigned char *LoadBitmapFile(char *filename,BITMAPINFOHEADER *bmih)
void Initialize()
void DrawCup()
void Render()
//为设备环境设置像素格式
void SetupPixelFormat(HDC hDC)
//WINDOWS PROCEDURE 事件处理器
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM
lParam)
//WINDOWS 应用程序入口
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR
lpCmdLine,int nCmdShow)
调试和测试
最终显示效果如下:
1、上下键绕 x 轴旋转。
2、翻页键绕 y 轴旋转。
3、左右键绕 z 轴旋转。
用户手册
设计体会:
参考文献:
附录
#define BITMAP_ID 0x4D42
#include
#include
#include
#include
#include
#include
#pragma
#pragma
#pragma
comment(lib,"opengl32.lib")
comment(lib,"glu32.lib")
comment(lib,"glaux.lib")
HDC g_HDC;//全局设备环境
float anglex=300;//旋转角度
float angley=330;
float anglez=180;
BITMAPINFOHEADER bmih;
unsigned char* bitmapData;
unsigned int texture;
bool fullScreen=false;//全屏控制参数
GLUquadricObj *g_Object = gluNewQuadric();//创建二次曲面对象
GLUquadricObj *g_Object2 = gluNewQuadric();
/**********************************************/
//
/**********************************************/
unsigned char *LoadBitmapFile(char *filename,BITMAPINFOHEADER *bmih)
{
FILE *filePtr;
BITMAPFILEHEADER bmfh;
unsigned char *bitmapImage;
int imageIdx=0;
unsigned char tempRGB;
filePtr =fopen(filename,"rb");
if(filePtr==NULL)
return NULL;
fread(&bmfh,sizeof(BITMAPFILEHEADER),1,filePtr);
if(bmfh.bfType!=BITMAP_ID)
{
fclose(filePtr);
return NULL;
}
fread(bmih,sizeof(BITMAPINFOHEADER),1,filePtr);
fseek(filePtr,bmfh.bfOffBits,SEEK_SET);
bitmapImage=(unsigned char *)malloc(bmih->biSizeImage);
if(!bitmapImage)
{
free(bitmapImage);
fclose(filePtr);
return NULL;
}
fread(bitmapImage,1,bmih->biSizeImage,filePtr);
if(bitmapImage==NULL)
{
fclose(filePtr);
return NULL;
}
for(imageIdx=0;imageIdx < bmih->biSizeImage;imageIdx+=3)//BGR->RGB
{
tempRGB=bitmapImage[imageIdx];
bitmapImage[imageIdx]=bitmapImage[imageIdx+2];
bitmapImage[imageIdx+2]=tempRGB;
}
fclose(filePtr);
return bitmapImage;
}
/**********************************************/
//
/**********************************************/
void Initialize()
{
float matAmbient[]={1,1,1,1};
float matdiff[]={1,1,1,1};
float light_position[] = {2, 1, 1,1 };//灯光位置
float ambientLight[]={0.1,0.2,0.1,1};
float diffuseLight[]={0.5,0.5,1,1};
glClearColor(0,0,0,0);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);//灯光位置设置
glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);
glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
glEnable(GL_SMOOTH);//使用平滑明暗处理
glEnable(GL_LIGHTING);//启用光照
glEnable(GL_LIGHT0);//启用灯光 0
glDepthFunc(GL_LESS);//默认深度比较,当 z 坐标值小于深度缓存中 z 坐
标值才会绘制当前像素
glEnable(GL_DEPTH_TEST);//消除隐藏面
glEnable(GL_TEXTURE_2D);
bitmapData=LoadBitmapFile("tietu.bmp",&bmih);
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,bmih.biWidth,bmih.biHeight,0,
GL_RGB,GL_UNSIGNED_BYTE,bitmapData);
glMaterialfv(GL_FRONT,GL_AMBIENT,matAmbient);
glMaterialfv(GL_FRONT,GL_DIFFUSE,matdiff);
gluQuadricTexture(g_Object,GL_TRUE);//开启二次曲面对象纹理坐标创
建
}
void DrawCup()
{
glPushMatrix();
gluCylinder(g_Object,0.27,0.32,0.8,20,5);
gluCylinder(g_Object2,0.25,0.3,0.8,20,5);
glTranslatef(0,0,0.1);
gluDisk(g_Object,0,0.27,20,5);
glTranslatef(0,0,-0.1);
gluDisk(g_Object,0.25,0.27,20,5);
glTranslatef(0,0,0.8);
gluDisk(g_Object,0.3,0.32,20,5);
glPopMatrix();
}
void Render()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);//清理屏幕和深度
缓存
glLoadIdentity();//复位模型视图矩阵
glRotatef(anglex,1,0,0);//绕 x 轴旋转
glRotatef(angley,0,1,0);//绕 y 轴旋转
glRotatef(anglez,0,0,1);//绕 z 轴旋转
DrawCup();//绘制茶杯
glFlush();//刷新缓存
SwapBuffers(g_HDC);//交换前后缓存
}
/**********************************************/
//
/**********************************************/
//为设备环境设置像素格式
void SetupPixelFormat(HDC hDC)
{
int nPixelFormat;
PIXELFORMATDESCRIPTOR pfd={
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW|
PFD_SUPPORT_OPENGL|
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,
0,
0,
0,
0,0,0,0,
16,
0,
0,
PFD_MAIN_PLANE,
0,
0,0,0
};
nPixelFormat=ChoosePixelFormat(hDC,&pfd);
SetPixelFormat(hDC,nPixelFormat,&pfd);
}
//WINDOWS PROCEDURE 事件处理器
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM
lParam)
{
HGLRC hRC;
HDC hDC;
int width,height;
switch(message)
{
case WM_CREATE:
hDC=GetDC(hwnd);
g_HDC=hDC;
SetupPixelFormat(hDC);
hRC=wglCreateContext(hDC);
wglMakeCurrent(hDC,hRC);
return 0;
case WM_SIZE:
height=HIWORD(lParam);
width=LOWORD(lParam);
if(height==0) height=1;
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
return 0;
case WM_KEYDOWN:
if(wParam==VK_UP)
{
anglex++;
if(anglex>=360)anglex=0;
}
else if(wParam==VK_DOWN)
{
anglex--;
if(anglex<=0)anglex=360;
}
if(wParam==VK_RIGHT)
{
angley++;
if(angley>=360)angley=0;
}
else if(wParam==VK_LEFT)
{
angley--;
if(angley<=0)angley=360;
}
if(wParam==VK_PRIOR)
{
anglez++;
if(anglez>=360)anglez=0;
}