Opengl教程之读取obj并绘制在picturecontrol控件内
By Cracent
注:本文将简单图文表述基于MFC对话框的OpenGL三维显示(picture control 类版)以及obj文件读取绘制
目录
一、
配置相应环境
二、
建立CMyStatic类
2.1 添加类
2.2 类向导
2.2.1添加消息处理函数OnTimer()
2.2.2 重写虚函数PreSubclassWindow()
2.3 添加其他函数与变量
三、
OpenGl使用
3.1函数内容
3.2插入picture control控件, 并为其添加控制变量
3.3绘制简单函数
四、
obj文件读取并绘制
4.1 添加并配置glm.h glm.c
4.2添加函数:ObjRead();和LightShine()
一、
配置相应环境
二、
建立CMyStatic类
2.1 添加类
建立C++类;
2.2 类向导
2.2.1添加消息处理函数OnTimer()
2.2.2 重写虚函数PreSubclassWindow()
2.3 添加其他函数与变量
void GLDraw();//Opengl绘制
bool InitGL();//Opengl初始化
HGLRC hglrc;
HDC hdc;
三、
OpenGl使用
3.1函数内容
#include <GL\glu.h>
bool CMyStatic::InitGL(void)
{
static 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,
32 ,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
int pixelformat;
hdc = ::GetDC(this->GetSafeHwnd());
if (!(pixelformat = ChoosePixelFormat(hdc , &pfd)))
{
MessageBox("ChoosePixelFormat failed!");
return false;
}
if (!SetPixelFormat(hdc , pixelformat , &pfd))
{
MessageBox("SetPixelFormat failed!");
return false;
}
if (!(hglrc = wglCreateContext(hdc)))
{
MessageBox("CreateContext failed!");
return false;
}
if (!wglMakeCurrent(hdc , hglrc))
{
MessageBox("MakeCurrent failed!");
return false;
}
CRect rect; //在这个矩形中画图
GetClientRect(rect);
glViewport(0 , 0 , rect.Width() , rect.Height());
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/*gluPerspective(45.0f , rect.Width()/rect.Height() , 0.1f , 100.0f);// 计算窗口的外观比例*/
gluPerspective(45.0f , 640/480 , 0.1f , 100.0f);// 计算窗口的外观比例
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.0f , 0.0f , 0.0f , 1.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
SetTimer(1 , 50 , NULL);
return true;
}
void CMyStatic::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
DrawFunc(); //定时器中调用这个函数
CStatic::OnTimer(nIDEvent);
}
void CMyStatic::PreSubclassWindow()
{
// TODO: Add your specialized code here and/or call the base class
InitGL();
CStatic::PreSubclassWindow();
}
若出现此种情况:
如此设置:
3.2插入picture control控件, 并为其添加控制变量
3.3绘制简单函数
void CMyStatic::GLDraw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-0.0f , 0.0f , -10.0f);
static int RotateDegTriangle =1;
glRotatef(RotateDegTriangle++ , 0.0f , 1.0f , 0.0f);
glBegin(GL_TRIANGLES);
glColor3f(1.0f , 0.0f , 0.0f);
glVertex3f(0.0f , 2.0f , 0.0f);
glColor3f(0.0f , 1.0f , 0.0f);
glVertex3f(-1.0f , 0.0f , 1.0f);
glColor3f(0.0f , 0.0f , 1.0f);
glVertex3f(1.0f , 0.0f , 1.0f );
glColor3f(1.0f , 0.0f , 0.0f);
glVertex3f(0.0f , 2.0f , 0.0f);
glColor3f(0.0f , 0.0f , 1.0f);
glVertex3f(1.0f , 0.0f , 1.0f);
glColor3f(0.0f , 1.0f , 0.0f);
glVertex3f(1.0f , 0.0f , -1.0f );
glColor3f(1.0f , 0.0f , 0.0f);
glVertex3f(0.0f , 2.0f , 0.0f);
glColor3f(0.0f , 1.0f , 0.0f);
glVertex3f(1.0f , 0.0f , -1.0f);
glColor3f(0.0f , 0.0f , 1.0f);
glVertex3f(-1.0f , 0.0f , -1.0f );
glColor3f(1.0f , 0.0f , 0.0f);
glVertex3f(0.0f , 2.0f , 0.0f);
glColor3f(0.0f , 0.0f , 1.0f);
glVertex3f(-1.0f , 0.0f , -1.0f);
glColor3f(0.0f , 1.0f , 0.0f);
glVertex3f(-1.0f , 0.0f , 1.0f );
glEnd();
#ifdef TWO_OBJS
glLoadIdentity();
glTranslatef(5.0f , 0.0f , -15.0f);
RotateDegQuad += 3.0f;
glRotatef(RotateDegQuad , 1.0f , 1.0f , 0.0f) ;
glBegin(GL_QUADS);
glColor3f(1.0f , 1.0f , 0.0f);
glVertex3f(-1.0f , 1.0f , 0.0f);
glVertex3f(-1.0f , -1.0f , 0.0f);
glVertex3f(1.0f , -1.0f , 0.0f);
glVertex3f(1.0f , 1.0f , 0.0f);
glEnd();
#endif
SwapBuffers(hdc); //利用双缓冲
}
F5后,可以看到如下画面
一个旋转的彩色立体正四面体
四、
obj文件读取并绘制
4.1 添加并配置glm.h glm.c
若glm.cpp没有#include "stdafx.h",必须在最开头加上
CMyStatic.cpp添加库头
#include "glm.h"
4.2添加函数:ObjRead();和LightShine()
void CMyStatic::ObjRead(void)
{
GLfloat scalefactor = 0.0;
float modelCenter[] = {0.0f, 0.0f, 0.0f};
//GLMmodel *object1;
object1 = glmReadOBJ("Model/moto.obj");
if(!scalefactor)
{
scalefactor = glmUnitize(object1,modelCenter);
}
else
{
glmScale(object1,scalefactor);
}
glmScale(object1,1.5);
glmFacetNormals(object1);
glmVertexNormals(object1,90.0);
}
void CMyStatic::LightShine(void)
{
GLfloat mat_diffuse[4]={1,0.5,0.5,1.0};
GLfloat mat_specular[4]={1.0,1.0,1.0,1.0};
GLfloat mat_shininess[1]={100.0};
//光源 1
GLfloat light_position0[4]={0,500,500,0};
glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);
glLightfv(GL_LIGHT0,GL_POSITION,light_position0);
glEnable(GL_LIGHT0);
//光源 2
GLfloat light_position1[4]={1000,-1000,1000,0};
GLfloat mat_diffuse1[4]={0.5,0.5,1.0,1.0};
glLightfv(GL_LIGHT1,GL_DIFFUSE,mat_diffuse1);
glLightfv(GL_LIGHT1,GL_SPECULAR,mat_specular);
glLightfv(GL_LIGHT1,GL_SHININESS,mat_shininess);
glLightfv(GL_LIGHT1,GL_POSITION,light_position1);
glEnable(GL_LIGHT1);
//使模型能接受光照
glEnable(GL_LIGHTING);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
//计算定点法线
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
}
修改GLDraw()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glEnable(GL_POINT_SMOOTH);
glEnable(GL_DEPTH_TEST);
LightShine();
glTranslatef(0.0f,0.0f,-5.0f);
static float step = 0.0;
step = step + 1.0;
if (step > 360.0)
step = step - 360.0;
glPushMatrix();
glRotatef(-45,1.0,0.0,0.0);
//glRotatef(step,0.0,1.0,0.0);
glRotatef(step,0.0,0.0,1.0);
if ( object1 )
{
glmDraw(object1, GLM_SMOOTH | GLM_MATERIAL | GLM_TEXTURE );
}
glPopMatrix();
SwapBuffers(hdc);
添加OBJ文件:
F5运行程序
如出现此种情况:
如此处理即可:
处理后F5可看到如下:
OK,我们的第一个Obj模型成功读入
原创作品,转载请联系博主。