2015-01-28 12 views
0

OpenGL을 사용하여 C에서 스카이 박스를 만들려고합니다. 많은 튜토리얼을보고 많은 사람들의 코드를 보았습니다. 내가 아무 것도 놓치지 않았다고 생각하고 검은 화면을 보게된다. 나는 모든 것을 잘못 생각 했는가?C에서 OpenGL을 사용하여 스카이 박스를 만들려고하는데 검정색 화면 만 나타납니다.

#include <windows.h> 
#include <GL/glut.h> 
#include <GL/glu.h> 
#include <GL/gl.h> 
#include <stdio.h> 
#include <math.h> 

GLuint texture[6]; 

/** 
* Init function initializing the background to black. 
*/ 
void init() 
{ 
    glClearColor(0.0, 0.0, 0.0, 0.0); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glLoadIdentity(); 
    glMatrixMode(GL_MODELVIEW | GL_PROJECTION); 
    glEnable(GL_DEPTH_TEST);  
} 

void reshape(int w, int h) 
{ 
    glViewport(0, 0, (GLsizei) w, (GLsizei) h); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0); 
    glMatrixMode(GL_MODELVIEW); 
} 

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

    //Open the image file 
    file = fopen(filename, "rb"); 
    //If it doesn't open just return 0 
    if(file == NULL) 
    { 
     return 0; 
    } 

    //Allocate space for data and read 
    data = (unsigned char *)malloc(width * height * 3); 
    fread(data, width * height * 3, 1, file); 

    //Close the file 
    fclose(file); 

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

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); 

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);  
    free(data); 

    return texture;  
} 

void draw() 
{ 
    int width = 512; 
    int height = 512; 
    int length = 512; 

    //start in this coordinates 
    int x = 0; 
    int y = 0; 
    int z = 0; 

    //center the square 
    x = x - width/2; 
    y = y - height/2; 
    z = z - length/2; 

    // Bind the BACK texture of the sky map to the BACK side of the cube 
    glBindTexture(GL_TEXTURE_2D, texture[0]); 
    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(); 

    //FRONT 
    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(); 

    //BOTTOM 
    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(); 

    //TOP 
    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(); 

    //LEFT 
    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(); 

    //RIGHT 
    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(); 
} 

void display() 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 
    glLoadIdentity(); 
    gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); 
    texture[0] = LoadTexture("back.bmp", 512, 512); 
    /*texture[0] = SOIL_load_OGl_texture 
    { 
     "back.bmp", 
     SOIL_LOAD_AUTO, 
     SOIL_CREATE_NEW_ID, 
     SOIL_FLAG_INVERT_Y 
    };*/ 
    texture[1] = LoadTexture("front.bmp", 512, 512); 
    texture[2] = LoadTexture("left.bmp", 512, 512); 
    texture[3] = LoadTexture("right.bmp", 512, 512); 
    texture[4] = LoadTexture("cesped.bmp", 512, 512); 
    texture[5] = LoadTexture("top.bmp", 512, 512); 

    glEnable(GL_TEXTURE_2D); 
    glEnable(GL_TEXTURE_GEN_S); 
    glEnable(GL_TEXTURE_GEN_T); 

    draw(); 
    glutSwapBuffers(); 
} 

int main(int argc, char* argv[]) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_ALPHA); 
    glutInitWindowSize(1000, 1000); 
    glutInitWindowPosition(100, 100); 
    glutCreateWindow("blah"); 

    init(); 
    glutDisplayFunc(display); 
    glutReshapeFunc(reshape); 

    glutMainLoop(); 

    return 0; 
} 
+0

몇 가지 시도해보기 1. 디스플레이 기능에서 계속해서 텍스처를 만들고 있습니다. 이것은 방법이 아닙니다. Init 함수에 텍스처를 만들고 디스플레이 2에서 사용하십시오. 그리기 기능에서 idleFunc를 설정하지 않고 glutPostRedisplay를 호출하지 않았습니다. –

+0

디버그를 시도하고 문제를 찾을 수 있습니까? – Mysterion

+0

맑은 색을 변경하면 어떤 차이가 있습니까? 또한 텍스처가 올바르게로드되는지 확인 했습니까? 선명한 색상을 볼 수 있다면 메시 그림에 문제가있는 것입니다. 여전히 검은 색이면 텍스처가 성공적으로 작성되지 않은 것입니다. –

답변

1

하늘 상자가 보이는 영역 안에 있지 않은 것 같습니다. 투영 행렬 glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);의 정의를 보면 z 축의 가시 값이 1.5와 20.0 사이 여야한다는 것을 알 수 있습니다. 그러나 skybox는 -256.0에서 256.0으로 그려집니다. 이것은 far-plane/near-plane의 뒤쪽에서 떨어져서 클리핑됩니다.

두 가지 가능한 해결책이 있습니다. 작은 스카이 박스를 그릴 수도 있고, 보이는 영역을 늘릴 수도 있습니다. 일반적으로 결과는 두 경우 모두 동일합니다 (적어도 깊이 테스트없이 하늘 상자를 첫 번째 객체로 렌더링 할 때 일반적으로 수행 할 것입니다).

의견에 따르면 픽셀 단위의 텍스처 크기와 형상 크기 사이에는 아무런 관련이 없습니다. 그래서 512

+0

나는 본다. 그래서 솔루션을 구현하려면 절두체의 값을 변경해야합니까?어떤 가치가 가장 합리적일까요? – user3579421

+0

적어도 256보다 큰 것 – BDL

0

여러 가지의 측면 길이 큐브를 그릴 필요가 wonrg 것 같다 없습니다 : glClear가 GL_DEPTH_BUFFER_BIT하지만 깊이 테스트가 활성화되어

  • 하는 gluLookAt 사용하는 (0없이 호출

    • , 0,0)을 사용하면 모델 뷰 행렬이 좋지 않습니다. 당신은 목표물에 대해 원하는 위치와 위치에 상자의 중심을 사용해야합니다.
    • 디스플레이 기능이 이미지를 다시로드하고 모든 프레임마다 텍스처를 다시 만듭니다! 이 작업은 init() 함수에서 시작시 한 번만 수행하면됩니다. 당신이 텍스처 좌표를 제공입니다 때문에
    • 당신은 GL_TEXTURE_GEN_S 또는 GL_TEXTURE_GEN_T를 사용할 필요가 없습니다.
    • @BDL이 말한 바 : 상자의 크기 (512.0)를 고려하면 멀리 클리핑면이 너무 가깝습니다 (20.0).
  • +0

    감사합니다. 텍스쳐를 만드는 메소드를 init()으로 옮겼습니다. 나는 또한 GL_DEPTH_BUFFER_BIT를 지우고 여분의 가능을 없앴습니다. 그러나 문제는 해결되지 않았습니다. @BDL 값이 올바르지 않다는 것이 맞습니다. 나는 그것을 올바르게하기 위해 지금 당황하고있다. 그러나 나는 그들을 고치기 위해 어떻게 가야하는지 정확히 모르겠다. – user3579421

    +0

    원거리 자르기 평면의 경우 1024.0을 시도하십시오. 또한 gluLookAt 호출을 수정 했습니까? – Shadocko