分享

windows 下使用OPENGL开发

 mediatv 2018-11-24
1, 初始化:
       1.1 根据hwnd 取得设备DC
       HDC dc = ::GetDC(hWnd);
PIXELFORMATDESCRIPTOR pfd = 
{
sizeof(PIXELFORMATDESCRIPTOR), //数据结构大小
1, //数据结构版本号
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,//缓冲区可以在窗口上绘图,支持OpenGL绘图
24, //深度颜色缓冲区位数
0,0,0,0,0,0, //忽略颜色位
0,0,0, //没有非透明度缓存,忽略移位位,无累加缓存
0,0,0,0, //忽略累加位
32, //32位深度缓存
0, //无模板缓存
0, //无辅助缓存
PFD_MAIN_PLANE, //主层
0, //保留
0,0,0, //忽略层,可见性和损毁掩膜
};
       //得到当前正在使用的绘图设备句柄
int nPixelFormat = ::ChoosePixelFormat(dc, &pfd);
//将当前绘图设备的像素格式设为nPixelFormat
::SetPixelFormat(dc, nPixelFormat, &pfd);
//生成 open设备上下文
        openglRC = wglCreateContext(dc);
        //生成纹理对象 
       glGenTextures(1, &mTextureID);
glBindTexture(GL_TEXTURE_2D, mTextureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//对于贴了纹理的模型,可以使用 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,XX)来指定纹//理贴图和材质混合的方式,从而产生特定的绘制效果
如果target是GL_TEXTURE_ENV,且pname是GL_TEXTURE_ENV_MODE 那么param必须是GL_REPLACE,GL_DECAL,GL_MODULATE; GL_ADD, GL_BLEND,GL_COMBINE颜色组合操作类型之一,
或者GL_TEXTURE_ENV_COLOR直接提供一个色调进行组合颜色。
OpenGL提供了3种不同的贴图模式:GL_MODULATE,GL_DECAL和GL_BLEND。默认情况下,贴图模式是GL_MODULATE,在这种模式下,OpenGL会根据当前的光照系统调整物体的色彩和明暗。第二种模式是GL_DECAL,在这种模式下所有的光照效果都是无效的,OpenGL将仅依据纹理贴图来绘制物体的表面。最后是GL_BLEND,这种模式允许我们使用混合纹理。在这种模式下,我们可以把当前纹理同一个颜色混合而得到一个新的纹理。我们可以调用glTexEnvi函数来设置当前贴图模式:
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

2,绘制
void paintGL(int width, int height, char*the_image_data)
{
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.0, 1.0, 0.0, 1.0);    //设置清屏颜色
glClear(GL_COLOR_BUFFER_BIT); //清屏
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);  //初始画投影矩阵
glLoadIdentity();                            //使用投影矩阵
gluOrtho2D(0, width, height, 0); //
        //gluOrtho2D定义剪裁面,通过正交投影,把景物(模型)按照1:1的比例绘制  
        // 到一个剪裁面上,相当于对世界坐标窗口的一个截取。
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
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, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, the_image_data);
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex2i(0, height);
glTexCoord2i(0, 1); glVertex2i(0, 0);
glTexCoord2i(1, 1); glVertex2i(width, 0);
glTexCoord2i(1, 0); glVertex2i(width, height);
glEnd();
glDisable(GL_TEXTURE_2D);
}

3 介绍
OpenGL中只提供了两种投影方式,一种是正射投影,另一种是透视投影(参见glFrustum(), gluPerspective())。
正射投影,又叫平行投影。这种投影的视景体是一个矩形的平行管道,也就是一个长方体,如图所示。正射投影的最大一个特点是无论物体距离相机多远,投影后的物体大小尺寸不变。这种投影通常用在建筑蓝图绘制和计算机辅助设计等方面,这些行业要求投影后的物体尺寸及相互间的角度不变,以便施工或制造时物体比例大小正确。

OpenGL正射投影函数共有两个:
一个函数是:

void glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top, GLdouble near,GLdouble far)
它创建一个平行视景体。实际上这个函数的操作是创建一个正射投影矩阵,并且用这个矩阵乘以当前矩阵。其中近裁剪平面是一个矩形,矩形左下角点三维空间坐标是(left,bottom,-near),右上角点是(right,top,-near);远裁剪平面也是一个矩形,左下角点空间坐标是(left,bottom,-far),右上角点是(right,top,-far)。所有的near和far值同时为正或同时为负。如果没有其他变换,正射投影的方向平行于Z轴,且视点朝向Z负轴。这意味着物体在视点前面时far和near都为负值,物体在视点后面时far和near都为正值。
另一个函数是:
void gluOrtho2D(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top)
它是一个特殊的正射投影函数,主要用于二维图像到二维屏幕上的投影。它的near和far缺省值分别为-1.0和1.0,所有二维物体的Z坐标都为0.0。因此它的裁剪面是一个左下角点为(left,bottom)、右上角点为(right,top)的矩形。

函数原型:
void glBegin(GLenummode)
  void glEnd(void)
  参数说明:
  mode:创建图元的类型。可以是以下数值
  GL_POINTS:把每一个顶点作为一个点进行处理,顶点n即定义了点n,共绘制N个点
  GL_LINES:把每一个顶点作为一个独立的线段,顶点2n-1和2n之间共定义了n条线段,总共绘制N/2条线段
  GL_LINE_STRIP:绘制从第一个顶点到最后一个顶点依次相连的一组线段,第n和n+1个顶点定义了线段n,总共绘制n-1条线段
  GL_LINE_LOOP:绘制从第一个顶点到最后一个顶点依次相连的一组线段,然后最后一个顶点和第一个顶点相连,第n和n+1个顶点定义了线段n,总共绘制n条线段
  GL_TRIANGLES:把每个顶点作为一个独立的三角形,顶点3n-2、3n-1和3n定义了第n个三角形,总共绘制N/3个三角形
  GL_TRIANGLE_STRIP:绘制一组相连的三角形,对于奇数n,顶点n、n+1和n+2定义了第n个三角形;对于偶数n,顶点n+1、n和n+2定义了第n个三角形,总共绘制N-2个三角形
  GL_TRIANGLE_FAN:绘制一组相连的三角形,三角形是由第一个顶点及其后给定的顶点确定,顶点1、n+1和n+2定义了第n个三角形,总共绘制N-2个三角形
  GL_QUADS:绘制由四个顶点组成的一组单独的四边形。顶点4n-3、4n-2、4n-1和4n定义了第n个四边形。总共绘制N/4个四边形
  GL_QUAD_STRIP:绘制一组相连的四边形。每个四边形是由一对顶点及其后给定的一对顶点共同确定的。顶点2n-1、2n、2n+2和2n+1定义了第n个四边形,总共绘制N/2-1个四边形
  GL_POLYGON:绘制一个凸多边形。顶点1到n定义了这个多边形。
  
glBegin 函数说明:
  glBegin和glEnd函数限定了一组或多组图元的定点定义。
1.在glBegin()和glEnd()之间可调用的函数
函数 函数意义
glVertex*() 设置顶点坐标
  glColor*() 设置当前颜色
  glIndex*() 设置当前颜色表
  glNormal*() 设置法向坐标
  glEvalCoord*() 产生坐标
  glCallList(),glCallLists() 执行显示列表
  glTexCoord*() 设置纹理坐标
  glEdgeFlag*() 控制边界绘制
  glMaterial*() 设置材质
  表7-2 在glBegin()和glEnd()之间可调用的函数
glVertex3f()表示了该函数属于 gl库,参数是三个float型参数指针。我们用glVertex*()来表示这一类函数。
基本库
  2.几何图元类型和说明
  类型 说明
  GL_POINTS 单个顶点集
  GL_LINES 多组双顶点线段
  GL_POLYGON 单个简单填充凸多边形
  GL_TRIANGLES 多组独立填充三角形
  GL_QUADS 多组独立填充四边形
  GL_LINE_STRIP 不闭合折线
  GL_LINE_LOOP 闭合折线
  GL_TRIANGLE_STRIP 线型连续填充三角形串
  GL_TRIANGLE_FAN 扇形连续填充三角形串
  GL_QUAD_STRIP 连续填充四边形串

注意事项

编辑
glBegin()与glEnd()函数使用注意点:
  在OpenGL最初的定义中,几何对象数据的输入是通过调用glBegin()和glEnd()接口对来实现的。glBegin()的参数表示其下所接收的数据是何种类型,如点,线段,三角型,扇形三角行,多边形等等。
  而如glTranslatef(), glScalef(), glRotatef()等接口的作用是对当前模型空间进行几何转换。如glTranslatef(1,2,3);表示把模型的世界坐标原点从当前位置(系统总认为是(0,0,0))转到起相对位置(1,2,3)。注意,OpenGL空间使用的是右手系的定义,与屏幕水平方向一致,并方向向右的是x轴;与屏幕垂直方向一致,并方向向上的是y轴;与屏幕(平面)垂直一致,并方向向外的是z轴。
  glTranslatef()等此类几何转换接口在glBegin()和glEnd()之间是无效的。因此,如果想对模型的位置进行转换,要在调用glBegin()和glEnd()接口对之前行处理。这是许多初学者特别容易犯错的地方,而且这个错误不容易找出来。
  例如,以下的代码,并不会把模型的位置进行转移:
  glBegin(GL_TRIANGLES)
  glTranslatef(1,2,3);
  render model......
  glEnd()
  而应该这样调用:
  glTranslatef(1,2,3);
  glBegin(GL_TRIANGLES)
  render model......
  glEnd()

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多