在纹理贴图场景时,必须为每个顶点提供物体坐标和顶点坐标,经过变换之后,物体坐标决定了应该在屏幕上的那个地点渲染每个特定的顶点,纹理坐标决定了纹理图像中的那个纹理单元将分配给这个顶点
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;
}
#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;
}