2013-05-31 4 views
0

Я улучшаю свое знание open gl. Ну, я ужасно терпеть неудачу. У меня случился сбой, когда я пытался отобразить простой треугольник с некоторым кодом из моих исследований, смешанных с этим учебным пособием: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-2-the-first-triangle/OpenGl 3.3 сбой glDrawArrays

Любая идея, почему я получил сбой (никакой дополнительной информации из gdb просто вызов glDrawArrays не вызывает сбой). У меня есть экспериментальный драйвер gpu на моем 64-битном lubuntu, но 3D-игры и другой код работают. Не уверен, что я делаю неправильно. PS: Я делаю это для себя, никаких «домашних заданий» или чего-то еще.

#include <iostream> 

#include <GL/glew.h> 
#include <GL/freeglut.h> 
#include <glm/glm.hpp> 
#include <glm/gtc/type_ptr.hpp> 
#include <glm/gtc/matrix_transform.hpp> 
#include <glm/gtc/matrix_inverse.hpp> 
#include <glm/gtx/rotate_vector.hpp> 
#include <glm/gtx/string_cast.hpp> 

#include <stdlib.h> 
#include <stdio.h> 
#include <iostream> 
#include <fstream> 
#include <stack> 
#include <cmath> 
#include <sstream> 
#include <vector> 

GLuint triangleVertexBufferId; 
GLuint attribPointer; 


void updateGL() 
{ 

    // clear buffer, enable transparency 
    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    //glEnable(GL_BLEND); 

    //glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBufferId); 

    std::cout << "Loop: " << triangleVertexBufferId << std::endl; 
    glEnableVertexAttribArray(0); 
    glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBufferId); 
    /*glVertexAttribPointer(
     0,     // attribute 0. No particular reason for 0, but must match the layout in the shader. 
     3,     // size 
     GL_FLOAT,   // type 
     GL_FALSE,   // normalized? 
     0,     // stride 
     (void*)0   // array buffer offset 
    );*/ 

    glDrawArrays(GL_TRIANGLES, 0, 3); 
    glDisableVertexAttribArray(0); 



    // swap renderbuffers for smooth rendering // 
    glutSwapBuffers(); 
} 

void idle() 
{ 
    glutPostRedisplay(); 
} 

// Callback function called by GLUT when window size changes 
void Reshape(int width, int height) 
{ 
    glutPostRedisplay(); 

} 

void Terminate(void) 
{ 
} 


int main(int argc, char** argv) 
{ 

    std::cout << "Hi" << std::endl; 

    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 
    glutInitContextVersion(3,3); 
    glutInitContextFlags(GLUT_FORWARD_COMPATIBLE); 
    glutInitContextProfile(GLUT_CORE_PROFILE); 

    glutInitWindowSize (1024, 768); 
    glutInitWindowPosition (10, 10); 
    glutCreateWindow("Exercise 04 - Camera control and projection"); 
    glutCreateMenu(NULL); 

    glutDisplayFunc(updateGL); 
    glutReshapeFunc(Reshape); 
    glutIdleFunc(idle); 
    atexit(Terminate); 


    glewInit(); 

    std::vector<glm::vec3> vertices; 
    std::vector<glm::vec3> normals; 
    std::vector<glm::vec2> uvs; 
    std::vector<glm::vec3> triangle_index; 

    vertices.push_back(glm::vec3(-1.0f,-1.0f,0.0f)); 
    vertices.push_back(glm::vec3(1.0f,-1.0f,0.0f)); 
    vertices.push_back(glm::vec3(0.0f,1.0f,0.0f)); 



    std::cout << "Main: " << triangleVertexBufferId << std::endl; 

    glGenVertexArrays(1,&triangleVertexBufferId); 

    glBindVertexArray(triangleVertexBufferId); 



    GLfloat rawVertexData[vertices.size()*3]; 
    for(unsigned int i = 0; i < vertices.size();i=i+3) 
    { 
     rawVertexData[i] = vertices[i].x; 
     rawVertexData[i+1] = vertices[i].y; 
     rawVertexData[i+2] = vertices[i].z; 
    } 

    glBufferData(GL_ARRAY_BUFFER, vertices.size()*3*sizeof(GLfloat), &rawVertexData[0], GL_STATIC_DRAW); 

    std::cout << "Main: " << triangleVertexBufferId << std::endl; 
    glutMainLoop(); 
    return(0); 
} 
+2

Почему вы прокомментировали вызов 'glVertexAttribPointer'? Без него вы просто включаете массив 0, но указатель остается на начальных значениях, что может привести к сбою. – derhass

+0

Какова конфигурация вашего устройства (поддерживается версия gl, производитель карт, модель карты, ОС)? Я вижу ту же самую проблему на OSX с Nvidia geforce gt 650M; Взгляните на этот пост на форумах OpenGL: https://www.opengl.org/discussion_boards/showthread.php/180761-Shader-glDrawArrays-crash-only-on-nVidia-Win32. В основном это говорит о том, что (по крайней мере) на картах nvidia будет сброшено исключение нарушения доступа, и ваше приложение выйдет из строя, если атрибутные массивы будут включены, но никогда не будут использоваться. Я думаю, чтобы этот учебник работал, нам нужен и шейдерный код, вопреки утверждениям автора – CCJ

ответ

1
  • glGenBuffers для буфера вершин и glGenVertexArrays для ВАО
  • петли для инициализации rawVertexData была неправильной (только первая вершина получила загружена)
  • шейдеров могут быть использованы (раскоментируйте glVertexAttribPointer())

С этими адаптациями ваш код будет выглядеть примерно так:

... 
GLuint triangleVertexBufferId; 
GLuint attribPointer; 
GLuint programID; 

void updateGL() 
{ 

    // clear buffer, enable transparency 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    //glEnable(GL_BLEND); 

    //glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBufferId); 
    glUseProgram(programID); 

    //std::cout << "Loop: " << triangleVertexBufferId << std::endl; 
    glEnableVertexAttribArray(0); 
    glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBufferId); 
    glVertexAttribPointer(
     0,     // attribute 0. No particular reason for 0, but must match the layout in the shader. 
     3,     // size 
     GL_FLOAT,   // type 
     GL_FALSE,   // normalized? 
     0,     // stride 
     (void*)0   // array buffer offset 
    ); 

    glDrawArrays(GL_TRIANGLES, 0, 3); 
    glDisableVertexAttribArray(0); 

    // swap renderbuffers for smooth rendering // 
    glutSwapBuffers(); 
} 

void idle() 
{ 
    glutPostRedisplay(); 
} 

// Callback function called by GLUT when window size changes 
void Reshape(int width, int height) 
{ 
    glutPostRedisplay(); 

} 

void Terminate(void) 
{ 
} 

GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){ 
    ... 
    see www.opengl-tutorial.org for code and shaders 
    ...   
}  

int main(int argc, char** argv) 
{ 

    std::cout << "Hi" << std::endl; 

    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 
    glutInitContextVersion(3,3); 
    glutInitContextFlags(GLUT_FORWARD_COMPATIBLE); 
    glutInitContextProfile(GLUT_CORE_PROFILE); 

    glutInitWindowSize (1024, 768); 
    glutInitWindowPosition (10, 10); 
    glutCreateWindow("Exercise 04 - Camera control and projection"); 
    glutCreateMenu(NULL); 

    glutDisplayFunc(updateGL); 
    glutReshapeFunc(Reshape); 
    glutIdleFunc(idle); 
    atexit(Terminate); 

    glewExperimental = true; 
    glewInit(); 

    programID = LoadShaders("SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader"); 

    std::vector<glm::vec3> vertices; 
    std::vector<glm::vec3> normals; 
    std::vector<glm::vec2> uvs; 
    std::vector<glm::vec3> triangle_index; 

    vertices.push_back(glm::vec3(-1.0f,-1.0f,0.0f)); 
    vertices.push_back(glm::vec3(1.0f,-1.0f,0.0f)); 
    vertices.push_back(glm::vec3(0.0f,1.0f,0.0f)); 

    GLuint VertexArrayID; 
    glGenVertexArrays(1, &VertexArrayID); 
    glBindVertexArray(VertexArrayID); 
    std::cout << "Main: " << VertexArrayID << std::endl; 

    GLfloat rawVertexData[3*3]; 
    for(unsigned int i = 0; i < vertices.size(); i++) 
    { 
     rawVertexData[i*3] = vertices[i].x; 
     rawVertexData[i*3+1] = vertices[i].y; 
     rawVertexData[i*3+2] = vertices[i].z; 
    } 

    glGenBuffers(1, &triangleVertexBufferId); 
    glBindBuffer(GL_ARRAY_BUFFER, triangleVertexBufferId); 
    glBufferData(GL_ARRAY_BUFFER, vertices.size()*3*sizeof(GLfloat), &rawVertexData[0], GL_STATIC_DRAW); 

    std::cout << "Main: " << triangleVertexBufferId << std::endl; 
    glutMainLoop(); 
    return(0); 
} 
Смежные вопросы