0

我尝试将六张图片加载为纹理并绘制一个天空盒,但结果很奇怪,每张图片在其对应的灰色矩形上映射了三次。问题是什么?

#include <stdlib.h>
#include <stdio.h>

#include <glut.h>
#include <gl.h>
#include <glu.h>

#include <math.h>
#include <windows.h>

GLuint texture [6]; //the array for our texture

void init(void)
{

glClearColor (0.0, 0.0, 0.0, 1.0);
glShadeModel (GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glEnable(GL_TEXTURE_2D);
}

GLuint LoadTexture( const char * filename, int width, int height) {
GLuint texture;
unsigned char * data;
FILE* file;

file = fopen( filename, "r" );
if ( file == NULL ) return 0;
data = (unsigned char *)malloc( width * height * 3 );
fread( data, width * height * 3, 1, file );
fclose( file );



glGenTextures( 1, &texture ); 
glBindTexture( GL_TEXTURE_2D, texture ); 
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_DECAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_DECAL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // texture should tile
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE,data);    
free(data);
return texture; 
}     

void FreeTexture( GLuint texture )
{
glDeleteTextures( 1, &texture );
}

void skybox (void) {
float x = 0;
float y = 0;
float z = 0;
float width  = 100;
float height = 100;
float length = 100;
glPushAttrib(GL_ENABLE_BIT);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_BLEND);
// Bind the BACK texture of the sky map to the BACK side of the cube
glBindTexture(GL_TEXTURE_2D, texture[0]);
// Center the skybox
x = x - width  / 2;
y = y - height / 2;
z = z - length / 2;
glBegin(GL_QUADS);      
glTexCoord2f(1.0f, 0.0f); glVertex3f(x + width, y,  z);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x + width, y + height, z); 
glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y + height, z);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y,  z);
glEnd();
glBindTexture(GL_TEXTURE_2D, texture[1]);
glBegin(GL_QUADS);  
glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y,  z + length);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y + height, z + length);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y + height, z + length); 
glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y,  z + length);
glEnd();

glBindTexture(GL_TEXTURE_2D, texture[4]);
glBegin(GL_QUADS);      

glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y,  z);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y,  z + length);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y,  z + length); 
glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y,  z);
glEnd();
glBindTexture(GL_TEXTURE_2D, texture[5]);
glBegin(GL_QUADS);      
glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y + height, z);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x + width, y + height, z + length); 
glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y + height, z + length);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y + height, z);
glEnd();
glBindTexture(GL_TEXTURE_2D, texture[2]);
glBegin(GL_QUADS);      
glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y + height, z); 
glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y + height, z + length); 
glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y,  z + length);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y,  z);     

glEnd();
glBindTexture(GL_TEXTURE_2D, texture[3]);
glBegin(GL_QUADS);  
glTexCoord2f(0.0f, 0.0f); glVertex3f(x + width, y,  z);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x + width, y,  z + length);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x + width, y + height, z + length); 
glTexCoord2f(0.0f, 1.0f); glVertex3f(x + width, y + height, z);
glEnd();
//glBindTexture( GL_TEXTURE_CUBE_MAP, texture[0] ); //bind the texture
//glRotatef( angle, 1.0f, 1.0f, 1.0f );
//glutSolidSphere(2, 40, 40);
}

void display (void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLfloat light_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_position[] = { 0.0, 0.0, 30.0, 0.0 };


glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);

glLoadIdentity();
glPushMatrix();
gluLookAt (20.0, 20.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glPushMatrix();
texture[0] = LoadTexture( "back.bmp", 256, 256 ); //load the texture
texture[1] = LoadTexture( "front.bmp", 256, 256 ); //load the texture
texture[2] = LoadTexture( "left.bmp", 256, 256 ); //load the texture
texture[3] = LoadTexture( "right.bmp", 256, 256 ); //load the texture
texture[4] = LoadTexture( "bottom.bmp", 256, 256 ); //load the texture
texture[5] = LoadTexture( "top.bmp", 256, 256 ); //load the texture
glPopMatrix();
glPopMatrix();

//glEnable(GL_TEXTURE_GEN_S); //enable texture coordinate generation
//glEnable(GL_TEXTURE_GEN_T);
skybox();
for (int i = 0; i < 6; i++) {
  FreeTexture( texture[i] );
}
glutSwapBuffers();


}


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

}

int main (int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("A basic OpenGL Window");
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(reshape);

glutMainLoop();
}
4

3 回答 3

1

因此,您正在尝试加载 DIB/BMP 图像文件:

>     texture[0] = LoadTexture( "back.bmp", 256, 256 ); //load the texture
>                                    ^^^^
> 

读取文件内容

> GLuint LoadTexture( const char * filename, int width, int height) {
> GLuint texture; unsigned char * data; FILE* file;
> 
> file = fopen( filename, "r" );
> if ( file == NULL ) return 0;
> data = (unsigned char *)malloc( width * height * 3 );
> fread( data, width * height * 3, 1, file ); 

这对于 BMP 来说太短了,顺便说一句。

> fclose( file );

那么你的 DIB 解析器代码在哪里呢?

glGenTextures( 1, &texture ); 
glBindTexture( GL_TEXTURE_2D, texture ); 
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_DECAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_DECAL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // texture should tile
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE,data);    
free(data);
return texture; 
}

您只需将未解析的 DIB/BMP 文件内容传递给 OpenGL。您希望 OpenGL 对此做什么?OpenGL 不知道文件格式,更不知道如何处理 DIB 文件。你需要一个 DIB 解析器。

于 2012-11-25T19:55:27.947 回答
0

由于您正在加载 RGB 数据,请确保GL_UNPACK_ALIGNMENT设置为1

glPixelStorei(GL_UNPACK_ALIGNMENT, 1)​.
gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE,data);
于 2012-11-25T19:34:55.790 回答
0

我使用ImageMagick开放库轻松加载任何用于 OpenGL 的图像。

于 2013-07-18T18:11:06.870 回答