您的位置:首页 > 运维架构

2 MFC+opengl+nehe配置绘制金字塔和立方体

2018-03-01 18:01 190 查看
1 在vc6中,点击File--》new-》project
 


选单文档,点击完成
 
2 点击工程--》设置,加入下面三个库
opengl32.lib glu32.lib glaux.lib
 


点击确定。
 
3  在stdafx.h中加入
#include "gl\gl.h"
#include "gl\glu.h"
#include "gl\glaux.h"
 
见下图:
 
 


 
4  点击查看--》建立类向导,出现class Wizard界面,在视图类中加入五个消息映射函数:
 


 
加入后,打开mfcnehe1View.h,可以看到加入的五个消息函数:
 


 
同时在视图头文件中加入:
protected:
HGLRC m_hRC;
HDC m_hDC;
public:
void DrawGLScene();
BOOL InitGL();
见下图
 


 
5  在mfcneheview.cpp中
1) 在OnCreate函数中加入
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO: Add your specialized creation code here
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
          };
m_hDC=GetDC()->GetSafeHdc();
int setPixelFormat=::ChoosePixelFormat(m_hDC,&pfd);
::SetPixelFormat(m_hDC,setPixelFormat,&pfd);
m_hRC=::wglCreateContext(m_hDC);
::wglMakeCurrent(m_hDC,m_hRC);
InitGL();
SetTimer(1,1,NULL);
return 0;
 
2)在OnDestroy函数中加入
    ::wglMakeCurrent(NULL,NULL);
::wglDeleteContext(m_hRC);
 
3)在OnEraseBkgnd函数中修改为
return true;
 
4)在OnSize函数中加入if (cy==0) cy=1; glViewport(0, 0, cx, cy); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // 计算窗口的外观比例 gluPerspective(45.0f,(GLfloat)cx/(GLfloat)cy,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); 
5)在OnTimer函数
6)再加入几个辅助函数
  InitGL函数中加入
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
return TRUE;
 
glDepthFunc
函数原型:
    void glDepthFunc(GLenum func);
函数功能:
    指定“目标像素与当前像素在z方向上值大小比较”的函数,符合该函数关系的目标像素才进行绘制,否则对目标像素不予绘制。
参数说明:
    func指定深度比较函数,GL_NEVER,GL_LESS,GL_EQUAL,GL_LEQUAL,GL_GREATER,GL_NOTE_QUAL,GL_GEQUAL,GL_ALWAYS,缺省值GL_LESS,
GL_NEVER,不通过(输入的深度值不取代参考值)
GL_LESS,如果输入的深度值小于参考值,则通过
GL_EQUAL,如果输入的深度值等于参考值,则通过
GL_LEQUAL,如果输入的深度值小于或等于参考值,则通过
GL_GREATER,如果输入的深度值大于参考值,则通过
GL_NOTE_QUAL,如果输入的深度值不等于参考值,则通过
GL_GEQUAL,如果输入的深度值大于或等于参考值,则通过
GL_ALWAYS,总是通过(输入的深度值取代参考值)
描述:
       通过目标像素与当前像素在z方向上值大小的比较是否满足参数指定的条件,来决定在深度(z方向)上是否绘制该目标像素。该函数只有启用“深度测试”时才有效,参考glEnable(GL_DEPTH_TEST)和glDisable(GL_DEPTH_TEST)
 
OpenGL反走样glDisable(GL_LINE_SMOOTH),glHint(GLenum target,GLenum hint);
反走样:
       在光栅图形显示器上绘制非水平且非垂直的直线或多边形边界时,或多或少会呈现锯齿状或台阶状外观。这是因为直线、多边形、色彩边界等是连续的,而光栅则是由离散的点组成,在光栅显示设备上表现直线、多边形等,必须在离散位置采样。由于采样不充分重建后造成的信息失真,就叫走样(aliasing)。而用于减少或消除这种效果的技术,就称为反走样(antialiasing)。
         计算机生成图像时通常存在三种走样现象中的两种:锯齿形边以及图形细节或纹理绘制失真。第三种现象出现在显示非常微小对象的场合。
         基本上反走样方法可分为两类。第一类是提高分辨率 即增加采样点(提高采样频率)。然而,CRT光栅扫描设备显示非常精细光栅的能力是有限的,因此人们通常是在较高分辨率上对光栅进行计算,然后采用某种平均算法(滤除高频分量)得到较低分辨率的象素的属性,并显示在分辨率较低的显示器上 。这种方法称为超采样或后置滤波。另一类反走样是把像素作为一个有限区域,对区域采样来调整像素的亮度,以光顺边界来减小锯齿现象 J。这种方法等价于图像的前置滤波。OpenGL的反走样函数:
          void glHint(GLenum target,GLenum hint); 
         其中hint可以是:
          GL_FASTEST 给出最有效的选择 
          GL_NICEST 给出最高质量的选择 
          GL_DONT_CARE 没有选择
          target 意义
          GL_POINT_SMOOTH_HINT 指定点、 
          GL_LINE_SMOOTH_HINT 线、 
           GL_POLYGON_SMOOTH_HINT 多边形的采样质量 
           GL_FOG_HINT 指出雾化计算是按每个象素进行(GL_NICEST),还是按每个顶点进行(GL_FASTEST) 
          GL_PERSPECTIVE_CORRECTION_HINT 指定颜色纹理插值的质量 
          其中GL_PERSPECTIVE_CORRECTION_HINT用以纠正单纯线性插值带来的观察错误。
OpenGL实现反走样需要满足两个条件,一是启用混合,二是启用针对几何图元的反走样处理。
在DrawScene函数中加入
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
SwapBuffers(m_hDC);
 
7 在OnDraw函数中加入
DrawGLScene();
7 编译运行,显示
 


 
这是nehe课程中的第一课,显示一个没有绘制任何下图的opengl窗口。
 
二 运行nehe的向3d进军的代码,显示旋转的金字塔和立方体
我们直接在上面的工程mfcnehe1中加入代码:
1 在mfcneheview.h中加入用于旋转的成员变量
    GLfloat rtri; // 用于三角形的角度
GLfloat rquad; // 用于四边形的角度
2 在mfcneheview.cpp中加入
1)在构造函数中加入变量的初始化代码
CMfcnehe1View::CMfcnehe1View():rtri(0),rquad(0)
2)在OnTimer函数中加入
rtri+=1.0f; // 增加金字塔的旋转变量(新增)
rquad-=0.5f; // 减少立方体的旋转变量(新增)
Invalidate();//触发OnDraw函数
3)在OnSize函数中
4)在DrawScene函数中加入
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
//////////////////////////////////////////////////////////////////////
    //gluLookAt(0,0,2,0,0,0,0,1,0);//设置视点与目标点
 
glTranslatef(-1.5f,0.0f,-6.0f); // 左移 1.5 单位,并移入屏幕 6.0
glRotatef(rtri,0.0f,1.0f,0.0f); // 绕Y轴旋转金字塔
glBegin(GL_TRIANGLES); // 开始绘制金字塔的各个面
    glColor3f(1.0f,0.0f,0.0f); // 红色
        glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点 (前侧面)
        glColor3f(0.0f,1.0f,0.0f); // 绿色
        glVertex3f(-1.0f,-1.0f, 1.0f); // 三角形的左下顶点 (前侧面)
        glColor3f(0.0f,0.0f,1.0f); // 蓝色
        glVertex3f( 1.0f,-1.0f, 1.0f); // 三角形的右下顶点 (前侧面)
glColor3f(1.0f,0.0f,0.0f); // 红色
        glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点 (右侧面)
        glColor3f(0.0f,0.0f,1.0f); // 蓝色
        glVertex3f( 1.0f,-1.0f, 1.0f); // 三角形的左下顶点 (右侧面)
        g
a9dc
lColor3f(0.0f,1.0f,0.0f); // 绿色
        glVertex3f( 1.0f,-1.0f, -1.0f); // 三角形的右下顶点 (右侧面)
glColor3f(1.0f,0.0f,0.0f); // 红色
        glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点 (后侧面)
        glColor3f(0.0f,1.0f,0.0f); // 绿色
        glVertex3f( 1.0f,-1.0f, -1.0f); // 三角形的左下顶点 (后侧面)
        glColor3f(0.0f,0.0f,1.0f); // 蓝色
        glVertex3f(-1.0f,-1.0f, -1.0f); // 三角形的右下顶点 (后侧面)
glColor3f(1.0f,0.0f,0.0f); // 红色
        glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点 (左侧面)
        glColor3f(0.0f,0.0f,1.0f);// 蓝色
        glVertex3f(-1.0f,-1.0f,-1.0f); // 三角形的左下顶点 (左侧面)
        glColor3f(0.0f,1.0f,0.0f); // 绿色
        glVertex3f(-1.0f,-1.0f, 1.0f); // 三角形的右下顶点 (左侧面)
    glEnd(); //file://金字塔绘制结束
 
glLoadIdentity();
    glTranslatef(1.5f,0.0f,-7.0f); // 先右移再移入屏幕
    glRotatef(rquad,1.0f,1.0f,1.0f); // 在XYZ轴上旋转立方体
    glBegin(GL_QUADS); // 开始绘制立方体
    glColor3f(0.0f,1.0f,0.0f); // 颜色改为蓝色
        glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点 (顶面)
        glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点 (顶面)
        glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左下顶点 (顶面)
        glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右下顶点 (顶面)
glColor3f(1.0f,0.5f,0.0f); // 颜色改成橙色
        glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右上顶点(底面)
        glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左上顶点(底面)
        glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(底面)
        glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(底面)
glColor3f(1.0f,0.0f,0.0f); // 颜色改成红色
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右上顶点(前面)
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左上顶点(前面)
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左下顶点(前面)
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右下顶点(前面)
glColor3f(1.0f,1.0f,0.0f); // 颜色改成黄色
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右上顶点(后面)
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左上顶点(后面)
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左下顶点(后面)
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右下顶点(后面)
glColor3f(0.0f,0.0f,1.0f); // 颜色改成蓝色
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的右上顶点(左面)
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点(左面
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(左面)
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的右下顶点(左面)
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点(右面)
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的左上顶点(右面)
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的左下顶点(右面)
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(右面)
    glEnd(); // 立方体绘制结束
 
 
 
 
///////////////////////////////////////////////////////////////////////
SwapBuffers(m_hDC);
 
编译运行代码,显示
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: