Opengl教程之 读取obj并绘制在picturecontrol控件内




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 添加类
  Opengl教程之 读取obj并绘制在picturecontrol控件内_第1张图片
建立C++类;
  Opengl教程之 读取obj并绘制在picturecontrol控件内_第2张图片
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();
}


若出现此种情况:
  Opengl教程之 读取obj并绘制在picturecontrol控件内_第3张图片
如此设置:
  Opengl教程之 读取obj并绘制在picturecontrol控件内_第4张图片


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
 
  Opengl教程之 读取obj并绘制在picturecontrol控件内_第5张图片


若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可看到如下:
 
Opengl教程之 读取obj并绘制在picturecontrol控件内_第6张图片

OK,我们的第一个Obj模型成功读入


原创作品,转载请联系博主。

你可能感兴趣的:(mfc,OpenGL,三维,GLM,obj读取)