在纹理贴图场景时,必须为每个顶点提供物体坐标和顶点坐标,经过变换之后,物体坐标决定了应该在屏幕上的那个地点渲染每个特定的顶点,纹理坐标决定了纹理图像中的那个纹理单元将分配给这个顶点
void glTexCoord{1,2,3,4}{sifd} (Type coords);
纹理的放大与缩小
1.原始大小
glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f);
1.X轴重复(放大与缩小)
glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
glTexCoord2f(n*1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
glTexCoord2f(n*1.0f, 1.0f); glVertex2f( 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f);
当n=2时 当n=0.5时
2.Y轴重复(放大与缩小)
glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f);
glTexCoord2f(1.0f, n*1.0f); glVertex2f( 1.0f, 1.0f);
glTexCoord2f(0.0f, n*1.0f); glVertex2f(-1.0f, 1.0f);
当n=2时 当n=0.5时
3.纹理水平移动
glBegin(GL_QUADS);
glTexCoord2f(roll+0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f);
glTexCoord2f(roll+1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 0.0f);
glTexCoord2f(roll+1.0f,1.0f); glVertex3f( 1.0f, 1.0f, 0.0f);
glTexCoord2f(roll+0.0f,1.0f); glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd()
其中roll决定纹理水平移动的幅度,roll应该在0.1之间
4.纹理上下移动
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f+roll); glVertex3f(-1.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f+roll); glVertex3f( 1.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f,1.0f+roll); glVertex3f( 1.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f,1.0f+roll); glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd()
其中roll决定纹理上下移动的幅度,roll应该在0.1之间
纹理的重复与截取
当我们进行纹理放大时,纹理会以重复的形式进行平铺GL_REPEAT,但有时我们希望纹理坐标放大,可纹理并不进行重复的平铺,这就用到了截取GL_CLAMP
纹理重复:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
下图左边为2*2纹理的重复,右边为1*1纹理
第一个矩形
glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);
glTexCoord2f(0.0, 2.0); glVertex3f(-2.0, 1.0, 0.0);
glTexCoord2f(2.0, 2.0); glVertex3f(0.0, 1.0, 0.0);
glTexCoord2f(2.0, 0.0); glVertex3f(0.0, -1.0, 0.0);
第二个矩形
glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(3, 1.0, -0);
glTexCoord2f(1.0, 0.0); glVertex3f(3, -1.0, -0);
纹理截取
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
第一个矩形
glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);
glTexCoord2f(0.0, 2.0); glVertex3f(-2.0, 1.0, 0.0);
glTexCoord2f(2.0, 2.0); glVertex3f(0.0, 1.0, 0.0);
glTexCoord2f(2.0, 0.0); glVertex3f(0.0, -1.0, 0.0);
第二个矩形
glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(3, 1.0, -0);
glTexCoord2f(1.0, 0.0); glVertex3f(3, -1.0, -0);
左边的图为2*2纹理放大,右边为1*1纹理放大(原始大小)
glTexParameter*()函数的参数 |
参数(pname) | 值(param) |
GL_TEXTURE_WRAP_S 从左至右纹理环绕模式 GL_TEXTURE_WRAP_T 从下至上纹理环绕模式 GL_TEXTURE_WRAP_R 从里至外纹理环绕模式 |
GL_CLAMP:截取 GL_REPEAT:重复 GL_MIRRORED_REPEAT:镜像重复 GL_CLAMP_TO_EDGE:忽略边框截取 GL_CLAMP_TO_BORDER:代边框的截取 |
GL_TEXTURE_MAG_FILTER | GL_NEAREST或GL_LINEAR |
GL_TEXTURE_MIN_FILTER | GL_NEAREST 速度快,效果差 GL_LINEAR 计算量大。效果好 GL_NEAREST_MIPMAP_NEAREST 速度快,效果差 GL_LINEAR_MIPMAP_NEAREST GL_NEAREST_MIPMAP_LINEAR GL_LINEAR_MIPMAP_LINEAR 计算量大。效果好 |
GL_TEXTURE_BORDER_COLOR | |
GL_TEXTURE_PRIORITY | (0,1)纹理优先级 |
GL_TEXTURE_BASE_LEVEL | 浮点值 |
GL_TEXTURE_MAX_LEVEL | 浮点值 |
GL_TEXTURE_MIN_LOD | 浮点值 |
GL_TEXTURE_MAX_LEVEL | 浮点值 |
GL_TEXTURE_LOD_BIAS | |
GL_TEXTURE_COMPARE_MODE 纹理比较模式 |
GL_COMPARE_R_TO_TEXTURE 深度比较 |
GL_DEPTH_TEXTURE_MODE | GL_RED:R GL_LUMINANCE:亮度 GL_INSENSITY GL_ALPHA:A |
GL_TEXTURE_COMPARE_FUNC 纹理比较方式 |
GL_LEQUAL,GL_GEQUAL,GL_LESS,GL_GREATER, GL_EQUAL,GL_NOTEQUAL,GL_ALWAYS,GL_NEVER |
GL_GENERATE_MIAMAP 自动生成多重细节层 |
GL_TRUE,GL_FALSE
|
纹理坐标DEMO
#include "header.h" GLuint texture[1]; float rollx=0.0f; float rolly=0.0f; bool isX=false; bool isY=false; float xdouble=1.0f; float ydouble=1.0f; AUX_RGBImageRec *LoadBMP(char *Filename) { FILE *File=NULL; if (!Filename) { return NULL; } File=fopen(Filename,"r"); if (File) { fclose(File); return auxDIBImageLoad(Filename); } return NULL; } int LoadGLTextures() { int Status=FALSE; AUX_RGBImageRec *TextureImage[1]; memset(TextureImage,0,sizeof(void *)*1); if (TextureImage[0]=LoadBMP("Data/NeHe.bmp")) { Status=TRUE; glGenTextures(1, &texture[0]); // Typical Texture Generation Using Data From The Bitmap glBindTexture(GL_TEXTURE_2D, texture[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); } if (TextureImage[0]) { if (TextureImage[0]->data) { free(TextureImage[0]->data); } free(TextureImage[0]); } return Status; } GLvoid ReSizeGLScene(GLsizei width, GLsizei height) { if (height==0) { height=1; } glViewport(0,0,width,height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Calculate The Aspect Ratio Of The Window gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int InitGL(GLvoid) { if (!LoadGLTextures()) { return FALSE; } glEnable(GL_TEXTURE_2D); glShadeModel(GL_SMOOTH); glClearColor(0.0f, 0.0f, 0.0f, 0.5f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); return TRUE; } void DrawGLScene(GLvoid) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0f,0.0f,-5.0f); glBindTexture(GL_TEXTURE_2D, texture[0]); glBegin(GL_QUADS); // Front Face glTexCoord2f(0.0f+rollx, 0.0f+rolly); glVertex2f(-1.0f, -1.0f); glTexCoord2f(xdouble*1.0f+rollx, 0.0f+rolly); glVertex2f( 1.0f, -1.0f); glTexCoord2f(xdouble*1.0f+rollx,ydouble*1.0f+rolly); glVertex2f( 1.0f, 1.0f); glTexCoord2f(0.0f+rollx, ydouble*1.0f+rolly); glVertex2f(-1.0f, 1.0f); glEnd(); glFlush(); } void scroll() { if(isX) { rollx+=0.002f; if (rollx>1.0f) { rollx-=1.0f; } } if (isY) { rolly+=0.002f; if (rolly>1.0f) { rolly-=1.0f; } } glutPostRedisplay(); } void keyboard(unsigned char key,int x,int y) { switch (key) { case 'x': isX=true; isY=false; glutIdleFunc(scroll); break; case 'y': isY=true; isX=false; glutIdleFunc(scroll); break; case 'X': xdouble=xdouble+0.5f; break; case 'Y': isY=true; ydouble=ydouble+0.5f; break; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(640,480); glutCreateWindow("纹理坐标"); glutReshapeFunc(ReSizeGLScene); glutDisplayFunc(DrawGLScene); glutKeyboardFunc(keyboard); InitGL(); glutMainLoop(); return 0; }
纹理截取DEMO
#include "header.h" #define checkImageWidth 64 #define checkImageHeight 64 static GLubyte checkImage[checkImageHeight][checkImageWidth][4]; static GLubyte otherImage[checkImageHeight][checkImageWidth][4]; static GLuint texName[2]; void makeCheckImages(void) { int i, j, c; for (i = 0; i < checkImageHeight; i++) { for (j = 0; j < checkImageWidth; j++) { c = ((((i&0x8)==0)^((j&0x8))==0))*255; checkImage[i][j][0] = (GLubyte) c; checkImage[i][j][1] = (GLubyte) c; checkImage[i][j][2] = (GLubyte) c; checkImage[i][j][3] = (GLubyte) 255; c = ((((i&0x10)==0)^((j&0x10))==0))*255; otherImage[i][j][0] = (GLubyte) c; otherImage[i][j][1] = (GLubyte) 0; otherImage[i][j][2] = (GLubyte) 0; otherImage[i][j][3] = (GLubyte) 255; } } } void init(void) { glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel(GL_FLAT); glEnable(GL_DEPTH_TEST); makeCheckImages(); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures(2, texName); glBindTexture(GL_TEXTURE_2D, texName[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 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_RGBA, checkImageWidth, checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage); glBindTexture(GL_TEXTURE_2D, texName[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, otherImage); glEnable(GL_TEXTURE_2D); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, texName[0]); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0); glTexCoord2f(0.0, 4.0); glVertex3f(-2.0, 1.0, 0.0); glTexCoord2f(4.0, 4.0); glVertex3f(0.0, 1.0, 0.0); glTexCoord2f(4.0, 0.0); glVertex3f(0.0, -1.0, 0.0); glEnd(); glBindTexture(GL_TEXTURE_2D, texName[1]); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(2.5, -1.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(2.5, 1.0, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(0.5, 1.0, -0); glTexCoord2f(1.0, 0.0); glVertex3f(0.5, -1.0, -0); glEnd(); glFlush(); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -5); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(250, 250); glutInitWindowPosition(100, 100); glutCreateWindow("纹理截取"); init(); glutReshapeFunc(reshape); glutDisplayFunc(display); glutKeyboardFunc (keyboard); glutMainLoop(); return 0; }
相关推荐
1. **多纹理贴图**:立方体的每个面都可以独立加载和显示不同的纹理图像,展示了纹理坐标和纹理映射的基本原理。 2. **着色器编程**:使用了顶点着色器和片元着色器来实现立方体的立体效果和纹理贴图。 3. **变换...
解释一下标题:复合空间变换指地球围绕太阳转,而月球围绕地球转的...本代码结构简单,代码量少,适合新手快速学习原理,以及上手。 如果出现编译后纹理无法加载,请将代码包内的图片纹理文件夹拷贝至程序同一目录。
基于Win32+OpenGL的一个三维地形模拟小demo,一个课程作业,可以用三维坐标点生成三角网,设置光照并纹理贴图,包内有exe版本可直接运行,在VS2017下可编译通过,利于学习的好资源。
计算各顶点对应的纹理坐标 texcoord 计算各顶点所对应的顶点法向量 Normal 计算出需要绘制的各顶点的顺序 order 绘制飘动效果 根据正弦曲线,计算出各顶点所对应的深度值 zDepth 计算出正弦曲线的波动 坐标点...
4. 生成纹理坐标时比较简单,再生成顶点坐标的同时就可以生成,但是实现后遇到问题,问题贴图是上下颠倒的,所以需要与顶点对应的纹理坐标需要上下转换一下,虽然感觉比较麻烦,但是还是比较容易实现的 5. 计算各...
如果你对计算机图形学还不太了解,那么请先从《OpenGL编程指南》一书入手学习,并同时参考下面这些书: ?James D. Foley、 Andries van Dam、Steven K. Feiner和John F. Hughes著,《计算机图形学:原理及应用》...
把渲染得图像作为纹理提取出来,在利用OpenGL本身自带的纹理过滤,就能实现这种效果,不信,你试试。 37.卡通映射 什么是卡通了,一个轮廓加上少量的几种颜色。使用一维纹理映射,你也可以实现这种效果。 ...
一、第一个OPENGL程序...................................................................................................................4 1.1、OPENGL的优点.................................................
以可视化的方式,让你轻松掌握OpenGL中透视坐标变换,以及纹理坐标变换的基本原理,以及雾的掌握。绝对物超所值的资源
第6章 为伊消得人憔悴——纹理映射本章主要介绍了纹理的基础知识,以及纹理的不同拉伸方式和纹理过滤高级技术,从绘制三角形开始到绘制地月系,可能会经历很长时间,但是这对以后的学习是有帮助的 第7章 海阔凭...
把渲染得图像作为纹理提取出来,在利用OpenGL本身自带的纹理过滤,就能实现这种效果,不信,你试试。 37.卡通映射 什么是卡通了,一个轮廓加上少量的几种颜色。使用一维纹理映射,你也可以实现这种效果。 38.从...
计算各顶点对应的纹理坐标 texcoord 计算各顶点所对应的顶点法向量 Normal 计算出需要绘制的各顶点的顺序 order 绘制飘动效果 根据正弦曲线,计算出各顶点所对应的深度值 zDepth 计算出正弦曲线的波动 坐标点...
通过这一章,使读者对OpenGL有初步的概念和了解,对于纹理、显示列表等更深入的编程,我们将通过后续章节进行更详细的讲解和学习。 第3章 主要对Oracle数据库及其特点进行简要的介绍和说明。以Oracle 9i为例,...
通过这一章,使读者对OpenGL有初步的概念和了解,对于纹理、显示列表等更深入的编程,我们将通过后续章节进行更详细的讲解和学习。 第3章 主要对Oracle数据库及其特点进行简要的介绍和说明。以Oracle 9i为例,...
此外,我们还说明了在顶点上进行坐标变换的方法,并简单介绍了OpenGL ES 3.0管线的光栅化阶段。 第8章——顶点着色器 我们所介绍的管线的下一部分是顶点着色器。第8章概述了顶点着色器如何融入管线以及OpenGL ES...
通过这一章,使读者对OpenGL有初步的概念和了解,对于纹理、显示列表等更深入的编程,我们将通过后续章节进行更详细的讲解和学习。 第3章 主要对Oracle数据库及其特点进行简要的介绍和说明。以Oracle 9i为例,...
如果你对计算机图形学还不太了解,那么请先从《OpenGL编程指南》一书入手学习,并同时参考下面这些书: ?James D. Foley、 Andries van Dam、Steven K. Feiner和John F. Hughes著,《计算机图形学:原理及应用》...
通过这一章,使读者对OpenGL有初步的概念和了解,对于纹理、显示列表等更深入的编程,我们将通过后续章节进行更详细的讲解和学习。 第3章 主要对Oracle数据库及其特点进行简要的介绍和说明。以Oracle 9i为例,...
通过这一章,使读者对OpenGL有初步的概念和了解,对于纹理、显示列表等更深入的编程,我们将通过后续章节进行更详细的讲解和学习。 第3章 主要对Oracle数据库及其特点进行简要的介绍和说明。以Oracle 9i为例,...
通过这一章,使读者对OpenGL有初步的概念和了解,对于纹理、显示列表等更深入的编程,我们将通过后续章节进行更详细的讲解和学习。 第3章 主要对Oracle数据库及其特点进行简要的介绍和说明。以Oracle 9i为例,...