2012-09-25 6 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 남아 있고, 아무것도 열려진에 출력되지 않는다)

//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 함수의 반환 값은 텍스처 배열의 모든 요소 (right, left, top, bottom, front, back (enums))에 복사됩니다.

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을 오류를 멀리 던져 아주 똑똑한 아니다. 일반적으로 그들은 당신에게 중요한 것을 말하려고합니다.

관련 문제