您的位置:首页 > 运维架构

OpenGL学习十七:纹理贴图

2014-01-21 15:40 369 查看
纹理贴图的步骤

1.创建纹理对象,并为它指定一个纹理,纹理包含1维,2维,3维。描述纹理的数据由1~4个元素组成,用于表示RGBA四元组。调整常量或者深度成分

glGenTextures(1, &texture[0]);

glBindTexture(GL_TEXTURE_2D, texture[0]);

2.确定纹理如何应用到每个像素上

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

3.启用纹理贴图功能

GL_TEXTURE_1D,GL_TEXTURE_2D,GL_TEXTURE_3D,GL_TEXTURE_CUBE_MAP如果同时启用了2维3维,则以后者为准,如果启用了GL_TEXTURE_CUBE_MAP,则其他被启用的纹理均不在生效

4.绘制场景,提供纹理坐标和几何图形坐标

指定纹理

void glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);定义一个2维纹理

GL_TEXTURE_1D

1维纹理
GL_TEXTURE_2D

2维纹理
GL_PROXY_TEXTURE_1D

1维代理纹理
GL_PROXY_TEXTURE_2D2维代理纹理
GL_TEXTURE_CUBE_MAP_POSITIVE_X

立方体X轴正方向纹理
targetGL_TEXTURE_CUBE_MAP_NEGATIVE_X

立方体X轴负方向纹理
GL_TEXTURE_CUBE_MAP_POSITIVE_Y

立方体Y轴正方向纹理
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y

立方体Y轴负方向纹理
GL_TEXTURE_CUBE_MAP_POSITIVE_Z

立方体Z轴正方向纹理
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z立方体Z轴负方向纹理
GL_PROXY_TEXTURE_CUBE_MAP立方体代理纹理
level 多重细节层时指定的分辨率,对于普通来说设置为0
 纹理内部数据格式,图像数据转换为纹理数据希望以哪种数据格式存储
GL_LUMINANCE只含有亮度成分
internaGL_LUMINANCE_ALPHA含有亮度和A成分
lformatGL_DEPTH_COMPONENT深度缓存
GL_RGBRGB颜色格式
GL_RGBARGBA颜色格式
height

width
 必须是2m+2b,其中m是一个非负的整数,b是border值,纹理最大值取决于OPENGL,但它最少是64*64
border 边框,0代表无,1代表有
format 图像数据颜色格式
typeGL_BYTE

GL_UNSIGNED_BYTE

GL_SHORT

GL_UNSIGHED_SHORT

……
图像数据数据类型
pixels 图像数据
void glCopyTexImage2D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);

void glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);

替换当前一幅现有的二维图像的全部或一块连续的区域

和修改原有的纹理对比,创建新纹理的开销更大一些,用新的信息修改一个现有纹理的全部或一部分常常比重头创建一个新纹理和合适

void glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);

使用帧缓冲区的图像数据代替现有的一幅二维纹理图像的一部分或全部

纹理代理

由于纹理资源有限,因此来判断是否有足够的纹理空间来存储是十分重要的,纹理代理作用就在于此

1.查询系统支持纹理图像最大宽度和最大高度

glGetIntegerv(GL_MAX_TEXTURE_SIZE,size);

GL_MAX_3D_TEXTURE_SIZE 3D纹理图像

GL_MAX_CUBE_TEXTURE_SIZE 立方体纹理图像

2.使用纹理代理查询纹理资源

2.1 设置要查询的内容

glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, 10240, 10240,

0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

2.2 查询纹理资源

void glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params);

pname:GL_TEXTURE_WIDTH

GL_TEXTURE_HEIGHT

GL_TEXTURE_DEPTH

GL_TEXTURE_BORDER

GL_TEXTURE_INTERNAL_FORMAT

GL_TEXTURE_RED_SIZE

GL_TEXTURE_BLUE_SIZE

GL_TEXTURE_GREED_SIZE

GL_TEXTURE_ALPHA_SIZE

GL_TEXTURE_LUMINANCE_SIZE

GL_TEXTURE_INTENSITY_SIZE

如果没有足够的资源容纳这个纹理代理,宽度,高度,边框宽度以及成分分辨率的纹理状态变量都设置为0

创建帧缓冲区的数据来定义纹理单元

一维纹理

void glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);

一维纹理可以看成是高度为1的2为纹理

三维纹理

void glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei depth ,GLint border, GLenum format, GLenum type, const GLvoid *pixels);

三维纹理可以看成由一层层的2纹理组成

#include "header.h"

#define checkImageWidth 64
#define checkImageHeight 64
#define subImageWidth 16
#define subImageHeight 16
static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
static GLubyte subImage[subImageHeight][subImageWidth][4];

static GLuint texName[2];
float quard=0.0f;
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;
}
}
for (i = 0; i < subImageHeight; i++) {
for (j = 0; j < subImageWidth; j++) {
c = ((((i&0x4)==0)^((j&0x4))==0))*255;
subImage[i][j][0] = (GLubyte) c;
subImage[i][j][1] = (GLubyte) 0;
subImage[i][j][2] = (GLubyte) 0;
subImage[i][j][3] = (GLubyte) 255;
}
}
}

void init(void)
{
GLuint size[2];
glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE,size);
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

makeCheckImages();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
/* glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, 1024, 1024,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_DEPTH,size);*/
glGenTextures(2, &texName[0]);
glBindTexture(GL_TEXTURE_2D, texName[0]);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
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_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,0,0,100,100,0);

}

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, texName[0]);
glRotatef(quard,1,0,0);

glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0) ;glVertex3f(0.0, 100, 0);
glTexCoord2f(0.0, 1.0);  glVertex3f(100, 100, 0);
glTexCoord2f(1.0, 1.0); glVertex3f(100, 0, 0);
glTexCoord2f(1.0, 0.0); glVertex3f(0, 0, 0);
glEnd();
glBindTexture(GL_TEXTURE_2D, texName[1]);
glColor3f(1,0,0);
glBegin(GL_QUADS);
glTexCoord2f(1.0, 0.0) ;glVertex3f(150, 100, 0);
glTexCoord2f(1.0, 1.0);  glVertex3f(250, 100, 0);
glTexCoord2f(0.0, 1.0); glVertex3f(250, 0, 0);
glTexCoord2f(0.0, 0.0); glVertex3f(150, 0, 0);
glEnd();

glFlush();
glDisable(GL_TEXTURE_2D);
}

void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glOrtho(-0, (GLdouble) w, -0, (GLdouble) h,-100,100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -3.6);
}

void keyboard (unsigned char key, int x, int y)
{
switch (key) {
case 's':
case 'S':
glBindTexture(GL_TEXTURE_2D, texName[0]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 12, 44, subImageWidth,
subImageHeight, GL_RGBA,
GL_UNSIGNED_BYTE, subImage);
glutPostRedisplay();
break;
case 'a':
case 'A':
glBindTexture(GL_TEXTURE_2D, texName[1]);
glCopyTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,0,0,100,100,0);
glutPostRedisplay();
break;
case 'B':

case 'b':
glBindTexture(GL_TEXTURE_2D, texName[1]);
glCopyTexSubImage2D(GL_TEXTURE_2D,0,10,10,20,20,120,120);
glutPostRedisplay();
break;
case 'r':
case 'R':
glBindTexture(GL_TEXTURE_2D, texName[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth,
checkImageHeight, 0, GL_RGBA,
GL_UNSIGNED_BYTE, checkImage);
glutPostRedisplay();
break;
case 27:
exit(0);
break;
default:
break;
}
}
void rotate()
{
quard+=0.1;
glutPostRedisplay();
}
void mouse(int button,int state,int x,int y)
{
switch(button)
{
case GLUT_LEFT_BUTTON:
if(GLUT_DOWN==state)
{
glutIdleFunc(rotate);
}else
{
//glutIdleFunc(0);
}
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(600, 480);
glutInitWindowPosition(100, 100);
glutCreateWindow("纹理贴图");
glewInit();
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMainLoop();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: