当前位置:   article > 正文

ArchieOpenGL教程第一课:搭建opengl基本框架(SDI)①_microsoft visual c++ will insert additional declar

microsoft visual c++ will insert additional declarations immediately before

 

点击打开链接

带纹理映射的链接下载

1、新建SDI工程

2、添加OpenGL库。

3、在stdafx.h中添加OpenGL包含头文件4个


#include<gl\gl.h>
#include<gl\glu.h>
#include <gl\glaux.h>
#include <gl\glut.h>
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__F84A6C6C_B5B1_431C_A251_F8ADFE30EE49__INCLUDED_)

4、在view.h中添加成员变量与成员函数

1、在PreCreateWindow中设置窗口类型

  1. BOOL COpenglbaseView::PreCreateWindow(CREATESTRUCT& cs)
  2. {
  3. // TODO: Modify the Window class or styles here by modifying
  4. // the CREATESTRUCT cs
  5. //
  6. //设置窗口类型
  7. cs.style|=WS_CLIPCHILDREN|WS_CLIPSIBLINGS;//OpenGL必须为此项
  8. //
  9. return CView::PreCreateWindow(cs);
  10. }


2、添加成员变量

  1. CDC* m_pDC;//设备描述表
  2. HGLRC m_hRC; //绘制描述表
  1. BOOL InitializeOpenGL(CDC* pDC);
  2. BOOL SetupPixelFormat();
  3. BOOL RenderScene();
GLuint texture[5];     // 保存5个纹理标志

3、设置像素格式

  1. BOOL COpenglbaseView::SetupPixelFormat()
  2. {
  3. PIXELFORMATDESCRIPTOR pixelDesc;//在opengl中用PIXELFORMATDESCRIPTOR描述绘图曲面的象素格式
  4. //定义一个像素对象为pixelDesc
  5. //以下为该格式的成员设置
  6. pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);//数据结构大小
  7. pixelDesc.nVersion = 1;//数据结构的版本号,设为1
  8. pixelDesc.dwFlags =//定义象素格式属性的一系列位标志,一般不互相排斥
  9. PFD_DRAW_TO_WINDOW //指缓冲区可以在窗口或者设备表面绘图
  10. | PFD_SUPPORT_OPENGL //缓冲区支持opengl绘图
  11. |PFD_DOUBLEBUFFER //使用双缓冲区,在当前基本功能下,与PFD_SUPPOT_GDI相互排斥
  12. | PFD_STEREO;//缓冲区是立体的,当前基本功能不支持这个标志
  13. //_DONTCARE;
  14. pixelDesc.iPixelType = //像素格式的类型
  15. PFD_TYPE_RGBA;//RGBA类型,每个象素依次有四个基本组成:红绿蓝所占的比例,一般在0-1之间设值,
  16. //最后一个是alpha,代表像素的透明程度,1表示完全不透明,0表示完全透明
  17. pixelDesc.cColorBits = 32;//表示每个RGBA颜色缓冲区的位平面数目,(不包括alpha)这里值32位真彩色
  18. pixelDesc.cRedBits = 8;//表示每个RGBA颜色缓冲区的红色位平面数目
  19. pixelDesc.cRedShift = 16;//表示每个RGBA颜色缓冲区的红色位平面偏移量
  20. pixelDesc.cGreenBits = 8;//表示每个RGBA颜色缓冲区的绿色位平面数目
  21. pixelDesc.cGreenShift = 8;//表示每个RGBA颜色缓冲区的绿色位平面偏移量
  22. pixelDesc.cBlueBits = 8;//表示每个RGBA颜色缓冲区的蓝色位平面数目
  23. pixelDesc.cBlueShift = 0;//表示每个RGBA颜色缓冲区的蓝色位平面偏移量
  24. pixelDesc.cAlphaBits = 0;//表示每个RGBA颜色缓冲区的alpha平面数目,alpha平面数目不被支持
  25. pixelDesc.cAlphaShift = 0;//表示每个RGBA颜色缓冲区的alpha平面偏移量,alpha平面偏移量不被支持
  26. pixelDesc.cAccumBits = 64;//累加缓冲区的位平面总数
  27. pixelDesc.cAccumRedBits = 16;//累加缓冲区的红色位平面数
  28. pixelDesc.cAccumGreenBits = 16;//累加缓冲区的绿色位平面数
  29. pixelDesc.cAccumBlueBits = 16;//累加缓冲区的蓝色位平面数
  30. pixelDesc.cAccumAlphaBits = 0;//累加缓冲区的alpha平面数
  31. pixelDesc.cDepthBits = 32;//深度(z轴)缓冲区的深度值
  32. pixelDesc.cStencilBits = 8;//模板缓冲区的深度值
  33. pixelDesc.cAuxBuffers = 0;//辅助缓冲区的数目,不支持辅助缓冲区
  34. //pixelDesc.iLayerType = PFD_MAIN_PLANE; 早期的opengl使用,现在不使用此参数,可忽略
  35. pixelDesc.bReserved = 0;//定义覆盖及底层平面的编号,0-3个字节最多定义15个覆盖层平面,
  36. //4-7个平面最多定义15个底层平面
  37. //pixelDesc.dwLayerMask = 0;早期的opengl使用,现在不使用此参数,可忽略
  38. pixelDesc.dwVisibleMask = 0;//若像素类型为RGBA,定义底层平面的象素颜色或色彩指数
  39. //pixelDesc.dwDamageMask = 0;早期的opengl使用,现在不使用此参数,可忽略
  40. //像素格式设置完毕
  41. m_pDC = new CClientDC(this);//动态生成一个CClientDC类的指针this指针覆给CTestView类的成员变量m_PDC
  42. int m_GLPixelIndex = ChoosePixelFormat(m_pDC->GetSafeHdc(),&pixelDesc); //选择像素格式
  43. //GetSafeHdc()得到一个设备描述表的句柄,此为得到当前设备描述表的句柄
  44. if(m_GLPixelIndex == 0) // Choose default
  45. {
  46. AfxMessageBox("no matched pixelformat!");
  47. m_GLPixelIndex = 1;
  48. if(DescribePixelFormat(m_pDC->GetSafeHdc(),m_GLPixelIndex,
  49. sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)//当前描述表与定义的象素格式不符
  50. //DescribePixelFormat提供与参数hdc参数相关的,由iPixelFormat标识的象素格式类型,
  51. //并由像素格式类型设置ppfd指向的PIXELFORMATDESCRIPTOR结构,参数依次为hdc,iPixelFormat,nByte,ppfd
  52. return FALSE;
  53. }
  54. if(!SetPixelFormat(m_pDC->GetSafeHdc(),m_GLPixelIndex,&pixelDesc)) //设置像素格式
  55. return FALSE;
  56. return TRUE;
  57. }

4、载入图像函数

  1. /* 这段代码用来加载位图文件。
  2. * 如果文件不存在,返回 NULL 告知程序无法加载位图。
  3. * 关于用作纹理的图像。图像的宽和高必须是2的n次方;宽度和高度最小必须是64象素;
  4. * 并且出于兼容性的原因,图像的宽度和高度不应超过256象素。如果您的原始素材的宽度
  5. * 和高度不是64,128,256象素的话,使用图像处理软件重新改变图像的大小。*/
  6. AUX_RGBImageRec * COpenglbaseView::LoadBMP(char *Filename)
  7. {
  8.  // 首先,我们创建一个文件句柄。句柄是个用来鉴别资源的数值,它使程序能够
  9.  //访问此资源。我们开始先将句柄设为 NULL 。
  10.  FILE *File=NULL;
  11.  if (!Filename)  //确保文件名已提供
  12.  {
  13.   return NULL;
  14.  }
  15.  File=fopen(Filename,"r");
  16.  if (File)// 文件存在么?
  17.  {
  18.   fclose(File);
  19.   return auxDIBImageLoad(Filename); // 载入位图并返回指针
  20.  }
  21.  return NULL;
  22. }

5、载入纹理函数,调用LoadBMP函数。

  1. int COpenglbaseView::LoadGLTextures()
  2. {
  3. GLuint loop;
  4. int Status=FALSE;
  5. AUX_RGBImageRec *TextureImage[5]; // 创建保存5个纹理的数据结构
  6. memset(TextureImage,0,sizeof(void *)*5); // 初始化
  7. if ((TextureImage[0]=LoadBMP("Data/logo.bmp")) && // 加载纹理0
  8. (TextureImage[1]=LoadBMP("Data/mask1.bmp")) && // 加载掩模纹理1,作为“掩模”使用
  9. (TextureImage[2]=LoadBMP("Data/image1.bmp")) && // 加载纹理1
  10. (TextureImage[3]=LoadBMP("Data/mask2.bmp")) && // 加载掩模纹理2,作为“掩模”使用
  11. (TextureImage[4]=LoadBMP("Data/image2.bmp"))) // 加载纹理2
  12. {
  13. Status=TRUE;
  14. glGenTextures(5, &texture[0]); // 创建5个纹理
  15. for (loop=0; loop<5; loop++) // 循环加载5个纹理
  16. {
  17. glBindTexture(GL_TEXTURE_2D, texture[loop]);
  18. glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  19. glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
  20. glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[loop]->sizeX, TextureImage[loop]->sizeY,
  21. 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[loop]->data);
  22. }
  23. }
  24. for (loop=0; loop<5; loop++)
  25. {
  26. if (TextureImage[loop])
  27. {
  28. if (TextureImage[loop]->data)
  29. {
  30. free(TextureImage[loop]->data);
  31. }
  32. free(TextureImage[loop]);
  33. }
  34. }
  35. return Status;
  36. }

6、初始化OpenGL函数,在View::OnCreate里调用

  1. BOOL COpenglbaseView::InitializeOpenGL(CDC *pDC)
  2. {
  3. m_pDC=pDC;
  4. if(!SetupPixelFormat())
  5. return FALSE;
  6. m_hRC=::wglCreateContext(m_pDC->GetSafeHdc());//产生一个新的opengl绘图描述表使之适合在参数hdc给出的设备上画图
  7. ::wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC);
  8. SetLight();//设置光照环境
  9. LoadGLTextures();//加载纹理
  10. glEnable(GL_TEXTURE_2D);//启用纹理映射必须加此句
  11. return TRUE;
  12. }

 

5、为View类添加OnDraw绘图函数和消息WM_CREATE、WM_DESTROY、WM_SIZE、WM_TIMER的响应函数

 

1、OnDraw绘制函数

  1. void COpenglbaseView::OnDraw(CDC* pDC)
  2. {
  3. COpenglbaseDoc* pDoc = GetDocument();
  4. ASSERT_VALID(pDoc);
  5. // TODO: add draw code for native data here
  6. static BOOL bBusy = FALSE;
  7. if (bBusy)
  8. {
  9. return;
  10. }
  11. bBusy=TRUE; //双缓存应用
  12. //
  13. RenderScene();//渲染场景
  14. //
  15. glFlush();//完成绘制
  16. SwapBuffers(wglGetCurrentDC());//双缓存应用
  17. bBusy=FALSE;
  18. }

2、WM_CREATE消息响应函数,初始化OpenGL和定时器(timer可省)

  1. int COpenglbaseView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  2. {
  3. if (CView::OnCreate(lpCreateStruct) == -1)
  4. return -1;
  5. // TODO: Add your specialized creation code here
  6. //
  7. //初始化OpenGL和定时器函数
  8. m_pDC=new CClientDC(this);
  9. SetTimer(1,20,NULL);
  10. InitializeOpenGL(m_pDC);
  11. //
  12. return 0;
  13. }


3、WM_DESTROY函数

  1. void COpenglbaseView::OnDestroy()
  2. {
  3. CView::OnDestroy();
  4. //
  5. //删除调色板和渲染上下文、定时器
  6. wglMakeCurrent(NULL,NULL);
  7. if(m_hRC)
  8. wglDeleteContext(m_hRC);
  9. m_hRC=0;
  10. if (m_pDC)
  11. {
  12. delete m_pDC;
  13. }
  14. KillTimer(1);
  15. }


4、OnSize函数

  1. void COpenglbaseView::OnSize(UINT nType, int cx, int cy)
  2. {
  3. CView::OnSize(nType, cx, cy);
  4. // TODO: Add your message handler code here
  5. //添加窗口缩放时的图形变换函数
  6. glViewport(0,0,cx,cy);
  7. }


5、OnTimer函数,定时刷新

  1. void COpenglbaseView::OnTimer(UINT nIDEvent)
  2. {
  3. // TODO: Add your message handler code here and/or call default
  4. //
  5. //添加定时器响应函数和场景和更新函数
  6. Invalidate(FALSE);
  7. //
  8. CView::OnTimer(nIDEvent);
  9. }


6、场景绘制与渲染

  1. BOOL COpenglbaseView::RenderScene()
  2. {
  3. glClearColor(1.0f,0.0f,0.0f,0.0f);
  4. glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  5. glLoadIdentity();
  6. glBindTexture(GL_TEXTURE_2D,texture[0]);// 选择Logo纹理
  7. glBegin(GL_QUADS); // 绘制纹理四边形
  8. glTexCoord2f(0.0f, 0.0f);
  9. glVertex2f(-0.5,-0.5);
  10. glTexCoord2f(1.0f, 0.0f);
  11. glVertex2f(0.5,-0.5);
  12. glTexCoord2f(1.0f, 1.0f);
  13. glVertex2f(0.5,0.5);
  14. glTexCoord2f(0.0f, 1.0f);
  15. glVertex2f(-0.5,0.5);
  16. glEnd();
  17. return TRUE;
  18. }


 

 

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/825224
推荐阅读
相关标签
  

闽ICP备14008679号