点击打开链接
带纹理映射的链接下载
1、新建SDI工程
2、添加OpenGL库。
#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_)
BOOL COpenglbaseView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs ////////////////////////////////////////////////////////////////////////// //设置窗口类型 cs.style|=WS_CLIPCHILDREN|WS_CLIPSIBLINGS;//OpenGL必须为此项 ////////////////////////////////////////////////////////////////////////// return CView::PreCreateWindow(cs); }
CDC* m_pDC;//设备描述表 HGLRC m_hRC; //绘制描述表
BOOL InitializeOpenGL(CDC* pDC); BOOL SetupPixelFormat(); BOOL RenderScene();
GLuint texture[5]; // 保存5个纹理标志
BOOL COpenglbaseView::SetupPixelFormat() { PIXELFORMATDESCRIPTOR pixelDesc;//在opengl中用PIXELFORMATDESCRIPTOR描述绘图曲面的象素格式 //定义一个像素对象为pixelDesc //以下为该格式的成员设置 pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);//数据结构大小 pixelDesc.nVersion = 1;//数据结构的版本号,设为1 pixelDesc.dwFlags =//定义象素格式属性的一系列位标志,一般不互相排斥 PFD_DRAW_TO_WINDOW //指缓冲区可以在窗口或者设备表面绘图 | PFD_SUPPORT_OPENGL //缓冲区支持opengl绘图 |PFD_DOUBLEBUFFER //使用双缓冲区,在当前基本功能下,与PFD_SUPPOT_GDI相互排斥 | PFD_STEREO;//缓冲区是立体的,当前基本功能不支持这个标志 //_DONTCARE; pixelDesc.iPixelType = //像素格式的类型 PFD_TYPE_RGBA;//RGBA类型,每个象素依次有四个基本组成:红绿蓝所占的比例,一般在0-1之间设值, //最后一个是alpha,代表像素的透明程度,1表示完全不透明,0表示完全透明 pixelDesc.cColorBits = 32;//表示每个RGBA颜色缓冲区的位平面数目,(不包括alpha)这里值32位真彩色 pixelDesc.cRedBits = 8;//表示每个RGBA颜色缓冲区的红色位平面数目 pixelDesc.cRedShift = 16;//表示每个RGBA颜色缓冲区的红色位平面偏移量 pixelDesc.cGreenBits = 8;//表示每个RGBA颜色缓冲区的绿色位平面数目 pixelDesc.cGreenShift = 8;//表示每个RGBA颜色缓冲区的绿色位平面偏移量 pixelDesc.cBlueBits = 8;//表示每个RGBA颜色缓冲区的蓝色位平面数目 pixelDesc.cBlueShift = 0;//表示每个RGBA颜色缓冲区的蓝色位平面偏移量 pixelDesc.cAlphaBits = 0;//表示每个RGBA颜色缓冲区的alpha平面数目,alpha平面数目不被支持 pixelDesc.cAlphaShift = 0;//表示每个RGBA颜色缓冲区的alpha平面偏移量,alpha平面偏移量不被支持 pixelDesc.cAccumBits = 64;//累加缓冲区的位平面总数 pixelDesc.cAccumRedBits = 16;//累加缓冲区的红色位平面数 pixelDesc.cAccumGreenBits = 16;//累加缓冲区的绿色位平面数 pixelDesc.cAccumBlueBits = 16;//累加缓冲区的蓝色位平面数 pixelDesc.cAccumAlphaBits = 0;//累加缓冲区的alpha平面数 pixelDesc.cDepthBits = 32;//深度(z轴)缓冲区的深度值 pixelDesc.cStencilBits = 8;//模板缓冲区的深度值 pixelDesc.cAuxBuffers = 0;//辅助缓冲区的数目,不支持辅助缓冲区 //pixelDesc.iLayerType = PFD_MAIN_PLANE; 早期的opengl使用,现在不使用此参数,可忽略 pixelDesc.bReserved = 0;//定义覆盖及底层平面的编号,0-3个字节最多定义15个覆盖层平面, //4-7个平面最多定义15个底层平面 //pixelDesc.dwLayerMask = 0;早期的opengl使用,现在不使用此参数,可忽略 pixelDesc.dwVisibleMask = 0;//若像素类型为RGBA,定义底层平面的象素颜色或色彩指数 //pixelDesc.dwDamageMask = 0;早期的opengl使用,现在不使用此参数,可忽略 //像素格式设置完毕 m_pDC = new CClientDC(this);//动态生成一个CClientDC类的指针this指针覆给CTestView类的成员变量m_PDC int m_GLPixelIndex = ChoosePixelFormat(m_pDC->GetSafeHdc(),&pixelDesc); //选择像素格式 //GetSafeHdc()得到一个设备描述表的句柄,此为得到当前设备描述表的句柄 if(m_GLPixelIndex == 0) // Choose default { AfxMessageBox("no matched pixelformat!"); m_GLPixelIndex = 1; if(DescribePixelFormat(m_pDC->GetSafeHdc(),m_GLPixelIndex, sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)//当前描述表与定义的象素格式不符 //DescribePixelFormat提供与参数hdc参数相关的,由iPixelFormat标识的象素格式类型, //并由像素格式类型设置ppfd指向的PIXELFORMATDESCRIPTOR结构,参数依次为hdc,iPixelFormat,nByte,ppfd return FALSE; } if(!SetPixelFormat(m_pDC->GetSafeHdc(),m_GLPixelIndex,&pixelDesc)) //设置像素格式 return FALSE; return TRUE; }
/* 这段代码用来加载位图文件。 * 如果文件不存在,返回 NULL 告知程序无法加载位图。 * 关于用作纹理的图像。图像的宽和高必须是2的n次方;宽度和高度最小必须是64象素; * 并且出于兼容性的原因,图像的宽度和高度不应超过256象素。如果您的原始素材的宽度 * 和高度不是64,128,256象素的话,使用图像处理软件重新改变图像的大小。*/ AUX_RGBImageRec * COpenglbaseView::LoadBMP(char *Filename) { // 首先,我们创建一个文件句柄。句柄是个用来鉴别资源的数值,它使程序能够 //访问此资源。我们开始先将句柄设为 NULL 。 FILE *File=NULL; if (!Filename) //确保文件名已提供 { return NULL; } File=fopen(Filename,"r"); if (File)// 文件存在么? { fclose(File); return auxDIBImageLoad(Filename); // 载入位图并返回指针 } return NULL; }
int COpenglbaseView::LoadGLTextures() { GLuint loop; int Status=FALSE; AUX_RGBImageRec *TextureImage[5]; // 创建保存5个纹理的数据结构 memset(TextureImage,0,sizeof(void *)*5); // 初始化 if ((TextureImage[0]=LoadBMP("Data/logo.bmp")) && // 加载纹理0 (TextureImage[1]=LoadBMP("Data/mask1.bmp")) && // 加载掩模纹理1,作为“掩模”使用 (TextureImage[2]=LoadBMP("Data/image1.bmp")) && // 加载纹理1 (TextureImage[3]=LoadBMP("Data/mask2.bmp")) && // 加载掩模纹理2,作为“掩模”使用 (TextureImage[4]=LoadBMP("Data/image2.bmp"))) // 加载纹理2 { Status=TRUE; glGenTextures(5, &texture[0]); // 创建5个纹理 for (loop=0; loop<5; loop++) // 循环加载5个纹理 { glBindTexture(GL_TEXTURE_2D, texture[loop]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[loop]->sizeX, TextureImage[loop]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[loop]->data); } } for (loop=0; loop<5; loop++) { if (TextureImage[loop]) { if (TextureImage[loop]->data) { free(TextureImage[loop]->data); } free(TextureImage[loop]); } } return Status; }
BOOL COpenglbaseView::InitializeOpenGL(CDC *pDC) { m_pDC=pDC; if(!SetupPixelFormat()) return FALSE; m_hRC=::wglCreateContext(m_pDC->GetSafeHdc());//产生一个新的opengl绘图描述表使之适合在参数hdc给出的设备上画图 ::wglMakeCurrent(m_pDC->GetSafeHdc(),m_hRC); SetLight();//设置光照环境 LoadGLTextures();//加载纹理 glEnable(GL_TEXTURE_2D);//启用纹理映射必须加此句 return TRUE; }
void COpenglbaseView::OnDraw(CDC* pDC) { COpenglbaseDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here static BOOL bBusy = FALSE; if (bBusy) { return; } bBusy=TRUE; //双缓存应用 ////////////////////////////////////////////////////////////////////////// RenderScene();//渲染场景 ////////////////////////////////////////////////////////////////////////// glFlush();//完成绘制 SwapBuffers(wglGetCurrentDC());//双缓存应用 bBusy=FALSE; }
int COpenglbaseView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here ////////////////////////////////////////////////////////////////////////// //初始化OpenGL和定时器函数 m_pDC=new CClientDC(this); SetTimer(1,20,NULL); InitializeOpenGL(m_pDC); ////////////////////////////////////////////////////////////////////////// return 0; }
void COpenglbaseView::OnDestroy() { CView::OnDestroy(); ////////////////////////////////////////////////////////////////////////// //删除调色板和渲染上下文、定时器 wglMakeCurrent(NULL,NULL); if(m_hRC) wglDeleteContext(m_hRC); m_hRC=0; if (m_pDC) { delete m_pDC; } KillTimer(1); }
void COpenglbaseView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); // TODO: Add your message handler code here //添加窗口缩放时的图形变换函数 glViewport(0,0,cx,cy); }
void COpenglbaseView::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default ////////////////////////////////////////////////////////////////////////// //添加定时器响应函数和场景和更新函数 Invalidate(FALSE); ////////////////////////////////////////////////////////////////////////// CView::OnTimer(nIDEvent); }
BOOL COpenglbaseView::RenderScene() { glClearColor(1.0f,0.0f,0.0f,0.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glBindTexture(GL_TEXTURE_2D,texture[0]);// 选择Logo纹理 glBegin(GL_QUADS); // 绘制纹理四边形 glTexCoord2f(0.0f, 0.0f); glVertex2f(-0.5,-0.5); glTexCoord2f(1.0f, 0.0f); glVertex2f(0.5,-0.5); glTexCoord2f(1.0f, 1.0f); glVertex2f(0.5,0.5); glTexCoord2f(0.0f, 1.0f); glVertex2f(-0.5,0.5); glEnd(); return TRUE; }