2012-09-25 43 views
2

我一直在尝试使用SDL_image和OpenGL将纹理加载到多维数据集。出于某种原因,当我尝试使用纹理时,整个窗口仍为空白。通过注释我的纹理初始化调用,窗口呈现为它应该,除了一个白色的纹理。当我对glEnable(GL_TEXTURE_2D)的调用被注释掉时也是如此。我已经尝试了几个小时来解决这个问题,并且大部分人都在网上查找是否有人提出了解决方案,但没有任何我尝试过的。我只在下面发布了我的代码部分,如果需要更多,请告诉我。SDL 3D OpenGL:立方体上的纹理会产生空白屏幕

的OpenGL初始化(对于glEnable(GL_TEXTURE_2D的顺序)可以是不正确的):

//Configures OpenGL for 3d rendering 
//Needs to know the window height and width 
void setUpOpenGL(int width, int height) 
{ 
//Enable depth testing, necessary for 3d worlds 
glEnable(GL_DEPTH_TEST); 
glEnable(GL_TEXTURE_2D); 

//Set the background colour to black 
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
//Set the clear depth at 1m? 
glClearDepth(1.0f); 

//Configure the viewport, giving height and width 
glViewport(0, 0, width, height); 

//Clear the colour buffer 
glClear(GL_COLOR_BUFFER_BIT); 

//Initiate OpenGL for projection drawing 
glMatrixMode(GL_PROJECTION); 
//Load identity, purpose still unknown 
glLoadIdentity(); 

//Initiate viewport as perspective, give the field of view, aspect ratio (width/height), minimum distance and maximum distance 
gluPerspective(45.0f, (float)width/(float)height, 0.01f, 500.0f); 

//Initiate OpenGL for model drawing, preparation for frame rendering 
glMatrixMode(GL_MODELVIEW); 
//Load identity again (identity matrix?) 
glLoadIdentity(); 

//Set the shading model to smooth. Other options feasable, but don't look as good 
glShadeModel(GL_SMOOTH); 
//For whatever reason, we need to state how to calculate depth. Grouped under "Alpha Function" 
glDepthFunc(GL_LEQUAL); 

//Calculate perspective as "nicest"; "don't care" and "fastest" are other options 
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 

//Finished configuring OpenGL 
return; 
} 

这里我loadTexture函数(的errorCode保持为0通过整个功能,并且没有打印到stderr):

//Function to load textures from file. Needs to know the filename/relative location. 
//Load textures from file 
int loadTexture(char *filename) 
{ 
GLuint returnValue = -1; 
SDL_Surface *image; 
void *raw; 
int width, height, bpp; 
Uint8 *srcPixel, *dstPixel; 
Uint32 truePixel; 
GLenum errorCode; 

image = IMG_Load(filename); 

if(!image) 
{ 
    fprintf(stderr, "Warning: Error loading image %s: %s\n", filename, IMG_GetError()); 
    return -2; 
} 

if(image->format->BytesPerPixel < 2) 
{ 
    fprintf(stderr, "Warning: %s is a bad image, not true colour\n", filename); 
    return -3; 
} 

width = image->w; 
height = image->h; 

raw = (void *)malloc(width * height * 4); 
dstPixel = (Uint8 *)raw; 

SDL_LockSurface(image); 

bpp = image->format->BytesPerPixel; 

for(int i = height - 1; i >= 0; i--) 
{ 
    for(int j = 0; j < width; j++) 
    { 
     srcPixel = (Uint8 *)image->pixels + i * image->pitch + j * bpp; 

     switch(bpp) 
     { 
     case 1: 
      truePixel = *srcPixel; 
      break; 
     case 2: 
      truePixel = *(Uint16 *)srcPixel; 
      break; 
     case 3: 
      if(SDL_BYTEORDER == SDL_BIG_ENDIAN) 
       truePixel = srcPixel[0] << 16 | srcPixel[1] << 8 | srcPixel[2]; 
      else 
       truePixel = srcPixel[0] | srcPixel[1] << 8 | srcPixel[2] << 16; 
      break; 
     case 4: 
      truePixel = *(Uint32 *)srcPixel; 
      break; 
     default: 
      fprintf(stderr, "Warning: image BPP of %d in image %s unuseable\n", bpp, filename); 
      SDL_UnlockSurface(image); 
      SDL_FreeSurface(image); 
      free(raw); 
      return -4; 
     } 

     SDL_GetRGBA(truePixel, image->format, &(dstPixel[0]), &(dstPixel[1]), &(dstPixel[2]), &(dstPixel[3])); 
     dstPixel++; 
     dstPixel++; 
     dstPixel++; 
     dstPixel++; 
    } 
} 

SDL_UnlockSurface(image); 
SDL_FreeSurface(image); 

while(glGetError()); 

glGenTextures(1, &returnValue); 
glBindTexture(GL_TEXTURE_2D, returnValue); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR/*_MIPMAP_LINEAR*/); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
//glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); 

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 

glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (Uint8 *)raw); 

errorCode = glGetError(); 
if(errorCode) 
{ 
    if(errorCode == GL_OUT_OF_MEMORY) 
     fprintf(stderr, "Warning: Texture memory full while binding texture from image %s\n", filename); 
    else 
     fprintf(stderr, "OpenGL error while creating texture: %d", (int)errorCode); 

    glDeleteTextures(1, &returnValue); 
    free(raw); 
    return -5; 
} 

//gluBuild2DMipmaps(GL_TEXTURE_2D, 4, width, height, GL_RGBA, GL_UNSIGNED_BYTE, (Uint8 *)raw); 

errorCode = glGetError(); 
if(errorCode) 
{ 
    if(errorCode == GL_OUT_OF_MEMORY) 
     fprintf(stderr, "Warning: Texture memory full while building texture from image %s\n", filename); 
    else 
     fprintf(stderr, "OpenGL error while creating texture: %s", (int)errorCode); 

    glDeleteTextures(1, &returnValue); 
    free(raw); 
    return -6; 
} 

return returnValue; 
} 

最后,我的实际渲染代码。请注意,loadTexture函数的返回值被复制到纹理数组的所有元素中(右,左,上,下,前,后(枚举))。

void cube::render(void) 
{ 
float xMinOffset, xMaxOffset, yMinOffset, yMaxOffset, zMinOffset, zMaxOffset; 
//getoffset(xMinOffset, xMaxOffset, yMinOffset, yMaxOffset, zMinOffset, zMaxOffset); 

xMinOffset = yMinOffset = zMinOffset = 0.0f; 
xMaxOffset = yMaxOffset = zMaxOffset = 1.0f; 

//Positive x, or right 
glBegin(GL_QUADS); 
{ 
    glColor3f(1.0f, 1.0f, 1.0f); 
    glNormal3f(1.0f, 0.0f, 0.0f); 
    glBindTexture(GL_TEXTURE_2D, texture[right]); 

    glTexCoord2f(0.0f, 1.0f); 
    glVertex3f(xMaxOffset, yMinOffset, zMinOffset); 
    glTexCoord2f(1.0f, 1.0f); 
    glVertex3f(xMaxOffset, yMinOffset, zMaxOffset); 
    glTexCoord2f(1.0f, 0.0f); 
    glVertex3f(xMaxOffset, yMaxOffset, zMaxOffset); 
    glTexCoord2f(0.0f, 0.0f); 
    glVertex3f(xMaxOffset, yMaxOffset, zMinOffset); 
} 
glEnd(); 

//Negative x, or left 
glBegin(GL_QUADS); 
{ 
    glColor3f(1.0f, 1.0f, 1.0f); 
    glNormal3f(-1.0f, 0.0f, 0.0f); 
    glBindTexture(GL_TEXTURE_2D, texture[left]); 

    glTexCoord2f(0.0f, 1.0f); 
    glVertex3f(xMinOffset, yMinOffset, zMinOffset); 
    glTexCoord2f(1.0f, 1.0f); 
    glVertex3f(xMinOffset, yMinOffset, zMaxOffset); 
    glTexCoord2f(1.0f, 0.0f); 
    glVertex3f(xMinOffset, yMaxOffset, zMaxOffset); 
    glTexCoord2f(0.0f, 0.0f); 
    glVertex3f(xMinOffset, yMaxOffset, zMinOffset); 
} 
glEnd(); 

//Positive y, or top 
glBegin(GL_QUADS); 
{ 
    glColor3f(1.0f, 1.0f, 1.0f); 
    glNormal3f(0.0f, 1.0f, 0.0f); 
    glBindTexture(GL_TEXTURE_2D, texture[top]); 

    glTexCoord2f(1.0f, 1.0f); 
    glVertex3f(xMinOffset, yMaxOffset, zMinOffset); 
    glTexCoord2f(1.0f, 0.0f); 
    glVertex3f(xMinOffset, yMaxOffset, zMaxOffset); 
    glTexCoord2f(0.0f, 0.0f); 
    glVertex3f(xMaxOffset, yMaxOffset, zMaxOffset); 
    glTexCoord2f(0.0f, 1.0f); 
    glVertex3f(xMaxOffset, yMaxOffset, zMinOffset); 
} 
glEnd(); 

//Negative y, or bottom 
glBegin(GL_QUADS); 
{ 
    glColor3f(1.0f, 1.0f, 1.0f); 
    glNormal3f(0.0f, -1.0f, 0.0f); 
    glBindTexture(GL_TEXTURE_2D, texture[bottom]); 

    glTexCoord2f(1.0f, 1.0f); 
    glVertex3f(xMinOffset, yMinOffset, zMinOffset); 
    glTexCoord2f(1.0f, 0.0f); 
    glVertex3f(xMinOffset, yMinOffset, zMaxOffset); 
    glTexCoord2f(0.0f, 0.0f); 
    glVertex3f(xMaxOffset, yMinOffset, zMaxOffset); 
    glTexCoord2f(0.0f, 1.0f); 
    glVertex3f(xMaxOffset, yMinOffset, zMinOffset); 
} 
glEnd(); 

//Positive z, or front 
glBegin(GL_QUADS); 
{ 
    glColor3f(1.0f, 1.0f, 1.0f); 
    glNormal3f(0.0f, 0.0f, 1.0f); 
    glBindTexture(GL_TEXTURE_2D, texture[front]); 

    glTexCoord2f(0.0f, 1.0f); 
    glVertex3f(xMinOffset, yMinOffset, zMaxOffset); 
    glTexCoord2f(0.0f, 0.0f); 
    glVertex3f(xMinOffset, yMaxOffset, zMaxOffset); 
    glTexCoord2f(1.0f, 0.0f); 
    glVertex3f(xMaxOffset, yMaxOffset, zMaxOffset); 
    glTexCoord2f(1.0f, 1.0f); 
    glVertex3f(xMaxOffset, yMinOffset, zMaxOffset); 
} 
glEnd(); 

//Negative z, or back 
glBegin(GL_QUADS); 
{ 
    glColor3f(1.0f, 1.0f, 1.0f); 
    glNormal3f(0.0f, 0.0f, -1.0f); 
    glBindTexture(GL_TEXTURE_2D, texture[back]); 

    glTexCoord2f(1.0f, 1.0f); 
    glVertex3f(xMinOffset, yMinOffset, zMinOffset); 
    glTexCoord2f(1.0f, 0.0f); 
    glVertex3f(xMinOffset, yMaxOffset, zMinOffset); 
    glTexCoord2f(0.0f, 0.0f); 
    glVertex3f(xMaxOffset, yMaxOffset, zMinOffset); 
    glTexCoord2f(0.0f, 1.0f); 
    glVertex3f(xMaxOffset, yMinOffset, zMinOffset); 
} 
glEnd(); 
} 

这里的渲染功能,以及一些其他绘图相关的功能。请注意,initDisplayLists()在初始化过程中被调用。

void redraw(void) 
{ 
//Still has the data from the previous frame 
//Clear the colour and depth buffers before rendering 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
//Load identity, purpose unknown 
glLoadIdentity(); 

//Draw horizontal crosshair 
glBegin(GL_LINES); 
{ 
    //White colour 
    glColor3f(1.0f, 1.0f, 1.0f); 
    //x, y, z 
    //Vertex2f would be ideal, but doesn't appear (min view distance for perspective?) 
    glVertex3f(-0.0001f, 0.0f, -0.01f); 
    glVertex3f(0.0001f, 0.0f, -0.01f); 
} 
glEnd(); 
//Draw vertical crosshair 
glBegin(GL_LINES); 
{ 
    //Also white 
    glColor3f(1.0f, 1.0f, 1.0f); 
    //Again: x, y, z 
    glVertex3f(0.0f, -0.0001f, -0.01f); 
    glVertex3f(0.0f, 0.0001f, -0.01f); 
} 
glEnd(); 

//Rotate on the x axis (pitch) 
glRotatef(se::pl0.rX, 1.0f, 0.0f, 0.0f); 
//Rotate viewport on the y axis (yaw) 
glRotatef(se::pl0.rY, 0.0f, 1.0f, 0.0f); 
//Translate the world by the negative of our coordinates 
//Camera one way = objects the other... 
glTranslatef(-se::pl0.x, -se::pl0.y, -se::pl0.z); 

glCallList(1); 

//Show the screen we have been calculating, preparing the screen we were showing for drawing 
SDL_GL_SwapBuffers(); 
return; 
} 

void initDisplayLists(void) 
{ 
glGenLists(1); 

cube block = cube(); 

glNewList(1, GL_COMPILE); 
{ 
    block.render(); 
} 
glEndList(); 

return; 
} 

回答

0

你应该加强你的错误检查一下(你不是经常这样做)。

首先,在glBegin/glEnd块中调用glBindTexture是非法的(它需要在glBegin之前)。修复这些非法调用,在渲染循环中添加一些额外的错误检查,并查看是否可以解决您的问题。

而且,不这样做:如果你有,你应该抛出异常或记录他们至少是错误while(glGetError());

,这不是很聪明,只是扔掉任何优秀的OpenGL错误。一般他们都试图告诉你一些重要的事情。