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.xml

    Doch, 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 🤡


Anmelden zum Antworten