OpenGL 中的 MipMap 纹理
首先,我尝试读取 ppm 文件并将其用于我的纹理,但是我不确定这是否是我的问题所在(在读取文件中)。所以我硬编码了一个小的 4x4 图像(随机颜色)并使用它。我仍然无法让它工作。有人有任何见解吗?
data2、x2、y2 都是硬编码的图像属性。
glPushMatrix();
FILE *inFile;
char dump[3];
int max, k = 0;
inFile = fopen("mountains.ppm", "r");
int x;
int y;
fscanf(inFile, "%s", dump);
//printf("%s", dump);
fscanf(inFile, "%d %d", &x, &y);
fscanf(inFile, "%d", &max);
int arraySize = y*(3*x);
int data[arraySize];
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
fscanf(inFile, "%d", &data[k++]);
fscanf(inFile, "%d", &data[k++]);
fscanf(inFile, "%d", &data[k++]);
}
}
int data2[] = { 100 , 50, 50, 40, 30, 70, 70, 30, 40, 155, 50, 215,
50 , 40, 30, 60, 15, 77, 70, 70, 70, 70, 70, 70,
50 , 40, 30, 20, 110, 210, 20, 15, 47, 40, 40, 30,
15 , 40, 15, 40, 30, 40, 30, 20, 80, 80, 40, 20};
int x2 = 4;
int y2 = 4;
fclose(inFile);
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
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_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D,3,x2,y2,GL_RGB,GL_UNSIGNED_BYTE,data2);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
glBindTexture(GL_TEXTURE_2D,texture);
glTexCoord2d(0,0); glVertex3f(0,0.0,0);
glTexCoord2d(0,1); glVertex3f(0,0.0,80);
glTexCoord2d(1,1); glVertex3f(80,0.0,80);
glTexCoord2d(1,0); glVertex3f(80,0.0,0);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
First I tried to read in a ppm file and use that for my texture, however I wasn't sure if that is where my problem lies (in reading files). So I hardcoded a small 4x4 image (random colors) and used that. I still cannot get it to work. Does anyone have any insight?
data2, x2, y2 are all the hardcoded image properties.
glPushMatrix();
FILE *inFile;
char dump[3];
int max, k = 0;
inFile = fopen("mountains.ppm", "r");
int x;
int y;
fscanf(inFile, "%s", dump);
//printf("%s", dump);
fscanf(inFile, "%d %d", &x, &y);
fscanf(inFile, "%d", &max);
int arraySize = y*(3*x);
int data[arraySize];
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
fscanf(inFile, "%d", &data[k++]);
fscanf(inFile, "%d", &data[k++]);
fscanf(inFile, "%d", &data[k++]);
}
}
int data2[] = { 100 , 50, 50, 40, 30, 70, 70, 30, 40, 155, 50, 215,
50 , 40, 30, 60, 15, 77, 70, 70, 70, 70, 70, 70,
50 , 40, 30, 20, 110, 210, 20, 15, 47, 40, 40, 30,
15 , 40, 15, 40, 30, 40, 30, 20, 80, 80, 40, 20};
int x2 = 4;
int y2 = 4;
fclose(inFile);
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
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_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D,3,x2,y2,GL_RGB,GL_UNSIGNED_BYTE,data2);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
glBindTexture(GL_TEXTURE_2D,texture);
glTexCoord2d(0,0); glVertex3f(0,0.0,0);
glTexCoord2d(0,1); glVertex3f(0,0.0,80);
glTexCoord2d(1,1); glVertex3f(80,0.0,80);
glTexCoord2d(1,0); glVertex3f(80,0.0,0);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,纹理加载不应该每一帧都进行。您创建一次纹理,然后在需要使用该纹理进行渲染时使用它。因此,您需要将纹理加载代码从渲染逻辑中取出。
接下来:
data2
是一个int
的数组,一般大小为4个字节。但是你告诉 OpenGL 假设数据的每三个字节都是一个像素,第一个字节是红色,第二个字节是绿色,等等。但是你的红色值是 4 个字节。所以OpenGL无法正确获取数据。您想要的是将
data2
定义为GLubyte
数组,而不是int
数组。另外,永远不要对图像格式(第二个参数)使用数字。我不在乎规范是否说它是合法的;我不在乎。只需使用真实的格式即可。使用
GL_RGB8
而不是“3”。最后:
这几乎没有任何作用。如果没有
glBegin()/glEnd()
围绕它,您只是设置一些状态值。事实上,在glBegin()/glEnd() 对之外调用任何
glVertex*
命令都会导致未定义的行为。它肯定不会导致渲染(或者即使发生,也不会产生任何有用的结果)。顺便说一句,您会发现,如果您始终从工作代码开始,您的工作效率将会更高。例如,如果您想使用纹理,请从执行您所知道的操作开始:绘制无纹理的形状。一旦你做到了这一点,你就知道如果有什么东西坏了,那只是因为你的纹理代码。
First, texture loading is not something you should be doing every frame. You create the texture once, then use it when you need to render with that texture. So you need to get the texture loading code out of the rendering logic.
Next:
data2
is an array ofint
, which generally is 4 bytes in size. But you're telling OpenGL to assume that every three bytes of the data is a pixel, the first byte being red, the second being green, etc. But your red values are 4 bytes. So OpenGL doesn't get the data correctly.What you want is to define
data2
as aGLubyte
array, not anint
array.Also, never use numbers for the image format (the second parameter). I don't care that the specification says that it's legal; just use a real format. Use
GL_RGB8
instead of "3".Lastly:
This pretty much does nothing. Without the
glBegin()/glEnd()
around it, you're just setting some state values. Indeed, calling anyglVertex*
command outside of aglBegin()/glEnd()
pair results in undefined behavior. It certainly doesn't result in rendering (or if it does, it won't be anything useful).As an aside, you will find that you will be more productive if you always start with working code. For example, if you want to play with textures, start by doing what you know: draw an untextured shape. Once you have that working, you know that if something breaks, it will solely be because of your texturing code.