tipos significado que programacion ejemplos definicion declaracion datos c++ opengl segmentation-fault glfw glew

significado - tipos de datos en c++



Error mínimo de segmentación de C++ OpenGL (1)

Estoy siguiendo la primera entrega en el tutorial OpenGL moderno de Tom Dalling y cuando descargué su código funcionó perfectamente. Entonces quise crear mi propia versión mínima para ayudarme a entender cómo funcionaba todo.

#include <GL/glew.h> #include <GLFW/glfw3.h> #include <GLM/glm.hpp> #include <stdexcept> GLFWwindow* gWindow = NULL; GLint gProgram = 0; GLuint gVertexShader = 0; GLuint gFragmentShader = 0; GLuint gVAO = 0; GLuint gVBO = 0; int main() { /** Initialise GLFW **/ if (!glfwInit()){ throw std::runtime_error("GLFW not initialised."); } glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); gWindow = glfwCreateWindow(800, 600, "OpenGL 3.2", NULL, NULL); if(!gWindow) { throw std::runtime_error("glfwCreateWindow failed."); } glfwMakeContextCurrent(gWindow); /** Initialise GLEW **/ glewExperimental = GL_TRUE; if (glewInit() != GLEW_OK) { throw std::runtime_error("Glew not initialised."); } if (!GLEW_VERSION_3_2) { throw std::runtime_error("OpenGL 3.2 not supported."); } /** Set up shaders **/ gVertexShader = glCreateShader(GL_VERTEX_SHADER); //Segmentation fault here gFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(gVertexShader, 1, (const GLchar* const*)R"( #version 150 in vec3 vertexPos out vec colour; void main() { colour = vertexPos; gl_Position = vec4(vertexPos, 1); } )", NULL); glShaderSource(gFragmentShader, 1, (const GLchar* const*)R"( #version 150 in vec3 colour; out vec4 fragColour; void main() { fragColour = colour; } )", NULL); glCompileShader(gVertexShader); glCompileShader(gFragmentShader); /** Set up program **/ gProgram = glCreateProgram(); glAttachShader(gProgram, gVertexShader); glAttachShader(gProgram, gFragmentShader); glLinkProgram(gProgram); glDetachShader(gProgram, gVertexShader); glDetachShader(gProgram, gFragmentShader); glDeleteShader(gVertexShader); glDeleteShader(gFragmentShader); /** Set up VAO and VBO **/ float vertexData[] = { // X, Y, Z 0.2f, 0.2f, 0.0f, 0.8f, 0.2f, 0.0f, 0.5f, 0.8f, 0.0f, }; glGenVertexArrays(1, &gVAO); glBindVertexArray(gVAO); glGenBuffers(1, &gVBO); glBindBuffer(GL_ARRAY_BUFFER, gVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(GL_FLOAT)*9, vertexData, GL_STATIC_DRAW); glVertexAttribPointer(glGetAttribLocation(gProgram, "vertexPos"), 3, GL_FLOAT, GL_FALSE, 0, NULL); /** Main Loop **/ while (!glfwWindowShouldClose(gWindow)) { glfwPollEvents(); glBindBuffer(GL_ARRAY_BUFFER, gVBO); glDrawArrays(GL_TRIANGLES, 0, 1); glfwSwapBuffers(gWindow); } return 0; }

Esto es lo que creé y se construye correctamente. Sin embargo, al ejecutarlo obtengo un error de segmentación al llamar a glCreateShader.

He buscado mucho para encontrar una solución a esto y hasta ahora he encontrado dos razones principales para que esto suceda:

  • Una es que glewExperimental debe establecerse en GL_TRUE, sin embargo, nada cambió después de agregar esta línea.
  • La segunda razón era que el contexto de OpenGL no se estaba configurando, pero creo que la llamada a glfwMakeContextCurrent cubre este punto.

Desde aquí no tengo ni idea de qué hacer, ¡así que cualquier consejo sería de gran ayuda!

EDIT: ¡Gracias a todos por su ayuda! Eventualmente logré que funcione y cargué el código para pegarlo para futuras referencias.


Solución del problema

Usted programa bloqueos no en la línea que señaló, sino en la primera llamada glShaderSource . De hecho, pasa un puntero a una cadena como tercer argumento, fundiéndolo en (const GLchar* const*) . Eso no es lo que glShaderSource espera. Más bien se espera un puntero a una matriz de punteros a cadenas, cuya longitud (matriz de punteros) se debe pasar como segundo argumento (ver documentación ).

Como solución rápida y sucia para tu código, declaré lo siguiente:

const char *vs_source[] = { "#version 150/n", "in vec3 vertexPos/n", "out vec colour;/n", "void main() {/n", " colour = vertexPos;/n", " gl_Position = vec4(vertexPos, 1);/n", "}/n"}; const char *fs_source[] = { "#version 150/n", "in vec3 colour;/n", "out vec4 fragColour;/n", "void main() {/n", " fragColour = colour;/n", "}/n"};

y reemplazó las llamadas a glShaderSource para

glShaderSource(gVertexShader, 7, (const char**)vs_source, NULL); glShaderSource(gFragmentShader, 6, (const char**)fs_source, NULL);

Ahora el programa funciona bien y muestra una ventana como se esperaba.

Sugerencias

  • Su código ni siquiera se compiló en mi máquina (utilizo gcc 4.8.3 @ Linux) debido a la (const GLchar* const*) de una cadena literal a (const GLchar* const*) . Intente establecer indicadores más restrictivos en sus opciones de compilación y preste atención a las advertencias del compilador. Además, trata las advertencias como errores.

  • Utilice algún tipo de generador de perfiles de memoria para determinar la ubicación exacta de los bloqueos. Por ejemplo, utilicé Valgrind para localizar el problema.