在纹理贴图场景时,必须为每个顶点提供物体坐标和顶点坐标,经过变换之后,物体坐标决定了应该在屏幕上的那个地点渲染每个特定的顶点,纹理坐标决定了纹理图像中的那个纹理单元将分配给这个顶点
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; }
相关推荐
在着色器中,你可以使用`gl_TexCoord`(旧版OpenGL)或`in vec2 texCoord`(OpenGL 3.x及更高版本)来访问这些纹理坐标,并使用`texture2D`函数采样纹理。 ```glsl vec4 color = texture2D(u_TextureSampler, v_...
总之,易语言OPENGL应用中纹理贴图的方法涉及纹理坐标、纹理加载、纹理参数设置以及在渲染过程中应用纹理等多个环节。通过研究和实践这些源码,你将能够掌握OpenGL纹理贴图的核心技术,并能应用于自己的项目中。
对于初学者,理解纹理坐标系、纹理坐标的范围以及如何正确设置纹理参数都是必要的。 在提供的“OpenGL.txt”文件中,可能包含了上述过程的代码示例,包括纹理加载、创建、绑定和应用的详细步骤。通过研究和理解这段...
1. **纹理坐标**:每个顶点都有对应的纹理坐标,这些坐标告诉OpenGL ES如何将纹理映射到几何体表面。通常使用UV坐标系,U和V分别对应纹理的水平和垂直方向。 2. **纹理单元**:OpenGL ES支持同时使用多个纹理,每个...
OpenGL提供了多种纹理坐标系统和纹理过滤方法。纹理的加载和应用主要通过`glTexImage2D`和`glTexSubImage2D`函数完成。`glTexImage2D`用于加载整个纹理,而`glTexSubImage2D`则可以在不重新创建纹理的情况下更新纹理...
在OpenGL ES中,可以使用`glActiveTexture`函数切换纹理单元,`glBindTexture`绑定纹理,然后在着色器中通过纹理坐标和纹理单元索引来采样多个纹理。GLSL着色器中的`texture2D`函数(或在OpenGL ES 3.x中是`texture`...
6. **纹理坐标设置**:在3D模型的顶点数据中添加纹理坐标,这些坐标告诉OpenGL如何将纹理应用到几何体上。 7. **启用纹理坐标数组**:通过`glEnableClientState`开启纹理坐标数组。 8. **绘制几何体**:在绘制时,...
4. **启用纹理坐标数组**:通过`glEnableVertexAttribArray()`启用纹理坐标数组,确保OpenGL知道如何将纹理应用到绘制的几何体上。 5. **绑定纹理**:在绘制前,使用`glBindTexture()`将之前加载的纹理ID绑定到纹理...
1. **纹理坐标**: 在3D模型上,每个顶点都有对应的纹理坐标,这些坐标映射到纹理图像的像素上。纹理坐标系通常为(0,0)到(1,1),对应纹理图像的左下角到右上角。 2. **纹理单元**: OpenGL允许同时使用多个纹理,通过...
为了将纹理应用到图形上,需要定义纹理坐标,这通常与顶点坐标一起指定,然后使用glEnable(GL_TEXTURE_2D)启用纹理,glBindTexture绑定纹理,最后在顶点着色器中使用纹理坐标和纹理单元来采样纹理。 在...
2. **纹理坐标**:与3D模型的顶点坐标不同,纹理坐标通常在0到1之间,用于指定模型表面应该应用纹理的哪些部分。UV坐标系中,U对应水平方向,V对应垂直方向。 3. **加载纹理**:你需要从文件(如.png或.jpg)加载...
6. 应用纹理:在绘制几何体时,通过`glBindTexture()`绑定相应的纹理ID,然后在顶点着色器中设置纹理坐标,使得每个像素对应于纹理上的特定位置。 7. 渲染:最后,调用`glDrawArrays()`或`glDrawElements()`等函数...
通过指定每个顶点的纹理坐标(UV坐标),OpenGL可以计算出每个像素如何从纹理中采样。这可以实现不同的效果,如平铺、拉伸、镜像等。映射方法有几种,包括最简单的纹理坐标直接映射、纹理坐标的缩放和偏移、以及更...
OpenGL支持多种纹理格式,并提供了纹理坐标映射的机制,将2D图像(纹理)贴合到3D物体表面。动态光照纹理则进一步结合光照和纹理,使得物体表面的光照效果随纹理的变化而变化,例如在不同的光照条件下反射不同颜色或...
OpenGL提供了纹理对象和纹理坐标系统来支持这一功能。 1. **创建纹理对象**: 在OpenGL中,我们首先需要创建一个纹理对象,使用`glGenTextures()`函数生成纹理ID。例如: ```cpp GLuint textureID; ...
在OpenGL中,我们通常使用顶点、颜色、纹理坐标等数据来描述一个几何形状。纹理是存储像素数据的多边形,可以看作是二维图像,用于增加几何体的视觉细节。 在贴纹理前,我们需要准备纹理图像文件,如.jpg、.png或....
在OpenGL中,通过纹理坐标和纹理单元来完成这个过程。以下将详细介绍该Demo所涉及的关键概念和技术。 1. **纹理对象**:在OpenGL中,纹理对象是存储图像数据的容器,可以通过`glGenTextures()`函数生成,然后使用`...
总的来说,"opengl纹理贴图例子"是一个很好的学习资源,它涵盖了纹理映射的基本概念,包括纹理对象的创建、纹理数据的加载以及纹理坐标的应用。通过理解和实践这个例子,初学者能够对OpenGL中的纹理映射有一个清晰的...
6. 应用纹理:在绘制模型时,通过设置顶点属性数组和纹理坐标,将纹理应用到几何体上。 镂空效果在OpenGL中通常是通过混合模式和深度测试来实现的。深度测试确保了场景中离观察者更近的对象会遮挡更远的物体,而...
1. **纹理坐标**:每个3D模型的顶点都会有一个对应的纹理坐标,用于确定纹理应该如何覆盖模型表面。通常使用UV坐标系,U和V轴分别对应纹理的水平和垂直方向。 2. **纹理加载**:在OpenGL中,我们需要加载外部图像...