我正在尝试在opengl中绘制一个简单的纹理。我做了一个简单的类Texture:
class Texture{
public:
unsigned int id;
unsigned char image[256*256*3];
int level;
int border;
int width;
int height;
Texture (int level =0, int border = 0) : level(level), border(border) {
glGenTextures(1, &id);
width = 256, height = 256;
glTexImage2D(GL_TEXTURE_2D, level, GL_RGB, width, height, border, GL_RGB, GL_UNSIGNED_BYTE, &image[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
for (int i= 0; i<width*height*3; i+=3){
image[i]=1;//i%255;
image[i+1] =1;// 255-i%255;
image[i+2] =1;// i%128;
}
}
void useIt(){
glBindTexture( GL_TEXTURE_2D, id );
}
};
它创建一个unsigned char数组并用一些随机数据填充它。我试图用这种方式:
glEnable(GL_TEXTURE_2D);
texture->useIt();
glBegin(GL_TRIANGLES);
glNormal3d(0, 1, 0);
glTexCoord2d(0.0,0.0);
glVertex3f(width/-2.f,height/2.f,depth/2.f);
glTexCoord2d(1.0,1.0);
glVertex3f(width/2.f,height/2.f,depth/2.f);
glTexCoord2d(1.0,0.0);
glVertex3f(width/2.f,height/2.f,depth/-2.f);
glTexCoord2d(0.0,0.0);
glVertex3f(width/-2.f,height/2.f,depth/2.f);
glTexCoord2d(1.0,1.0);
glVertex3f(width/2.f,height/2.f,depth/-2.f);
glTexCoord2d(0.0,1.0);
glVertex3f(width/-2.f,height/2.f,depth/-2.f);
glEnd();
glDisable(GL_TEXTURE_2D);
它绘制平面,但具有纹理(使用以前使用的材质绘制)。我做错了什么?
答案 0 :(得分:1)
glBindTexture
操作之前,Texture
构造函数中需要 glTex*
。
在glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
之前,您可能还需要:glTexImage2D
,因为行内存地址不在4字节边界上。
BTW ... 您需要先设置image
数据,然后再通过glTexImage2D
上传。现在,您只是使用未初始化的数据设置纹理。此外,设置RGB字节数据的循环只是给你非常接近黑色的值,全部:(1, 1, 1)
。
答案 1 :(得分:1)
您的代码可能存在三个问题。 Brett Hale已经告诉过你,在使用glTexImage将数据上传到它之前你需要绑定一个纹理对象。
glTexImage创建您提供给它的数据的副本(这与glVertex ...指针函数不同,它只将指针或偏移量带入缓冲区对象)。但是,在将的内容复制到纹理后,您将使用数据填充图像数组。您也可以在将数据复制到纹理后安全地删除图像数组。
最后但并非最不重要:这些操作可在构造函数中找到。如果在创建OpenGL上下文之前初始化的作用域中有纹理类实例,则根本不会发生任何事情,因为没有OpenGL上下文。因此要么确保,只有在OpenGL上下文可用之后才创建纹理对象,或者将纹理创建和上传代码放入一个单独的方法中,一旦OpenGL上下文可用就调用该方法。