opengl纹理
- 格式:docx
- 大小:31.22 KB
- 文档页数:9
gl_texture_external_oes 用法一、概述gl_texture_external_oes是OpenGL ES 2.0中的一个特性,用于在渲染过程中使用纹理贴图。
它允许应用程序将纹理数据存储在外部存储设备上,并在需要时从外部存储设备中加载纹理数据。
这可以提高应用程序的性能和效率,特别是在处理大量纹理数据时。
二、使用场景1. 大型纹理:当应用程序需要使用大量纹理时,将纹理数据存储在外部存储设备上可以显著提高性能。
应用程序可以定期加载所需的纹理数据,而不是每次渲染时都加载整个纹理。
2. 多分辨率纹理:应用程序可以存储不同分辨率的纹理数据,并根据需要加载适当的分辨率。
这可以提高纹理的质量和性能。
3. 动态纹理:当应用程序需要实时更新纹理时,使用gl_texture_external_oes可以减少渲染过程中的计算负担。
应用程序可以在后台线程中更新纹理数据,并在需要时将其加载到渲染过程中。
三、使用步骤1. 创建外部存储设备目录:应用程序需要创建一个外部存储设备目录,用于存储纹理数据。
可以使用Android API中的FileManager 类来创建目录。
2. 创建纹理对象:使用OpenGL ES中的glGenTextures()函数创建一个纹理对象,用于存储外部存储设备上的纹理数据。
3. 绑定纹理对象:使用OpenGL ES中的glBindTexture()函数将纹理对象绑定到纹理单元。
4. 设置纹理参数:使用OpenGL ES中的glTexParameter()函数设置纹理参数,例如外部格式、外部采样器类型等。
5. 加载纹理数据:使用Android API中的MediaStore类从外部存储设备中加载纹理数据。
可以将纹理数据保存为文件或媒体库中的条目,并使用MediaStore类检索它们。
6. 将纹理数据传输到GPU:使用OpenGL ES中的glTexImage2D()函数将纹理数据传输到GPU。
OpenGL的帧缓冲对象和浮点纹理(转载⾃Graphixer何咏的博客)接下来准备实现光照贴图的打包和预计算了。
因为想实现HDR,光照贴图准备存储为RGBE或浮点格式。
为了渲染浮点格式的光照贴图,就需要解决两个问题,⼀是如何让OpenGL能够真正地处理浮点格式的纹理,⽽不是把他们截断到[0,1]区间内;⼆是如何将场景渲染到浮点格式的纹理中,以便对这个纹理进⾏Tone mapping 和Bloom等操作。
今天花了⼀晚上的时间在⽹上搜索资料,学习了Frame Buffer Object的⽤法。
FBO是⽬前实现RTT和GPGPU算法最好的解决⽅案,因为它的接⼝设计相对合理,避免了显存到内存之间的数据交换。
FBO相当于各类帧缓冲,是⼀个渲染对象。
在传统的渲染管线中,渲染后的数据输出到各种帧缓冲中,如颜⾊缓冲,深度缓冲等。
有了FBO之后,就可以把数据渲染到已粘附到FBO的纹理中。
稍后将会给出具体的代码,结合代码和分析你将很容易掌握FBO的⽤法。
现在先讨论⼀下OpenGL的浮点纹理。
我们先来看⼀下OpenGL的glTexImage2D函数原型。
void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border,GLenum format, GLenum type, const GLvoid *pixels );以前,我们向纹理对象提供数据时是这样做的:glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,pixels);我们为Type参数提供的值是GL_UNSIGNED_BYTE表⽰我们的数据在内存中的存储格式为⽆符号字节型整数。
现在我们的纹理格式为浮点型,我们会很⾃然地想到,能不能把上述函数调⽤改为:GL_FLOAT,pixels);glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,width,height,0,GL_RGBA,GL_FLOAT来让OpenGL接收浮点纹理呢?答案是不可以。
openGL三维网格坐标,旋转,缩放,灯光设置,纹理读取,模型读取(MFC单文档)在我的MFC单文档项目中enableview.h和enableview.cpp负责上面的窗口建立,myopenglview.h和myopenglView.cpp主要是功能的实现1.三维网格建立:void GLGrid(float pt1x, float pt1y, float pt1z, float pt2x, float pt2y, float pt2z, int num){const float _xLen = (pt2x - pt1x) / num;const float _yLen = (pt2y - pt1y) / num;const float _zLen = (pt2z - pt1z) / num; glLineWidth(2.f);glLineStipple(1, 0x0303);//线条样式glBegin(GL_LINES);glEnable(GL_LINE_SMOOTH);int xi = 0;int yi = 0;int zi = 0;//绘制平行于X的直线for (zi = 0; zi <= num; zi++){float z = _zLen * zi + pt1z;for (yi = 0; yi <= num; yi++){float y = _yLen * yi + pt1y;glVertex3f(pt1x, y, z);glVertex3f(pt2x, y, z);}}//绘制平行于Y的直线for (zi = 0; zi <= num; zi++){float z = _zLen * zi + pt1z;for (xi = 0; xi <= num; xi++){float x = _xLen * xi + pt1x;glVertex3f(x, pt1y, z);glVertex3f(x, pt2y, z);}}//绘制平行于Z的直线for (yi = 0; yi <= num; yi++){float y = _yLen * yi + pt1y;for (xi = 0; xi <= num; xi++){float x = _xLen * xi + pt1x;glVertex3f(x, y, pt1z);glVertex3f(x, y, pt2z);}}glEnd();}void CmyopenglView::ordination() {glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glEnable(GL_BLEND);glEnable(GL_POINT_SMOOTH); //设置反走样glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); //设置反走样glEnable(GL_LINE_SMOOTH);glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);glEnable(GL_POL YGON_SMOOTH);glHint(GL_POL YGON_SMOOTH_HINT, GL_NICEST);glRotatef(-45, 0.0, 1.0, 0.0);//网格glPushMatrix();glColor3f(0.9f, 0.9f, 0.9f);glTranslatef(-4, -4, -4);GLGrid(0,0,0,8,0,8,20);glPopMatrix();glPushMatrix();glTranslated(-4,4, -4);glRotatef(90, 1.0, 0.0, 0.0);glColor3f(0.9f, 0.9f, 0.0f);GLGrid(0, 0, 0, 8, 0, 8, 20);glPopMatrix();glPushMatrix();glTranslatef(-4, -4, -4);glRotatef(90, 0.0, 0.0, 1.0);glColor3f(0.0f, 0.9f, 0.0f);GLGrid(0, 0, 0, 8, 0, 8, 20);glPopMatrix();glDisable(GL_BLEND);glDisable(GL_LINE_SMOOTH);glDisable(GL_POINT_SMOOTH);glDisable(GL_POL YGON_SMOOTH);}我们在ordination()函数中增加绘制x,y,z坐标的代码void CmyopenglView::ordination() {glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glEnable(GL_BLEND);glEnable(GL_POINT_SMOOTH); //设置反走样glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); //设置反走样glEnable(GL_LINE_SMOOTH);glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);glEnable(GL_POL YGON_SMOOTH);glHint(GL_POL YGON_SMOOTH_HINT, GL_NICEST);glRotatef(-45, 0.0, 1.0, 0.0);//网格glPushMatrix();glColor3f(0.9f, 0.9f, 0.9f);glTranslatef(-4, -4, -4);GLGrid(0,0,0,8,0,8,20);glPopMatrix();glPushMatrix();glTranslated(-4,4, -4);glRotatef(90, 1.0, 0.0, 0.0);glColor3f(0.9f, 0.9f, 0.0f);GLGrid(0, 0, 0, 8, 0, 8, 20);glPopMatrix();glPushMatrix();glTranslatef(-4, -4, -4);glRotatef(90, 0.0, 0.0, 1.0);glColor3f(0.0f, 0.9f, 0.0f);GLGrid(0, 0, 0, 8, 0, 8, 20);glPopMatrix();//x//glTranslatef(-2, -2, -2);glColor3f(1.0f, 0.0f, 0.0f);glBegin(GL_LINES);glVertex3f(0.0f, 0.0f, 0.0f);glVertex3f(3.5, 0.0f, 0.0f);glEnd();glPushMatrix();glTranslatef(3.5, 0.0f, 0.0f);glRotatef(90.0f, 0.0f, 1.0f, 0.0f);glutWireCone(0.027, 0.09, 10, 10);glPopMatrix();//yglColor3f(0.0f, 1.0f, 0.0f);glBegin(GL_LINES);glVertex3f(0.0f, 0.0f, 0.0f);glVertex3f(0.0, 3.5, 0.0f);glEnd();glPushMatrix();glTranslatef(0.0, 3.5, 0.0f);glRotatef(90.0f, -1.0f, 0.0f, 0.0f);glutWireCone(0.027, 0.09, 10, 10);glPopMatrix();//zglColor3f(0.0f, 0.0f, 1.0f);glBegin(GL_LINES);glVertex3f(0.0f, 0.0f, 0.0f);glVertex3f(0.0, 0.0f, 3.5);glEnd();glPushMatrix();glTranslatef(0.0, 0.0f, 3.5);glRotatef(90.0f, 0.0f, 0.0f, 1.0f);glutWireCone(0.027, 0.09, 10, 10);glPopMatrix();glDisable(GL_BLEND);glDisable(GL_LINE_SMOOTH);glDisable(GL_POINT_SMOOTH);glDisable(GL_POL YGON_SMOOTH); }、2.基本三维图形创建点模型/线模型/面模型glColor3f(1.0f, 1.0f, 1.0f);if (model == 1){if (type == 1)glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);if (type == 2)glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);if (type == 3)glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);auxSolidCube(4);}if (model == 2){if (type == 1)glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);if (type == 2)glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);if(type == 3)glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);auxSolidSphere(3.0);}if (model == 3){glPushMatrix();glRotatef(90, -1.0, 0.0, 0.0);if (type == 1)glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);if (type == 2)glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);if (type == 3)glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);glutSolidCone(3, 3, 100, 100);glPopMatrix();}if (model == 4){if (type == 1)glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);if (type == 2)glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);if (type == 3)glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);glutSolidTeapot(2.5);}3.鼠标相应旋转缩放BOOL enableview::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt){// TODO: 在此添加消息处理程序代码和/或调用默认值double a = zDelta / 120;if ((scale + a * 0.1) < 10)scale += a * 0.1;this->InvalidateRect(NULL, FALSE);return CView::OnMouseWheel(nFlags, zDelta, pt);}void enableview::OnMouseMove(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值if (nFlags & MK_LBUTTON == TRUE) {//MessageBox("mouse move function triggered!", "attentino", MB_OK);du += point.x - oldmx; //鼠标在窗口x轴方向上的增量加到视点绕y轴的角度上,这样就左右转了h += 0.03f*(point.y - oldmy); //鼠标在窗口y轴方向上的改变加到视点的y坐标上,就上下转了if (h>15.0f) h = 15.0f; //视点y坐标作一些限制,不会使视点太奇怪else if (h<-5.0f) h = -5.0f;oldmx = point.x, oldmy = point.y; //把此时的鼠标坐标作为旧值,为下一次计算增量做准备/*CString debug;debug.Format(_T("h,du= %0.3f %3d\n"), h, du);OutputDebugString(debug);*///OnPaint();this->OnDraw(this->GetDC()); //重绘界面}else if (nFlags & MK_RBUTTON == TRUE){oldmx += point.x - oldmx;oldmy += point.y - oldmy;glTranslatef(oldmx, oldmy, -0.1f);this->OnDraw(this->GetDC());oldmx = point.x, oldmy = point.y;}else {oldmx = point.x, oldmy = point.y;//OutputDebugString(_T("mouse up\n"));}//CView::OnMouseMove(nFlags, point);}4.键盘相应旋转缩放BOOL CmyopenglView::PreTranslateMessage(MSG* pMsg){if (pMsg->message == WM_KEYDOWN) // If a keydown message{if (pMsg->wParam == _T('W')){this->rotate_x += 6.0;if (this->rotate_x > 360)this->rotate_x = -360;this->InvalidateRect(NULL, FALSE);}if (pMsg->wParam == _T('X')){this->rotate_x += 6.0;if (this->rotate_x < -360)this->rotate_x = 360;this->InvalidateRect(NULL, FALSE);}if (pMsg->wParam == _T('A')){this->rotate_y -= 6.0;if (this->rotate_y < -360)this->rotate_y = 360;this->InvalidateRect(NULL, FALSE);}if (pMsg->wParam == _T('D')){this->rotate_y += 6.0;if (this->rotate_y > 360)this->rotate_y = -360;this->InvalidateRect(NULL, FALSE);}if (pMsg->wParam == _T('Z')){this->rotate_z -= 6.0;if (this->rotate_z < -360)this->rotate_z = 360;this->InvalidateRect(NULL, FALSE);}if (pMsg->wParam == _T('E')){this->rotate_z += 6.0;if (this->rotate_z > 360)this->rotate_z = -360;this->InvalidateRect(NULL, FALSE);}if (pMsg->wParam == _T('Q')){if ((scale + 2) < 10)scale += 2;this->InvalidateRect(NULL, FALSE);}if (pMsg->wParam == _T('R')){scale -= 2;this->InvalidateRect(NULL, FALSE);}}return CView::PreTranslateMessage(pMsg);}5.灯光设置:单方位灯光/多方位光/多种类型光效果// 设置材质颜色GLfloat mat_ambient[] = { 0.6f, 0.6f, 0.6f, 1.0f }; // 蓝色的材质环境光GLfloat mat_diffuse[] = { 0.6f, 0.6f, 0.9f, 1.0f }; // 蓝色的材质漫反射光GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; // 全白色的材质镜面反射光GLfloat mat_emission[] = { 0.5f, 0.5f, 0.5f, 1.0f }; // 淡白色的材质辐射光GLfloat no_mat[] = { 0.0f, 0.0f, 0.0f, 1.0f }; // 无光(黑色光),用于关闭某种属性光时应用GLfloat no_shininess[] = { 0.0f }; // 无镜面反射GLfloat low_shininess[] = { 5.0f }; // 低镜面反射指数GLfloat high_shininess[] = { 70.0f }; // 高镜面反射指数void CmyopenglView::InitalLigt(){GLfloat light_position1[4] = { -52, -16, -50, 0 };GLfloat light_position2[4] = { -26, -48, -50, 0 };GLfloat light_position3[4] = { 16, -52, -50, 0 };GLfloat direction1[3] = { 52, 16, 50 };GLfloat direction2[3] = { 26, 48, 50 };GLfloat direction3[3] = { -16, 52, 50 };GLfloat light_position4[4] = { 52, 16, 50, 0 };GLfloat light_position5[4] = { 26, 48, 50, 0 };GLfloat light_position6[4] = { -16, 52, 50, 0 };GLfloat direction4[3] = { -52, -16, -50 };GLfloat direction5[3] = { -26, -48, -50 };GLfloat direction6[3] = { 16, -52, -50 };GLfloat color1[4], color2[4], color3[4], color4[4], color5[4], color6[4];glClearColor(1, 1, 1, 0);glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LESS);if (color_type == 0) { //彩色灯光color1[0] = 1; color1[1] = 0; color1[2] = 0; color1[3] = 1;color2[0] = 0.5; color2[1] = 1; color2[2] = 0; color2[3] = 1;color3[0] = 0; color3[1] = 0; color3[2] = 1; color3[3] = 1;color4[0] = 1; color4[1] = 0; color4[2] = 0; color4[3] = 1;color5[0] = 0.5; color5[1] = 1; color5[2] = 0; color5[3] = 1;color6[0] = 0; color6[1] = 0; color6[2] = 1; color6[3] = 1;GLfloat ambient[4] = { 0.3f, 0.3f, 0.3f, 1.0f };GLfloat material_color[4] = { 1, 1, 1, 0.5f };GLfloat material_specular[4] = { 0.5f, 0.5f, 0.5f, 0.5f };GLfloat material_ambient[4] = { 0.0, 0.0, 0.0, 0.0 };glLightfv(GL_LIGHT3, GL_POSITION, light_position4);glLightfv(GL_LIGHT3, GL_SPOT_DIRECTION, direction4);glLightfv(GL_LIGHT3, GL_DIFFUSE, color4);glLightfv(GL_LIGHT3, GL_SPECULAR, color4);glLightfv(GL_LIGHT4, GL_POSITION, light_position5);glLightfv(GL_LIGHT4, GL_SPOT_DIRECTION, direction5);glLightfv(GL_LIGHT4, GL_DIFFUSE, color5);glLightfv(GL_LIGHT4, GL_SPECULAR, color5);glLightfv(GL_LIGHT5, GL_POSITION, light_position6);glLightfv(GL_LIGHT5, GL_SPOT_DIRECTION, direction6);glLightfv(GL_LIGHT5, GL_DIFFUSE, color6);glLightfv(GL_LIGHT5, GL_SPECULAR, color6);glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material_specular);glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material_color);glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material_ambient);glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 128);glDisable(GL_LIGHT0);glDisable(GL_LIGHTING);glEnable(GL_LIGHTING);glEnable(GL_LIGHT3);glEnable(GL_LIGHT4);glEnable(GL_LIGHT5);glDisable(GL_COLOR_MATERIAL);return;}if (color_type == 1){//白色灯光glDisable(GL_LIGHT3);glDisable(GL_LIGHT4);glDisable(GL_LIGHT5);glDisable(GL_LIGHTING);GLfloat m_LightPostion[4] = { 0.0f, 10.0f, 10.0f, 1.0f };GLfloat ambientLight[] = { 0.25f, 0.25f, 0.25f, 1.0f };GLfloat diffuseLight[] = { 0.5, 0.5f, 0.5f, 1.0f };GLfloat specularLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };glEnable(GL_LIGHTING);glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);glLightfv(GL_LIGHT0, GL_POSITION, m_LightPostion);glEnable(GL_LIGHT0);glEnable(GL_COLOR_MATERIAL);glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);}else {glDisable(GL_LIGHT3);glDisable(GL_LIGHT4);glDisable(GL_LIGHT5);glDisable(GL_LIGHTING);glDisable(GL_COLOR_MATERIAL);glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);//glDisable(GL_LIGHTING);GLfloat no_ambientLight[] = { 0.0f, 0.0f, 0.0f, 1.0f }; // 用于关掉默认的全局环境光// 设置光源的颜色GLfloat ambientLight[] = { 0.8f, 0.8f, 0.8f, 1.0f }; // 白色环境光GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8f, 1.0f }; // 白色漫射光GLfloat specularLight[] = { 0.8f, 0.8f, 0.8f, 1.0f }; // 白色镜面反射光GLfloat m_LightPostion[] = { 0.0f, 0.0f, 1.0f, 0.0f }; // 光源起始位置// 1.仅漫射光if (color_type == 12) {glEnable(GL_LIGHTING);//glLightModelfv(GL_LIGHT_MODEL_AMBIENT, no_ambientLight); // 关掉默认的全局环境光glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);glLightfv(GL_LIGHT0, GL_POSITION, m_LightPostion);glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat); // 关闭材质的环境反射光颜色glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); // 设置mat_diffuse的材质漫反射光glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat); //关闭材质的镜面反射光颜色glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess); // 设置材质的镜面反射指数为0glMaterialfv(GL_FRONT, GL_EMISSION, no_mat); // 关闭材质的辐射光glEnable(GL_LIGHT0);}// 2.仅镜面光if (color_type == 13) {glEnable(GL_LIGHTING);//glLightModelfv(GL_LIGHT_MODEL_AMBIENT, no_ambientLight); // 关掉默认的全局环境光glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);glLightfv(GL_LIGHT0, GL_POSITION, m_LightPostion);glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);glMaterialfv(GL_FRONT, GL_DIFFUSE, no_mat);glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);glEnable(GL_LIGHT0);}// 3.漫射光与低镜面光if (color_type == 16) {glEnable(GL_LIGHTING);glLightModelfv(GL_LIGHT_MODEL_AMBIENT, no_ambientLight); // 关掉默认的全局环境光glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);glLightfv(GL_LIGHT0, GL_POSITION, m_LightPostion);glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);glEnable(GL_LIGHT0);}// 4.辐射光与低镜面光if (color_type == 18) {glEnable(GL_LIGHTING);glLightModelfv(GL_LIGHT_MODEL_AMBIENT, no_ambientLight); // 关掉默认的全局环境光glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);glLightfv(GL_LIGHT0, GL_POSITION, m_LightPostion);glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);glMaterialfv(GL_FRONT, GL_DIFFUSE, no_mat);glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess);glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);glEnable(GL_LIGHT0);}}}6.纹理载入映射BOOL CmyopenglView::LoadImageResources() {FILE *File = NULL;AUX_RGBImageRec* textrue_Resource[6];if (model == 5 && type == 51)resource_path[0] = "shuijing.bmp";if(model == 5 && type == 52 )resource_path[0] = "earth.bmp";if (model == 5 && type == 53)resource_path[0] = "painting1.bmp";if (model == 5 && type == 54)resource_path[0] = "5.bmp";/*resource_path[1] = "image/2.bmp";resource_path[2] = "image/3.bmp";resource_path[3] = "image/4.bmp";resource_path[4] = "image/5.bmp";resource_path[5] = "image/6.bmp";*///装载图像文件资源for (int i = 0; i < 6; i++)//如果只需要一张贴图其实resource_path数组只需要一个元素就可以了{File = fopen(resource_path[0], "r");if (!File){//MessageBox(NULL, "加载图像资源文件失败!", "Fail", MB_OK);return FALSE;}fclose(File);CString str = CString(resource_path[0]);USES_CONVERSION;LPCWSTR wszClassName = A2CW(W2A(str));textrue_Resource[i] = auxDIBImageLoad(wszClassName);File = NULL;}//生成纹理glGenTextures(6, texture);for (int i = 0; i < 6; i++){glBindTexture(GL_TEXTURE_2D, texture[i]);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//Use the mipmap textureglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, \textrue_Resource[i]->sizeX, textrue_Resource[i]->sizeY, \GL_RGB, GL_UNSIGNED_BYTE, textrue_Resource[i]->data);//删除堆上的临时图像delete textrue_Resource[i]->data;delete textrue_Resource[i];}return TRUE;}void CmyopenglView::Draw_textrue() {GLUquadricObj* qobj;glClearColor(0.0, 0.0, 0.0, 0.0);glShadeModel(GL_FLAT);glEnable(GL_DEPTH_TEST);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);InitalLigt(); ///初始化光照信息glEnable(GL_TEXTURE_2D);glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);glPushMatrix();glTranslatef(0.0f, 0.0f, scale); //滚轮缩放gluLookAt(r*cos(c*du), h, r*sin(c*du), 0, 0, 0, 0, 1, 0); //从视点看远点,y轴方向(0,1,0)是上方向,鼠标拖动glRotatef(this->rotate_x, 1.0, 0.0, 0.0);glRotatef(this->rotate_y, 0.0, 1.0, 0.0);glRotatef(this->rotate_z, 0.0, 0.0, 1.0);if (iao)ordination();glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);qobj = gluNewQuadric();//画球体glBindTexture(GL_TEXTURE_2D, texture[0]);glEnable(GL_TEXTURE_2D);gluQuadricTexture(qobj, GL_TRUE);//纹理函数if (type == 51){glBegin(GL_QUADS);// Front FaceglTexCoord2f(0.0f, 0.0f); glVertex3f(-3.0f, -3.0f, 3.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(3.0f, -3.0f, 3.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(3.0f, 3.0f, 3.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-3.0f, 3.0f, 3.0f);// Back FaceglTexCoord2f(0.0f, 0.0f); glVertex3f(-3.0f, -3.0f, -3.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(-3.0f, 3.0f, -3.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(3.0f, 3.0f, -3.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(3.0f, -3.0f, -3.0f);// Top FaceglTexCoord2f(0.0f, 0.0f); glVertex3f(-3.0f, 3.0f, -3.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(-3.0f, 3.0f, 3.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(3.0f, 3.0f, 3.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(3.0f, 3.0f, -3.0f);// Bottom FaceglTexCoord2f(0.0f, 0.0f); glVertex3f(-3.0f, -3.0f, -3.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(3.0f, -3.0f, -3.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(3.0f, -3.0f, 3.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-3.0f, -3.0f, 3.0f);// Right faceglTexCoord2f(0.0f, 0.0f); glVertex3f(3.0f, -3.0f, -3.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(3.0f, 3.0f, -3.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(3.0f, 3.0f, 3.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(3.0f, -3.0f, 3.0f);// Left FaceglTexCoord2f(0.0f, 0.0f); glVertex3f(-3.0f, -3.0f, -3.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(-3.0f, -3.0f, 3.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f(-3.0f, 3.0f, 3.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-3.0f, 3.0f, -3.0f);glEnd();}if( type == 52 )gluSphere(qobj, 4, 60, 60);//二次曲面qobjif( type == 53 )gluCylinder(qobj, 3.5, 3.5, 6, 26, 23);if( type == 54 )gluCylinder(qobj, 3.5, 0.0, 6, 26, 23);glPopMatrix();glDisable(GL_TEXTURE_2D);}6.读取obj模型我只是简单的读取vt,vn,f等基本参数void CmyopenglView::ReadObj(char* Filename) {VN.clear();V.clear();VT.clear();F.clear();FQ.clear();ifstream in(Filename);string aline; //逐行读入string erase;while (getline(in, aline)){if (aline[0] == 'v'){if (aline[1] == 'n') //vn{istringstream sin(aline);V ertex v;sin >> erase >> v.x >> v.y >> v.z;VN.push_back(v);}else if (aline[1] == 't')//vt{istringstream sin(aline);Texture v;sin >> erase >> v.s >> v.t;VT.push_back(v);}else //v{istringstream sin(aline);V ertex v;sin >> erase >> v.x >> v.y >> v.z;V.push_back(v);}}else if (aline[0] == 'f'){istringstream sin(aline);sin >> erase;vector<string> strvector;string temp;while (sin >> temp) {strvector.push_back(temp);}if (strvector.size() == 3) {//三角面片Face fff;for (int count = 0; count < 3; count++) {string kkk = strvector[count];int i = 0;int num = 0;//顶点索引for (; i < kkk.size() && kkk[i] != '/'; i++)num = num * 10 + kkk[i] - '0';fff.v[count] = num;i++;num = 0;//vtnum = 0;for (; i < kkk.size() && kkk[i] != '/'; i++)num = num * 10 + kkk[i] - '0';fff.vt[0] = num;i++;num = 0;//法向量索引for (; i < kkk.size() && kkk[i] != '/'; i++)num = num * 10 + kkk[i] - '0';fff.vn[count] = num;}F.push_back(fff);}else if (strvector.size() == 4){FaceQ fff;for (int count = 0; count < strvector.size(); count++) { string kkk = strvector[count];int i = 0;int num = 0;//顶点索引for (; i < kkk.size() && kkk[i] != '/'; i++)num = num * 10 + kkk[i] - '0';fff.v[count] = num;i++;num = 0;//vtnum = 0;for (; i < kkk.size() && kkk[i] != '/'; i++)num = num * 10 + kkk[i] - '0';fff.vt[0] = num;i++;num = 0;//法向量索引for (; i < kkk.size() && kkk[i] != '/'; i++)num = num * 10 + kkk[i] - '0';fff.vn[count] = num;}FQ.push_back(fff);}}}}绘制obj模型:void CmyopenglView::OnReadobj(){model = 6;wchar_t filters[] =L"3D模型文件(*.obj)\|*.obj|所有文件(*.*)|*.*||";CFileDialog fileDlg(TRUE, NULL, NULL,OFN_HIDEREADONL Y, filters);if (fileDlg.DoModal() == IDOK){CString strBuf = fileDlg.GetPathName();USES_CONVERSION;char *Filename = T2A(strBuf.GetBuffer(0));ReadObj(Filename);}stringstream ss;ss <<"OK!";string str;ss >> str;CString s;s = str.c_str();MessageBox(s);float min_x, min_y, min_z, max_x, max_y, max_z;min_x = min_y = min_z = 10000000;max_x = max_y = max_z = -1000000;for (int i = 0; i < V.size(); i++){min_x = min(min_x, V[i].x);min_y = min(min_y, V[i].y);min_z = min(min_z, V[i].z);max_x = max(max_x, V[i].x);max_y = max(max_y, V[i].y);max_z = max(max_z, V[i].z);}worldx = (min_x + max_x) / 2;worldy = (min_y + max_y) / 2;worldz = (min_z + max_z) / 2;type = 1;Invalidate();CDC* ppDC = GetWindowDC();OnDrawGL(ppDC);// TODO: 在此添加命令处理程序代码}void CmyopenglView::Draw_obj(){if (type == 1) {if (!VN.empty()) {for (int i = 0; i < F.size(); i++) {glBegin(GL_LINE_LOOP);for (int j = 0; j < 3; j++) {glV ertex3f(V[F[i].v[j] - 1].x, V[F[i].v[j] - 1].y, V[F[i].v[j] - 1].z);}glEnd();}for (int i = 0; i < FQ.size(); i++) {glBegin(GL_LINE_LOOP);for (int j = 0; j < 4; j++) {glV ertex3f(V[FQ[i].v[j] - 1].x, V[FQ[i].v[j] - 1].y, V[FQ[i].v[j] - 1].z);}glEnd();}}else {for (int i = 0; i < F.size(); i++) {glBegin(GL_LINE_LOOP);for (int j = 0; j < 3; j++) {glV ertex3f(V[F[i].v[j] - 1].x, V[F[i].v[j] - 1].y, V[F[i].v[j] - 1].z);}glEnd();}for (int i = 0; i < FQ.size(); i++) {glBegin(GL_LINE_LOOP);for (int j = 0; j < 4; j++) {glV ertex3f(V[FQ[i].v[j] - 1].x, V[FQ[i].v[j] - 1].y, V[FQ[i].v[j] - 1].z);}glEnd();}}}else if (type == 3) {glBegin(GL_POINTS);for (int i = 0; i < V.size(); i++)glV ertex3f(V[i].x, V[i].y, V[i].z);glEnd();}else{if (!VN.empty()) {for (int i = 0; i < F.size(); i++) {glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);glBegin(GL_TRIANGLES);for (int j = 0; j < 3; j++) {glNormal3f(VN[F[i].vn[j] - 1].x, VN[F[i].vn[j] - 1].y, VN[F[i].vn[j] - 1].z);glV ertex3f(V[F[i].v[j] - 1].x, V[F[i].v[j] - 1].y, V[F[i].v[j] - 1].z);}glEnd();}for (int i = 0; i < FQ.size(); i++) {glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);glBegin(GL_QUADS);for (int j = 0; j < 4; j++) {glNormal3f(VN[FQ[i].vn[j] - 1].x, VN[FQ[i].vn[j] - 1].y, VN[FQ[i].vn[j] - 1].z);glV ertex3f(V[FQ[i].v[j] - 1].x, V[FQ[i].v[j] - 1].y, V[FQ[i].v[j] - 1].z);}glEnd();}}else{for (int i = 0; i < F.size(); i++) {glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);glBegin(GL_TRIANGLES);for (int j = 0; j < 3; j++) {glV ertex3f(V[F[i].v[j] - 1].x, V[F[i].v[j] - 1].y, V[F[i].v[j] - 1].z);}glEnd();}for (int i = 0; i < FQ.size(); i++) {glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);glBegin(GL_QUADS);for (int j = 0; j < 4; j++) {glV ertex3f(V[FQ[i].v[j] - 1].x, V[FQ[i].v[j] - 1].y, V[FQ[i].v[j] - 1].z);}glEnd();}}}}。
opengl算法学习---纹理映射纹理映射纹理映射(Texture Mapping),⼜称纹理贴图,是将纹理空间中的纹理像素映射到屏幕空间中的像素的过程。
简单来说,就是把⼀幅图像贴到三维物体的表⾯上来增强真实感,可以和光照计算、图像混合等技术结合起来形成许多⾮常漂亮的效果。
纹理纹理可看成是⼀个或多个变量的函数,因此根据纹理定义域的不同,纹理可分为⼀维纹理、⼆维纹理、三维纹理和⾼维纹理。
基于纹理的表现形式,纹理⼜可分为颜⾊纹理、⼏何纹理两⼤类。
颜⾊纹理指的是呈现在物体表⾯上的各种花纹、图案和⽂字等,即通过颜⾊⾊彩或明暗度的变化体现出来的细节。
如⼤理⽯墙⾯、墙上贴的字画器⽫上的图案等。
⼏何纹理(也可称为凹凸纹理)是指基于景物表⾯微观⼏何形状的表⾯纹理,如桔⼦、树⼲、岩⽯、⼭脉等表⾯呈现的凸凹不平的纹理细节。
⽣成颜⾊纹理的⼀般⽅法是在⼀个平⾯区域(即纹理空间)上预先定义纹理图案,然后建⽴物体表⾯的点与纹理空间的点之间的对应—即映射。
以纹理空间的对应点的值乘以亮度值,就可把纹理图案附到物体表⾯上⽤类似的⽅法给物体表⾯产⽣凹凸不平的外观或称凹凸纹理。
普通纹理映射常见的2D纹理映射实际上是从纹理平⾯到三维物体表⾯的⼀个映射。
凹凸纹理映射前述各种纹理映射技术只能在光滑表⾯上描述各种事先定义的花纹图案,但不能表现由于表⾯的微观⼏何形状凹凸不平⽽呈现出来的粗糙质感,如布纹,植物和⽔果的表⽪等1978年Blinn提出了⼀种⽆需修改表⾯⼏何模型,即能模拟表⾯凹凸不平效果的有效⽅法⼀⼏何(凹凸)纹理映射(bump mapping)技术⼀个好的扰动⽅法应使得扰动后的法向量与表⾯的⼏何变换⽆关,不论表⾯如何运动或观察者从哪⼀⽅向观察表⾯,扰动后的表⾯法向量保持不变。
Blinn表⾯法⽮扰动法在表⾯任⼀点处沿其法向附加⼀微⼩增量,从⽽⽣成⼀张新的表⾯,计算新⽣成表⾯的法⽮量以取代原表⾯上相应点的法⽮量。
透明效果与混合光学原理:透射,折射,反射颜⾊调和法设a为透明体的不透明度,0≤a≤1,则I=αI a+(1−α)I ba=1,完全不透明a=0,完全透明alpha融合技术BlendingRGBA(a)不透明度a表⽰穿透该表⾯光线的数量a=1,完全不透明;a=0,完全透明gl.blendFunc(src_ factor,dst factor)混合后颜⾊=源颜⾊src_factor+⽬标颜⾊dst_factor源颜⾊:当前对象⽬标颜⾊:帧缓存像素透明与Z-Buffer消隐当对象A是透明的,即B透过A是部分可见时先画B再画A,可以处理先画A再画B,深度缓冲会从B取⼀个像素,同时注意到⼰经绘制了⼀个更近的像素(A),然后它的选择是不绘制BZ-Buffer消隐不能很好处理透明的物体,需要修正才⾏开启深度测试gl.enable(gl.DEPTH_TEST);绘制所有不透明物体(a=1.0)锁定深度缓冲区gl.depthMask(false);按从后向前次序绘制所有半透明物体释放深度缓冲区gl.depthMask(true);光线跟踪光线跟踪算法[WH1T80]是⽣成⾼度真实感图形的主要算法之⼀。
纹理映射(Texture Mapping,/wiki/Texture_mapping)是⼀一种中等难度的渲染⽅方法。
其基本思路是将⼀一张或者⼏几张图⽚片作为纹理,将其贴在模型表⾯面。
纹理映射的算法实在是⾮非常简单。
⽤用OpenGL实现纹理映射,最⼤大的难度不在于OpenGL,⽽而在于如何加载图⽚片!⽤用C++读取图⽚片有很多库可以选择,例如CImg、ImageStone和OpenCV之类的。
这些库都是跨平台的,但使⽤用起来过于复杂。
于是我找了⼀一个简单的库EasyBMP(/projects/easybmp/?source=directory),只能读取BMP 数据,够⽤用也跨平台。
所需要的就是将纹理图全部转换为BMP格式,⽤用图像处理软件很容易做到这⼀一点。
我们引⼊入⼀一个新的函数来加载纹理://加载纹理GLuint const char//使⽤用EasyBMP加载纹理图⽚片//使⽤用什么库没有关系,最终纹理需要⽣生成⼀一个数组,数组的格式如下://{r1,g1,b1,r2,g2,b2,...,rn,gn,bn},其中ri,gi,bi表⽰示i位置的//像素点的rgb值。
如果图像由alpha值,数组的格式如下://{r1,g1,b1,a1,r2,g2,b2,a2,...,rn,gn,bn,an}BMPReadFromFileint TellWidthint TellHeightunsigned char new unsignedchar3int0for int0for int0row col Redrow col Greenrow col Blue//创建纹理,并将纹理数据传递给OpenGLGLuint1glGenTextures1glBindTexture GL_TEXTURE_2D0//设置纹理参数glTexParameteri GL_TEXTURE_2D GL_TEXTURE_WRAP_S GL_REPEATglTexParameteri GL_TEXTURE_2D GL_TEXTURE_WRAP_T GL_REPEATglTexParameteri GL_TEXTURE_2D GL_TEXTURE_MAG_FILTERGL_LINEARglTexParameteri GL_TEXTURE_2D GL_TEXTURE_MIN_FILTERGL_LINEAR//传输数据glTexImage2D GL_TEXTURE_2D0GL_RGB0GL_RGB GL_UNSIGNED_BYTE deletereturn0加载纹理通常分为以下⼏几个步骤:(1)⽤用图像处理库(这⾥里是EasyBMP)读取纹理⽂文件。
view plaincopyprint? view plaincopyprint? view plaincopyprint? view plaincopyprint? view plaincopyprint?19. for (j = 0; j < checkImageWidth; j++) {20. c = ((((i&0x8)==0)^((j&0x8))==0))*255;21. checkImage[i][j][0] = (GLubyte) c;22. checkImage[i][j][1] = (GLubyte) c;23. checkImage[i][j][2] = (GLubyte) c;24. checkImage[i][j][3] = (GLubyte) 255;25. c = ((((i&0x10)==0)^((j&0x10))==0))*255;26. otherImage[i][j][0] = (GLubyte) c;27. otherImage[i][j][1] = (GLubyte) 0;28. otherImage[i][j][2] = (GLubyte) 0;29. otherImage[i][j][3] = (GLubyte) 255;30. }31. }32. }33.34. void init(void)35. {36. glClearColor (0.0, 0.0, 0.0, 0.0);37. glShadeModel(GL_FLAT);38. glEnable(GL_DEPTH_TEST);39.40. makeCheckImages();41. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);42.43. glGenTextures(2, texName);44. glBindTexture(GL_TEXTURE_2D, texName[0]);45. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);46. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);47. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,48. GL_NEAREST);49. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,50. GL_NEAREST);51. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth,52. checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,53. checkImage);54.55. glBindTexture(GL_TEXTURE_2D, texName[1]);56. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);57. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);58. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);59. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);60. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);61. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth,62. checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,63. otherImage);64.65. glEnable(GL_TEXTURE_2D);66. }67.68. void display(void)69. {70. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);71. glBindTexture(GL_TEXTURE_2D, texName[0]);72. glBegin(GL_QUADS);73. glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);74. glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0);75. glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0);76. glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0);77. glEnd();78. glBindTexture(GL_TEXTURE_2D, texName[1]);79. glBegin(GL_QUADS);80. glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);81. glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0);82. glTexCoord2f(1.0, 1.0); glVertex3f(2.41421, 1.0, -1.41421);83. glTexCoord2f(1.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421);84. glEnd();85. glFlush();86. }87.88. void reshape(int w, int h)89. {90. glViewport(0, 0, (GLsizei) w, (GLsizei) h);91. glMatrixMode(GL_PROJECTION);92. glLoadIdentity();93. gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);94. glMatrixMode(GL_MODELVIEW);95. glLoadIdentity();96. glTranslatef(0.0, 0.0, -3.6);97. }98.99. void keyboard(unsigned char key, int x, int y)100. {101. switch (key) {102. case 27:103. exit(0);104. break;105. }106. }107.108. int main(int argc, char** argv)109. {110. glutInit(&argc, argv);111. glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);112. glutInitWindowSize(250, 250);113. glutInitWindowPosition(100, 100);114. glutCreateWindow(argv[0]);115. init();116. glutReshapeFunc(reshape);117. glutDisplayFunc(display);118. glutKeyboardFunc (keyboard);119. glutMainLoop();120. return 0;121. }122. #else123. int main(int argc, char** argv)124. {125. fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0.\n"); 126. fprintf (stderr, "If your implementation of OpenGL Version 1.0 has the right extensions,\n"); 127. fprintf (stderr, "you may be able to modify this program to make it run.\n");128. return 0;129. }130. #endif运⾏结果:。
opengl 立方体纹理顶点索引定义问题的开发过程。
标题:通过OpenGL绘制立方体纹理:顶点和索引定义详解导言:OpenGL是一种跨平台的图形编程接口,可用于绘制复杂的图形和对象。
在本文中,我们将重点讨论如何使用OpenGL绘制一个带有纹理的立方体。
我们将从顶点和索引的定义开始,逐步详细介绍每个步骤。
第一步:导入所需的库和资源首先,我们需要导入OpenGL库和一些必要的资源。
在C++中,我们可以使用如下方式导入头文件:#include <GL/gl.h>#include <GL/glut.h>同时,我们还需要准备一个纹理图像。
这里我们假设已经有一个名为"texture.jpg"的纹理图像。
第二步:顶点定义一个立方体有六个面,每个面有两个三角形,每个三角形有三个顶点。
因此,我们总共需要定义36个顶点。
每个顶点由三个坐标和两个纹理坐标组成。
在OpenGL中,我们可以使用GLfloat类型定义顶点坐标。
顶点坐标数据GLfloat vertices[] = {前面-0.5f, -0.5f, 0.5f, 左下0.5f, -0.5f, 0.5f, 右下-0.5f, 0.5f, 0.5f, 左上0.5f, 0.5f, 0.5f, 右上后面-0.5f, -0.5f, -0.5f, 左下0.5f, -0.5f, -0.5f, 右下-0.5f, 0.5f, -0.5f, 左上0.5f, 0.5f, -0.5f, 右上左边-0.5f, -0.5f, 0.5f, 左下-0.5f, -0.5f, -0.5f, 右下-0.5f, 0.5f, 0.5f, 左上-0.5f, 0.5f, -0.5f, 右上右边0.5f, -0.5f, 0.5f, 左下0.5f, -0.5f, -0.5f, 右下0.5f, 0.5f, 0.5f, 左上0.5f, 0.5f, -0.5f, 右上上面-0.5f, 0.5f, 0.5f, 左下0.5f, 0.5f, 0.5f, 右下-0.5f, 0.5f, -0.5f, 左上0.5f, 0.5f, -0.5f, 右上下面-0.5f, -0.5f, 0.5f, 左下0.5f, -0.5f, 0.5f, 右下-0.5f, -0.5f, -0.5f, 左上0.5f, -0.5f, -0.5f, 右上};第三步:纹理坐标定义除了顶点坐标,我们还需要为每个顶点定义纹理坐标。
texture() 函数texture() 函数是OpenGL中用于进行纹理映射的函数。
它的作用是将纹理映射到几何图形上,从而使得几何图形具有更为丰富的外观和细节。
在OpenGL中,纹理是一种图像,可以被映射到几何图形的表面上。
纹理可以是任何图像,例如照片、绘画、文本等等。
texture() 函数的语法如下:vec4 texture(sampler2D sampler, vec2 coord)其中,sampler2D 表示纹理采样器,用于指定纹理的类型和纹理数据的来源;vec2 表示纹理坐标,用于指定纹理在几何图形上的映射位置。
texture() 函数返回一个vec4 类型的向量,表示纹理在指定位置的颜色值。
在使用texture() 函数时,需要先将纹理数据加载到OpenGL中。
这可以通过以下步骤完成:1. 创建纹理对象:使用glGenTextures() 函数创建一个纹理对象,并将其绑定到当前的纹理单元上。
2. 加载纹理数据:使用glTexImage2D() 函数将纹理数据加载到OpenGL中。
3. 设置纹理参数:使用glTexParameteri() 函数设置纹理的过滤方式、重复方式等参数。
4. 绑定纹理:使用glBindTexture() 函数将纹理绑定到当前的纹理单元上。
一旦纹理数据加载到OpenGL中,就可以使用texture() 函数将纹理映射到几何图形上。
在进行纹理映射时,需要注意纹理坐标的范围和方向。
纹理坐标的范围通常为[0,1],而纹理坐标的方向与屏幕坐标的方向相反。
总之,texture() 函数是OpenGL中用于进行纹理映射的重要函数,它可以使几何图形具有更为丰富的外观和细节,提高图形渲染的质量和效果。
opengl顶点坐标纹理坐标关系OpenGL是一种图形编程接口,用于创建交互式三维应用程序。
OpenGL依靠一些最基本的图形概念来定义应用程序中的所有对象,其中包括顶点,纹理和坐标。
在OpenGL 中,这些概念之间的关系是一个非常重要的方面,特别是在创建三维模型时。
在OpenGL中,一个模型是由一组顶点定义的。
每个顶点包含三个坐标值:x、y和z。
这些坐标值表示三维空间中的位置。
例如,如果我们想要绘制一个正方体,我们需要定义每个顶点的坐标值。
正方体有六个面,每个面有四个顶点。
因此,我们需要定义顶点的坐标值为(1,1,1)、(-1,1,1)、(-1,-1,1)、(1,-1,1)、(1,1,-1)、(-1,1,-1)、(-1,-1,-1)和(1,-1,-1),这些坐标值确定了正方体的形状和大小。
除了顶点坐标外,纹理坐标也是非常重要的。
纹理是一张平面图像,用于覆盖到对象表面上,使其贴图效果更加真实。
每个像素点对应到一个坐标系中的点,我们称之为纹理坐标。
纹理坐标是介于0和1之间的浮点数,它们控制哪些部分的纹理图像用于哪些部分的模型表面。
在OpenGL中,纹理坐标通过顶点属性向着色器传递,然后用于计算纹理颜色。
顶点和纹理坐标之间的关系是通过OpenGL的纹理映射功能实现的。
纹理映射可将纹理图像映射到模型表面上,使其具有更丰富的视觉效果。
为了实现这一点,我们需要指定每个顶点的纹理坐标,以便在绘制过程中正确应用纹理贴图。
通常,每个顶点具有一个对应的纹理坐标,然后OpenGL会将这些纹理坐标插值成一个平滑的纹理映射区域,以便在绘制过程中创建出更加真实的纹理贴图效果。
在OpenGL中,我们通常使用两组坐标系来表示顶点和纹理坐标之间的关系。
世界坐标系用于定义三维物体的位置和大小,而纹理坐标系用于确定纹理图像的坐标位置。
由于这两个坐标系使用不同的度量单位,所以我们需要进行特殊的映射处理,以便正确地将纹理映射到模型表面上。
OpenGL的算法分类一、概述OpenGL(Open Graphics Library)是一个跨平台的图形编程接口,用于渲染2D和3D图形。
它提供了一系列的函数和工具,帮助开发者创建各种图形效果。
在OpenGL中,算法是关键的组成部分,它们被用于处理和渲染图形数据。
本文将对OpenGL中的算法进行分类和探讨。
二、OpenGL的算法分类在OpenGL中,算法可以根据其功能和用途进行分类。
下面将介绍几种常见的OpenGL算法分类。
2.1 顶点处理算法顶点处理算法是OpenGL中最基本的算法之一。
它负责对输入的顶点数据进行处理和变换,以生成最终的图形。
顶点处理算法通常包括以下几个阶段:1.顶点输入:将顶点数据输入到OpenGL中。
2.顶点着色器:对每个顶点进行变换和处理。
3.图元装配:将顶点组装成图元,如点、线、三角形等。
4.光栅化:将图元转化为像素,确定其在屏幕上的位置。
5.片段着色器:对每个像素进行处理,确定其颜色等属性。
2.2 光照算法光照算法用于模拟光的效果,使渲染的图形更加真实。
它基于光照模型,计算每个像素的颜色和明暗程度。
常见的光照算法包括:1.平行光照算法:模拟来自无限远处的光源,如太阳光。
2.点光源算法:模拟来自特定位置的光源,如灯泡。
3.聚光灯算法:模拟来自特定方向的光源,如手电筒。
2.3 纹理映射算法纹理映射算法用于将纹理图像映射到图形上,增加图形的细节和真实感。
它通过将纹理坐标与顶点坐标进行映射,确定每个像素的颜色。
常见的纹理映射算法包括:1.环境映射算法:将环境反射纹理映射到图形上,使其看起来具有反射光的效果。
2.法线映射算法:将法线纹理映射到图形上,使其看起来具有凹凸不平的效果。
3.投影纹理映射算法:将投影纹理映射到图形上,模拟物体在不同光照条件下的投影效果。
2.4 抗锯齿算法抗锯齿算法用于减少图形边缘的锯齿状效果,提高图形的平滑度。
它通过对图形进行采样和滤波,减少锯齿的出现。
opengl 立方体纹理顶点索引定义-回复OpenGL立方体纹理顶点索引定义OpenGL是一种图形编程接口,用于渲染2D和3D图形。
在OpenGL中,我们可以使用纹理贴图来给图形对象添加更多的细节和逼真感。
本文将重点讨论如何使用顶点和索引来定义一个带有纹理的立方体。
第一步:顶点定义在OpenGL中,一个3D对象的顶点通常使用(x, y, z)坐标来表示。
对于立方体而言,我们可以使用8个顶点来定义。
一个立方体的八个顶点可以如下定义:顶点1: (-1.0, 1.0, 1.0)顶点2: (1.0, 1.0, 1.0)顶点3: (-1.0, -1.0, 1.0)顶点4: (1.0, -1.0, 1.0)顶点5: (-1.0, 1.0, -1.0)顶点6: (1.0, 1.0, -1.0)顶点7: (-1.0, -1.0, -1.0)顶点8: (1.0, -1.0, -1.0)这些坐标定义了立方体的8个顶点,每个顶点都具有一个唯一的坐标。
第二步:纹理坐标定义在OpenGL中,我们可以为每个顶点定义一个纹理坐标。
纹理坐标用来确定在纹理贴图中的哪个位置采样颜色。
纹理坐标通常使用(u, v)坐标表示,并且取值范围从0到1。
对于立方体来说,我们可以为每个顶点定义一个纹理坐标。
纹理坐标可以如下定义:顶点1: (0.0, 1.0)顶点2: (1.0, 1.0)顶点3: (0.0, 0.0)顶点4: (1.0, 0.0)顶点5: (0.0, 1.0)顶点6: (1.0, 1.0)顶点7: (0.0, 0.0)顶点8: (1.0, 0.0)这些纹理坐标定义了立方体的每个顶点在纹理贴图中的采样位置。
第三步:索引定义在OpenGL中,我们通常使用索引数组来确定如何连接顶点以形成图形对象。
对于立方体而言,我们可以使用索引来确定每个顶点的连接关系。
编写一个索引数组可以减少顶点的重复定义,从而节省内存。
立方体的索引定义如下所示:索引1: 0索引2: 1索引3: 2索引4: 3索引5: 4索引6: 5索引7: 6索引8: 7索引9: 0索引10: 4索引11: 1索引12: 5索引13: 2索引14: 6索引15: 3索引16: 7索引17: 0索引18: 2索引19: 1索引20: 3索引21: 4索引22: 6索引23: 5索引24: 7这些索引定义了顶点之间的连接关系,从而构建了立方体的形状。
OpenGL可以把纹理映射到指定的图形的表面上。
简单一点的,就是给平面映射纹理,比如一个四边形,一个长方体的6个面,都关于将一个位图作为纹理映射到某个或者多个面上,可以学习Jeff Molofee的OpenGL系列对于指定的多个纹理,要根据自己的需要映射到不同的面上,需要对位图创建一个数组,用来存储位图的名称,然后在初始化Op成多个纹理存储到一个纹理数组中,接着就可以指定绘制的某个面,对该指定的面进行纹理下面,在的Jeff Molofee教程的第六课的基础上,实现对6个面分别进行不同的纹理映射准备工作就是制作6幅不同的位图,如图所示:关键代码及其说明如下。
创建全局纹理数组GLuint texture[6]; // 创建一个全局的纹理数组,用来存储将位图转换之后得到的纹理,对应于立方加载位图文件加载位图,也就是把位图读取到内存空间,实现纹理的创建,加载位图的函数说明一下AUX_RGBImageRec *LoadBMP(char *Filename) // 根据位图文件的名称进行加载{FILE *File=NULL; // 文件指针if (!Filename) // 如果没有指定位图文件名称就返回NULL{return NULL;}File=fopen(Filename,"r"); // 根据指定的位图文件名称,打开该位图文件if (File) // 如果位图文件存在{fclose(File); // 因为只是需要判断问题是否存在,而不需要对位图文件进行写操作,所以关闭位return auxDIBImageLoad(Filename); // 其实,只需要一个真正存在的位图文件的名称,实现加载位图文}return NULL; // 位图文件加载失败就返回NULL}上面实现加载位图的函数中,AUX_RGBImageRec是glaux.h中定义的类型,该类型的定义如下/*** RGB Image Structure*/typedef struct _AUX_RGBImageRec {GLint sizeX, sizeY;unsigned char *data;} AUX_RGBImageRec;首先,AUX_RGBImageRec类型是一个RGB图像结构类型。
该结构定义了三个成员:sizeX ——图像的宽度;sizeY ——图像的高度;data; ——图形所包含的数据,其实也就是该图形在内存中的像素数据的一个指针。
AUX_RGBImageRec类型的变量描述了一幅图像的特征。
上述函数中,调用了glaux.h库文件中的auxDIBImageLoad函数,其实它是一个宏,函数原型为auxRGBImageLoadW(LPCWSTR在该库文件中找到它的定义,如下所示:/* AUX_RGBImageRec * APIENTRY auxRGBImageLoad(LPCTSTR); */#ifdef UNICODE#define auxRGBImageLoad auxRGBImageLoadW#else#define auxRGBImageLoad auxRGBImageLoadA#endifAUX_RGBImageRec * APIENTRY auxRGBImageLoadA(LPCSTR);AUX_RGBImageRec * APIENTRY auxRGBImageLoadW(LPCWSTR);#ifdef UNICODE#define auxDIBImageLoad auxDIBImageLoadW#else#define auxDIBImageLoad auxDIBImageLoadA#endifAUX_RGBImageRec * APIENTRY auxDIBImageLoadA(LPCSTR);AUX_RGBImageRec * APIENTRY auxDIBImageLoadW(LPCWSTR);宏auxDIBImageLoad实现的功能就是:根据指定的位图名称,将该位图的信息加载到内存中,以便用来创建纹理并加载纹理用于创建并加载纹理的函数为LoadGLTextures,实现如下所示:int LoadGLTextures() // 根据加载的位图创建纹理{int Status=FALSE; // 指示纹理创建是否成功的标志AUX_RGBImageRec *TextureImage[6]; // 创建一个纹理图像数组,这里指定数组大小为memset(TextureImage,0,sizeof(void *)*6); // 初始化纹理图像数组,为其分配内存char *pictures[] = { // 创建一个位图名称数组,对应6幅位图"Data/No1.bmp","Data/No2.bmp","Data/No3.bmp","Data/No4.bmp","Data/No5.bmp","Data/No6.bmp"};for(int i=0; i<6; i++) // 遍历位图名称数组,根据位图名称分别生成{if (TextureImage[i]=LoadBMP(pictures[i])) // 加载位图i成功,修改状态标志变量Status为{Status=TRUE;glGenTextures(1, &texture[i]); // 为第i个位图创建纹理glBindTexture(GL_TEXTURE_2D, texture[i]); // 将生成的纹理的名称绑定到指定的纹理glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[i]->sizeX, TextureImage[i]->sizeY, 0, GL_RGB, GL_UNSIGNEDglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);}if (TextureImage[i]) // 释放位图数组占用的内存空间{if (TextureImage[i]->data){free(TextureImage[i]->data);}free(TextureImage[i]);}}return Status; // 创建纹理并加载,返回成功或者失败的标志Status}上述函数是创建和加载纹理的核心实现。
1、glGenTextures函数其中,调用了glGenTextures函数,查看MSDN可以看到,声明如下所示:void glGenTextures(GLsizei n,GLuint * textures);函数参数的含义:n ——生成的纹理的名称的个数;textures ——生成的纹理名称所存储位置的指针,也就是一个纹理数组的内存地址,或者说是数组首元函数被调用,会生成一系列纹理的名字,并存储到指定的数组中。
2、glBindTexture函数glBindTexture函数实现了将调用glGenTextures函数生成的纹理的名字绑定到对应的目标纹理上。
该函数void glBindTexture(GLenum target,GLuint texture);函数参数的含义:target ——纹理被绑定的目标,它只能取值GL_TEXTURE_1D或者GL_TEXTURE_2D;texture ——纹理的名称,并且,该纹理的名称在当前的应用中不能被再次使用。
3、glTexImage2D函数调用glTexImage2D函数,用来指定二维纹理图像。
该函数的声明如下所示:void glTexImage2D(GLenum target,GLint level,GLint components,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid *pixels);函数参数的含义:target ——指定目标纹理,必须为GL_TEXTURE_2D;level ——指定图像级别的编号,0表示基本图像,其它可以参考MSDN;components ——纹理中颜色组件的编号,可是是1或2或3或4;width ——纹理图像的宽度;height ——纹理图像的高度;border ——纹理图像的边框宽度,必须是0或1;format ——指定像素数据的格式,一共有9个取值:GL_COLOR_INDEX、GL_RED、GL_GREEN、GL_BLUE、GL_ALPHA、GL_REXT、GL_LUMINANCE、GL_LUMINANCE_ALPHA ,具体含义可以参考MSDN;type ——像素数据的数据类型,取值可以为GL_UNSIGNED_BYTE, GL_BYTE, GL_BITMAP, GL_UNSIGNED_SHORT, GL_SHORFLOAT;pixels ——内存中像素数据的指针。
4、glTexParameteri函数glTexParameteri函数或者glTexParameterf函数用来设置纹理参数,声明如下所示:void glTexParameterf(GLenum target,GLenum pname,GLfloat param);void glTexParameteri(GLenum target,GLenum pname,GLint param);函数参数的含义:target ——目标纹理,必须为GL_TEXTURE_1D或GL_TEXTURE_2D;pname ——用来设置纹理映射过程中像素映射的问题等,取值可以为:GL_TEXTURE_MIN_FILTER、GL_TEXTURE_MAG_FILTEWRAP_T,详细含义可以查看MSDN;param ——实际上就是pname的值,可以参考MSDN。
另外,该类函数还有两个:void glTexParameterfv(GLenum target,GLenum pname,const GLfloat *params);void glTexParameteriv(GLenum target,GLenum pname,const GLint *params);上述程序中调用如下:glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);功能就是实现线形滤波的功能,当纹理映射到图形表面以后,如果因为其它条件的设置导致纹理不能更好地显示的时候,进行过掉显示不正常的纹理像素。