2013-10-26 2 views
0

Я пытаюсь написать базовую программу OpenGL 3.3 с шейдерами, буферами и т. Д., Рисуя куб. Проблема в том, что куб не нарисован. Извините за такой код кода, но я чувствую, что ошибка может быть где угодно, потому что для меня все кажется правильным: функция отображения - это цикл, шейдеры скомпилированы, матрицы передаются шейдерам. Я подозреваю, что что-то может быть неправильно с отбраковкой. Взгляни, пожалуйста. Вот код (я использую freeglut, первый Init() вызывается, то дисплей работает в цикле):Куб не рендеринга в OpenGL

код инициализации:

struct ProgramData 
{ 
    GLuint theProgram; 
    GLuint iModel; 
    GLuint iView; 
    GLuint iProjection; 
}; 

ProgramData shaderProgram; 

ProgramData LoadProgram(const std::string &strVertexShader, 
         const std::string &strFragmentShader) 
{ 
    std::vector<GLuint> shaderList; 

    shaderList.push_back(LoadShader(GL_VERTEX_SHADER, strVertexShader)); 
    shaderList.push_back(LoadShader(GL_FRAGMENT_SHADER, strFragmentShader)); 

    ProgramData data; 
    data.theProgram = CreateProgram(shaderList); 
    data.iModel = glGetUniformLocation(data.theProgram, "mModel"); 
    data.iView = glGetUniformLocation(data.theProgram, "mView"); 
    data.iProjection = glGetUniformLocation(data.theProgram, "mProjection"); 

    return data; 
} 

float cube_vertices[] = { 
    -1.0f, -1.0f, 1.0f, 
    1.0f, -1.0f, 1.0f, 
    1.0f, 1.0f, 1.0f, 
    -1.0f, 1.0f, 1.0f, 
    -1.0f, -1.0f, -1.0f, 
    1.0f, -1.0f, -1.0f, 
    1.0f, 1.0f, -1.0f, 
    -1.0f, 1.0f, -1.0f, 

    GREEN_COLOR, 
    BLUE_COLOR, 
    RED_COLOR, 
    BROWN_COLOR, 

    GREEN_COLOR, 
    BLUE_COLOR, 
    RED_COLOR, 
    BROWN_COLOR, 
}; 

GLubyte cube_elements[] = { 
    0,1,2, 2,3,0, 
    0,3,4, 4,5,0, 
    0,5,6, 6,1,0, 
    1,6,7, 7,2,1, 
    7,4,3, 3,2,7, 
    4,7,6, 6,5,4 
}; 

void InitializeProgram() 
{ 

    //initialize vertex buffer 
    glGenBuffers(1, &vertex_buffer_obj); 
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_obj); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), 
        cube_vertices, GL_STATIC_DRAW); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 

    //initialize index buffer 
    glGenBuffers(1, &index_buffer_obj); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_obj); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cube_elements), 
          cube_elements, GL_STATIC_DRAW); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 

    shaderProgram = LoadProgram("shader.vert", "shader.frag"); 
} 

void init() 
{ 
    InitializeProgram(); 

    int numberOfVertices = 8; 
    size_t color_data_offset = sizeof(float) * 3 * numberOfVertices; 

    glGenVertexArrays(1, &vao); 
    glBindVertexArray(vao); 

    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_obj); 
    glEnableVertexAttribArray(0); 
    glEnableVertexAttribArray(1); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 
          (void*)color_data_offset); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_obj); 
    glBindVertexArray(0); 


    glEnable(GL_CULL_FACE); 
    glCullFace(GL_BACK); 
    glFrontFace(GL_CW); 

    glEnable(GL_DEPTH_TEST); 
    glDepthMask(GL_TRUE); 
    glDepthFunc(GL_LEQUAL); 
    glDepthRange(0.0f, 1.0f); 

} 

вершинные шейдеры:

#version 330 

layout (location = 0) in vec3 inPosition; 
layout (location = 1) in vec3 color; 

uniform mat4 mProjection; 
uniform mat4 mView; 
uniform mat4 mModel; 

smooth out vec3 theColor; 

void main() 
{ 
    gl_Position = mProjection * mView * mModel * vec4(inPosition, 1); 
    theColor = color; 
} 

пиксельный шейдер:

#version 330 

smooth in vec3 theColor; 
out vec4 outputColor; 

void main() 
{ 
    outputColor = vec4(theColor, 1); 
} 

Жеребьевка код:

glm::vec3 cam_pos(3, 2, 3); 
void display() 
{ 

glClearColor(0.3f, 0.3f, 0.3f, 1.0f); 
glClearDepth(1.0f); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

glUseProgram(shaderProgram.theProgram); 

glm::mat4 model_matrix = glm::translate(glm::vec3(0, 0, 0)); 
glm::mat4 view_matrix = glm::lookAt(cam_pos, 
         glm::vec3(0, 0, 0), glm::vec3(0, 0, 1)); 
glm::mat4 proj_matrix = glm::perspective(45.0f, 1.0f, 1.0f, 100.0f); 

glUniformMatrix4fv(shaderProgram.iProjection, 1, 
         GL_FALSE, glm::value_ptr(proj_matrix)); 
glUniformMatrix4fv(shaderProgram.iView, 1, 
         GL_FALSE, glm::value_ptr(view_matrix)); 
glUniformMatrix4fv(shaderProgram.iModel, 1, 
         GL_FALSE, glm::value_ptr(model_matrix)); 

glBindVertexArray(vao); 
int size; glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, 
             GL_BUFFER_SIZE, &size); 
glDrawElements(GL_TRIANGLES, size/sizeof(GLubyte), GL_UNSIGNED_SHORT, 0); 

glBindVertexArray(0); 
glUseProgram(0); 

    glutSwapBuffers(); 
    glutPostRedisplay(); 
} 

UPD: в методе инициализации, когда смещение для цветов рассчитывается должно быть sizeof(float) * 3 * numberOfVertices вместо sizeof(GLubyte) * 3 * numberOfVertices, цвета сохраняются в виде поплавков. Проблема рендеринга не решена.

РЕШЕНИЕ: Благодарю вас за помощь. См. Мой ответ ниже.

+0

Вы используете систему передала правильно для вашей модели пространства? – legends2k

+0

Я думаю, да, это правильно. –

+0

Тогда не должно быть лицевого лица CCW? – legends2k

ответ

0

В дисплее функции()

glDrawElements(GL_TRIANGLES, size/sizeof(GLubyte), GL_UNSIGNED_SHORT, 0); 

должен быть изменен на

glDrawElements(GL_TRIANGLES, size/sizeof(GLubyte), GL_UNSIGNED_BYTE, 0); 

и INIT()

glFrontFace(GL_CW); 

к

glFrontFace(GL_CCW); 

Таким образом, проблема заключалась в том, что я передал неправильные данные OpenGL. Массив индекса имеет GLUbyte (размер 1 байта для каждого элемента массива), но я почему-то решил, что это GLushort (2 байта).

редактировать: не имеет значения, много, но до вектора (при генерации матрицы камеры) должно быть не glm::vec3(0, 0, 1) но glm::vec3(0, 1, 0)

+0

Вероятно, потому что 'GLubyte' - это не размер поддерживаемого аппаратным обеспечением размера, а где-то в глубине, вы уже это знали;) Придерживайтесь 16-битных/32-разрядных индексов для рабочего стола Графические процессоры и большинство встроенных графических процессоров. Использование 8-разрядных индексов требует, чтобы драйвер выполнял дополнительную работу, поскольку аппаратные средства не могут их использовать.Индексы меньшего размера всегда лучше, но 8-битные индексы никогда не бывают хорошими - используйте наименьший размер, который вы можете уйти, пока поддерживается аппаратное обеспечение. –

+0

спасибо за совет! –

3

На, что я сделал, когда пятно поглядывая коды является следующей строкой из вашего вершинного шейдера:

gl_Position = mProjection * mView * mModel * vec4(inPosition, 0); 

Это 0 действительно должно быть 1.0.

+0

+1 только векторы имели бы 0 для w, точки должны иметь 1 для перевода на работу. – legends2k

+0

Спасибо, вы правы, исправлено это, но проблема все еще существует –

Смежные вопросы