GLSL: varying variable --> Segmentation fault
-
Hallo,
bei einem simplen Texture Beispiel komme ich nicht weiter
Vertex:#version 120 attribute vec2 position; varying vec2 texcoord; void main() { gl_Position = vec4(position, 0.0, 1.0); texcoord = position * vec2(0.5) + vec2(0.5); }
Fragment:
#version 120 uniform sampler2D texture; varying vec2 texcoord; void main() { gl_FragColor = texture2D(texture, texcoord); }
Kompilieren --> keine Fehler
In diesem Fall bekomme ich beim Ausführen meines Programmes eine Segmentation fault. Ersetze ich im Fragment-Shader texcoord mit vec2(0.0, 0.0) oder vec2(1.0,1.0) oder ... bekomme ich keine Fehlermeldung. Es muss also mit der varying Variable zusammen hängen.
Was mache ich falsch?
Anmerkung: Das Beispiel stammt aus http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Chapter-1:-The-Graphics-Pipeline.html
-
Zeig mal etwas Code, wo genau tritt der segfault auf?
-
glUseProgram ... // setze Parameter und aktivere Texturen glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, glResource.texture[0]); glUniform1i(glResource.uniforms.texture[0], 0); // Vertex und Element Buffer // ... glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, NULL); --> Boom
-
Ist dein Program richtig gelinked? Was sagt glGetError()? Hast du deine Vertex Attribute Pointer richtig gesetzt?
-
Da wurde was falsch verstanden:
Als ersten Parameter von glUniformi() musst du in dem Fall den Index des Uniforms schicken. Den musst du abfragen:int index = glGetUniformLocation("texture"); glUniform1i(index, 0);
edit:
Wobei ich mir nicht so sicher bin, dass es am Shader liegt.
Sind deine Vertices garantiert korrekt?
-
Scorcher24 schrieb:
Sind deine Vertices garantiert korrekt?
Was sollte da falsch sein?
static const GLfloatg_vertex_buffer_data[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f }; static const GLushort g_element_buffer_data[] = { 0, 1, 2, 3 };
-
Die nötigen Zeilen von Code.
void OpenGLWidget::initializeGL () { glClearColor (0.0f, 0.0f, 0.0f, 0.0f); glDisable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); // only show front face glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropicFiltering ); // cout << "max. Anisotropic Filtering: " << maxAnisotropicFiltering << endl; initializeResources (); glFlush (); } void OpenGLWidget::paintGL () { // boost::lock_guard<boost::mutex > mut (out->getMutex ()); glClear (GL_COLOR_BUFFER_BIT); glEnable(GL_TEXTURE_2D); paintPicture (); glDisable(GL_TEXTURE_2D); glFlush (); glFinish (); } void OpenGLWidget::paintPicture () { glUseProgram (glResources.program); glUniform1f (glResources.uniforms.ratio, textureRatio); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_2D, glResources.textures[0]); glUniform1i (glResources.uniforms.textures[0], 0); glBindBuffer (GL_ARRAY_BUFFER, glResources.vertex_buffer); glVertexAttribPointer (glResources.attributes.position, /* attribute */ 2, /* size */ GL_FLOAT, /* type */ GL_FALSE, /* normalized */ sizeof (GLfloat)*2, /* stride */ NULL /* array buffer offset */ ); glEnableVertexAttribArray (glResources.attributes.position); glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, glResources.element_buffer); glDrawElements ( GL_TRIANGLE_STRIP, /* mode */ 4, /* count */ GL_UNSIGNED_SHORT, /* type */ NULL /* element array buffer offset */ ); glDisableVertexAttribArray (glResources.attributes.position); glFlush (); } void OpenGLWidget::initializeSharedTexture(GLint width, GLint height) { sharedTextureWidth = width; sharedTextureHeight = height; const size_t size = sharedTextureWidth * sharedTextureHeight * 4 * sizeof (GLubyte); void* ptr = malloc (size); GLubyte* sharedTexture = reinterpret_cast<GLubyte*> (ptr); size_t cnt = 0; for (GLint i = 0; i < width; i++) { for (GLint j = 0; j < height; j++) { sharedTexture[cnt++] = 255; sharedTexture[cnt++] = 0; sharedTexture[cnt++] = 255; sharedTexture[cnt++] = 0; } } // create Textures glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glGenTextures (1, &glResources.textures[0]); glBindTexture (GL_TEXTURE_2D, glResources.textures[0]); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropicFiltering); glTexImage2D (GL_TEXTURE_2D, 0, // Level GL_RGBA8, // internalformat sharedTextureWidth, sharedTextureHeight, 0, // Breite des Rahmens, 0 oder 1 GL_RGBA8, GL_UNSIGNED_BYTE, // format of input texture sharedTexture ); glFlush (); glFinish (); free (sharedTexture); } GLuint OpenGLWidget::initializeBuffer (GLenum target, const void *buffer_data, GLsizei buffer_size) { GLuint buffer; glGenBuffers (1, &buffer); glBindBuffer (target, buffer); glBufferData (target, buffer_size, buffer_data, GL_STATIC_DRAW); return buffer; } int OpenGLWidget::initializeResources (void) { glResources.vertex_buffer = initializeBuffer (GL_ARRAY_BUFFER, g_vertex_buffer_data, sizeof (g_vertex_buffer_data) ); glResources.element_buffer = initializeBuffer (GL_ELEMENT_ARRAY_BUFFER, g_element_buffer_data, sizeof (g_element_buffer_data) ); initializeSharedTexture (512, 512); if (glResources.textures[0] == 0 || glResources.textures[1] == 0) return 0; glResources.vertex_shader = initializeShader (GL_VERTEX_SHADER, "shader/RenderRectangle_01.v.glsl" ); if (glResources.vertex_shader == 0) return 0; glResources.fragment_shader = initializeShader (GL_FRAGMENT_SHADER, "shader/RenderRectangle_01.f.glsl" ); if (glResources.fragment_shader == 0) return 0; glResources.program = initializeProgram ( glResources.vertex_shader, glResources.fragment_shader ); if (glResources.program == 0) return 0; glResources.uniforms.ratio = glGetUniformLocation (glResources.program, "ratio"); glResources.uniforms.textures[0] = glGetUniformLocation (glResources.program, "texture"); glResources.attributes.position = glGetAttribLocation (glResources.program, "position"); return 1; } GLuint OpenGLWidget::initializeShader (GLenum type, const char *filename) { GLint length; size_t begin, end; ifstream f; f.open (filename); // get length of file begin = f.tellg(); f.seekg (0, ios::end); end = f.tellg(); f.seekg (0, ios::beg); length = static_cast<GLint> ((end - begin)); // allocate memory: char* buffer = (char*) malloc(length+1); // read data as a block: f.read (buffer, length); f.close (); buffer[length] = '\0'; GLchar *source = static_cast<GLchar*> (buffer); GLuint shader; GLint shader_ok; if (!source) return 0; shader = glCreateShader (type); glShaderSource (shader, 1, (const GLchar**) &source, &length); free (buffer); glCompileShader (shader); glGetShaderiv (shader, GL_COMPILE_STATUS, &shader_ok); if (!shader_ok) { fprintf (stderr, "Failed to compile %s:\n", filename); show_info_log (shader, glGetShaderiv, glGetShaderInfoLog); glDeleteShader (shader); return 0; } return shader; } GLuint OpenGLWidget::initializeProgram (GLuint vertex_shader, GLuint fragment_shader) { GLint program_ok; GLuint program = glCreateProgram (); glAttachShader (program, vertex_shader); glAttachShader (program, fragment_shader); glLinkProgram (program); glGetProgramiv (program, GL_LINK_STATUS, &program_ok); if (!program_ok) { fprintf (stderr, "Failed to link shader program:\n"); show_info_log (program, glGetProgramiv, glGetProgramInfoLog); glDeleteProgram (program); return 0; } return program; }
-
Siassei schrieb:
Scorcher24 schrieb:
Sind deine Vertices garantiert korrekt?
Was sollte da falsch sein?
Ich meinte damit, ob du genug Daten gesendet hast um zu zeichnen.
Denn eigentlich denke ich dass glDrawElements mit NULL als letztem Parameter nicht ok ist.
http://www.opengl.org/sdk/docs/man/xhtml/glDrawElements.xml
-
Woher bekommt glResources.attributes.position seinen Wert? Irgendwie vermisse ich da ein glBindAttribLocation() bevor glLinkProgram() aufgerufen wird. Wenn du nur ein einzelnes Quad malen willst ist ein IndexBuffer (GL_ELEMENT_ARRAY_BUFFER) übrigens ziemlich sinnlos (aber gut, für komplexere Modelle ist dann normalerweise dringend zu empfehlen). Abgesehen davon kann es sein dass du noch ein glEnableClientState(GL_VERTEX_ARRAY) brauchst bevor die VBOs greifen, da bin ich mir atm grad nicht zu 100% sicher, evtl. hängt das auch von der OGL Version ab...
-
Scorcher24 schrieb:
Denn eigentlich denke ich dass glDrawElements mit NULL als letztem Parameter nicht ok ist.
http://www.opengl.org/sdk/docs/man/xhtml/glDrawElements.xmlDoch, er verwendet ja VBOs...
-
dot schrieb:
Was sagt glGetError()?
Danke, da habe ich was übersehen. In initializeSharedTexture bekomme ich bei
glTexImage2D (GL_TEXTURE_2D, 0, // Level GL_RGBA8, // internalformat sharedTextureWidth, sharedTextureHeight, 0, // Breite des Rahmens, 0 oder 1 GL_RGBA8, GL_UNSIGNED_BYTE, // format of input texture sharedTexture );
einen Fehlercode 1282. Das müsste invalid Operation heisen. Aber wieso?
max. Texture size = 2048
-
GL_RGBA8 ist kein gültiges format, das geht nur fürs internalFormat.
-
dot schrieb:
GL_RGBA8 ist kein gültiges format, das geht nur fürs internalFormat.
Danke, habe es auch gerade gesehen. Das war doppelt gemobbelt. Aber egal, jetzt läufts
Danke an alle hier