Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: Still having problems with calling glTransformFeedbackVaryings

  1. #1
    Junior Member Newbie
    Join Date
    Apr 2016
    Location
    Berlin / Germany
    Posts
    25

    Still having problems with calling glTransformFeedbackVaryings

    Hi there,

    i already posted this in the beginners-forum, but noone seems to know help. So i have a second try here...

    My program dosn't return from calling 'glTransformFeedbackVaryings'. Even a simple test-code dosn't work. My GPU should be able to do this (Intel HD4000 / OpenGL 4.0).

    This is my code (not the test-code):
    Code :
        success                 = GL_FALSE;                                         errHandle           = vShNewHandle;
     
        const GLchar* feedbackVaryings[] = { "cppReturn" };
     
    [...]
     
        vShNewHandle            = glCreateShader  (GL_VERTEX_SHADER); 
        tcShNewHandle           = glCreateShader  (GL_TESS_CONTROL_SHADER); 
        teShNewHandle           = glCreateShader  (GL_TESS_EVALUATION_SHADER);
        gShNewHandle            = glCreateShader  (GL_GEOMETRY_SHADER);   
        fShNewHandle            = glCreateShader  (GL_FRAGMENT_SHADER);   
        prgNewHandle            = glCreateProgram (); 
     
        clsRegEx hasCode ("[\\n\\r][\\t ]*void\\s*main\\s*\\(");      // Regular expresseion to test if a shader-string contains "void main ("
     
        if (hasCode.Matches(vShLnkC)) {
            success                 = GL_FALSE;                                     errHandle           = vShNewHandle;   
            glShaderSource          (vShNewHandle, 1, &vShLnkC, NULL);              glCompileShader     (vShNewHandle); 
            glGetShaderiv           (vShNewHandle,  GL_COMPILE_STATUS, &success);   if (success != GL_TRUE) goto ex;
            glAttachShader          (prgNewHandle, vShNewHandle); 
     
            if (hasCode.Matches(fShLnkC)) {
     
    [... - Tesselation-, geometry- & fragment-shader are compiled here if fragment-shader-string ('fShLnkC') contains a main-function]
     
            else {
                glTransformFeedbackVaryings (prgNewHandle, 1, feedbackVaryings, GL_INTERLEAVED_ATTRIBS);    
            }
        }

    Any idea what might be the reason?


    Best,
    Frank

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,359
    Try this short, stand-alone GLUT test program:

    Code cpp:
    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #define GL_GLEXT_PROTOTYPES 1
    #include <GL/gl.h>
    #include <GL/glext.h>
    #include <GL/glu.h>
    #include <GL/glut.h>
     
    #define ARRAY_SIZE(x)  (sizeof(x)/sizeof(x[0]))
     
    const int TF_NUM_OUT   = 2;
    const int TF_OUT_COUNT = 3;
    const int TF_OUT_SIZE  = TF_OUT_COUNT * sizeof(float);
     
    GLuint Tf_pgm                   = 0;      // Transform feedback program
    GLuint Tf_obj                   = 0;      // Transform feedback object
    GLuint Tf_outbuf[ TF_NUM_OUT ];           // Transform feedback output buffer
     
    const int NUM_ATTR = 1;
     
    GLuint Vbo_handle[ NUM_ATTR ];            // Positions
     
     
    static const char TF_VERT_SHADER[] = R"MAGIC(
      #version 330
     
      in  vec3 vertex;
      out vec3 pos;
     
      void main(void)
      {
        pos = vertex;
      };
     
    )MAGIC";
     
     
    static const char TF_GEOM_SHADER[] = R"MAGIC(
      #version 400
     
      layout( points )                   in ;
      layout( points, max_vertices = 1 ) out;
     
      // Inputs
      in vec3 pos[1];
     
      // Outputs
      layout( stream=0 ) out float stream0;
      layout( stream=1 ) out float stream1;
     
      void main(void)
      {
        int route = ( pos[0].z >= 1 ) ? 1 : 0;
     
        switch ( route )
        { 
          case 0  : stream0 = 1234; EmitStreamVertex(0); break;
          case 1  : 
          default : stream1 = 5678; EmitStreamVertex(1); break;
        }
      };
     
    )MAGIC";
     
     
    //----------------------------------------------------------------------------
     
    void check( const char *s )
    {
      GLenum err ;
      bool   found = false;
     
      while ( (err = glGetError()) != GL_NO_ERROR )
      {
        found = true;
        fprintf ( stderr, "%s: OpenGL Error: %s\n", 
                  s ? s : "", gluErrorString ( err ) );
      }
      if ( found )
        exit(1);
    }
     
    //----------------------------------------------------------------------------
     
    void dumpShaderLog( bool is_shader, GLuint obj )
    {
      int maxlen = 0;
      if ( is_shader ) glGetShaderiv ( obj, GL_INFO_LOG_LENGTH, &maxlen );
      else             glGetProgramiv( obj, GL_INFO_LOG_LENGTH, &maxlen );
     
      if ( maxlen > 0 )
      {
        char *log = new char [ maxlen ] ;
        int   len ;
     
        if ( is_shader )  glGetShaderInfoLog ( obj, maxlen, &len, log );
        else              glGetProgramInfoLog( obj, maxlen, &len, log );
     
        if( len > 0 && log[0] != '\0' )
          fprintf( stderr, "%s\n", log ) ;
     
        delete [] log ;
      }
    }
     
    //----------------------------------------------------------------------------
     
    #define getGL( e, str_width )  \
      do                           \
      {                            \
        GLint v;                   \
        glGetIntegerv( e, &v );    \
        printf( "%-*s = %d\n", str_width, #e, v ); \
      }                                           \
      while ( 0 )
     
    //----------------------------------------------------------------------------
     
    void queryGL()
    {
      int w = 48;
     
      printf( "\n" );
      getGL( GL_MAX_GEOMETRY_OUTPUT_VERTICES                 , w );
      getGL( GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS         , w );
      getGL( GL_MAX_VERTEX_STREAMS                           , w );
      getGL( GL_MAX_TRANSFORM_FEEDBACK_BUFFERS               , w );
      getGL( GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, w );
      printf( "\n" );
    }
     
    //----------------------------------------------------------------------------
     
    void initTFProgram( GLuint &tf_pgm )
    {
      // Read shader text
      const char *vert_src = TF_VERT_SHADER;
      const char *geom_src = TF_GEOM_SHADER;
     
      // Compile shaders
      GLint  compiled;
      GLuint vs = glCreateShader( GL_VERTEX_SHADER );
      GLuint gs = glCreateShader( GL_GEOMETRY_SHADER );
     
      glShaderSource ( vs, 1, &vert_src, 0 );
      glShaderSource ( gs, 1, &geom_src, 0 );
     
      glCompileShader( vs );
      glGetShaderiv  ( vs, GL_COMPILE_STATUS, &compiled );
     
      if ( !compiled )
      {
        fprintf( stderr, "TF vertex shader: Failed to compile.\n" );
        dumpShaderLog( true, vs );
        exit(1);
      }
     
      glCompileShader( gs );
      glGetShaderiv  ( gs, GL_COMPILE_STATUS, &compiled );
     
      if ( !compiled )
      {
        fprintf( stderr, "TF geometry shader: Failed to compile.\n" );
        dumpShaderLog( true, gs );
        exit(1);
      }
     
     
      GLuint pgm = glCreateProgram();
     
      glBindAttribLocation( pgm, 0, "vertex" );
     
      //--------------------------------------------------------------------------
      // Designate TRANSFORM FEEDBACK input varyings, ordering, and storage mode
      //--------------------------------------------------------------------------
      const GLchar *strs[] = { "stream0", "gl_NextBuffer", "stream1" }; 
      glTransformFeedbackVaryings( pgm, ARRAY_SIZE(strs), strs, 
                                   GL_INTERLEAVED_ATTRIBS ); 
     
     
      // Link program
      glAttachShader ( pgm, vs );
      glAttachShader ( pgm, gs );
      glLinkProgram  ( pgm ) ;
     
      GLint linked;
      glGetProgramiv ( pgm, GL_LINK_STATUS, & linked ) ;
      if ( !linked )
      {
        fprintf( stderr, "TF program: Failed to link.\n" );
        dumpShaderLog( false, pgm );
        exit(1);
      }
     
      tf_pgm = pgm;
     
      check( "initTFProgram" );
    }
     
    //----------------------------------------------------------------------------
     
    void initTFObject( GLuint &tf, GLuint outbuf[ TF_NUM_OUT ] )
    {
      //--------------------------------------------------------------------------
      // Create TRANSFORM FEEDBACK object
      //--------------------------------------------------------------------------
     
      glGenTransformFeedbacks   ( 1, &tf );
      glBindTransformFeedback   ( GL_TRANSFORM_FEEDBACK, tf );
     
      // Transform feedback:
      //   INPUTS : are program varying(s) (VS or GS output(s))
      //   OUTPUTS: are buffer(s)
     
      // INPUT: (varying)
      //   NOTE: Input varyings, ordering, and storage mode specified above
      //   before we linked the program.  Those are "program state".
     
      // OUTPUT: (buffer)
      for ( int i = 0; i < TF_NUM_OUT; i++ )
      {
        glGenBuffers              ( 1, &outbuf[i] );
        glNamedBufferDataEXT      ( outbuf[i], TF_OUT_SIZE, 0, GL_DYNAMIC_DRAW );
        glBindBufferBase          ( GL_TRANSFORM_FEEDBACK_BUFFER, i, outbuf[i] );
      }
     
      // NOTE: If had wanted to output to a subrange of a buffer, could have
      //   used glBindBufferRange.
     
      glBindTransformFeedback   ( GL_TRANSFORM_FEEDBACK, 0 );
     
      check( "initTFObject" );
    }
     
    //----------------------------------------------------------------------------
     
    void initBatch()
    {
      static const GLfloat pos  [ TF_OUT_COUNT*3 ] = { 0,0,0,
                                                       0,0,1,
                                                       0,0,2 };
     
      // Create and fill VBOs
      glGenBuffers( NUM_ATTR, Vbo_handle );
     
      GLenum gl_target = GL_ARRAY_BUFFER;
     
      // Positions...
      glBindBuffer( gl_target, Vbo_handle[0] );
      glBufferData( gl_target, sizeof(pos)  , pos  , GL_STATIC_DRAW );
    }
     
    //----------------------------------------------------------------------------
     
    void init()
    {
      queryGL();
     
      // Create transform feedback program and object
      initTFProgram( Tf_pgm );
      initTFObject ( Tf_obj, Tf_outbuf );
      initBatch    ();  
     
      check( "init" );
    }
     
    //----------------------------------------------------------------------------
     
    void classifyPoints()
    {
      //--------------------------------------------------------------------------
      // Write to TRANSFORM FEEDBACK buffer with vertex shader executions
      //--------------------------------------------------------------------------
     
      glEnable    ( GL_RASTERIZER_DISCARD );
      glUseProgram( Tf_pgm );
     
      glBindTransformFeedback ( GL_TRANSFORM_FEEDBACK, Tf_obj );
      glBeginTransformFeedback( GL_POINTS );
     
      // Render batch (classic VBOs)
      glBindBuffer             ( GL_ARRAY_BUFFER, Vbo_handle[0] );
      glVertexAttribPointer    ( 0, 3, GL_FLOAT, false, 0, 0 );
      glEnableVertexAttribArray( 0 );
     
      glDrawArrays       ( GL_POINTS, 0, 3 );
     
      glEndTransformFeedback();
     
      glUseProgram( 0 );
      glDisable   ( GL_RASTERIZER_DISCARD );
     
      check( "classifyPoints" );
    }
     
    //----------------------------------------------------------------------------
     
    float *mapBuffer( int i )
    {
      return (GLfloat *) glMapNamedBufferRangeEXT( Tf_outbuf[i], 0, TF_OUT_SIZE, 
                                                   GL_MAP_READ_BIT );
    }
     
    //----------------------------------------------------------------------------
     
    void unmapBuffer( int i )
    {
      glUnmapNamedBufferEXT( Tf_outbuf[i] );
    }
     
     
    //----------------------------------------------------------------------------
     
    void display()
    {
      glClearColor(0.4, 0.4, 0.8, 1.0);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
      // Clear TF output
      memset( mapBuffer(0), '\0', TF_OUT_SIZE ); unmapBuffer(0);
      memset( mapBuffer(1), '\0', TF_OUT_SIZE ); unmapBuffer(1);
     
      // Generate queries to determine how many entries written
      GLuint outquery[ TF_NUM_OUT ];
      glGenQueries( TF_NUM_OUT, outquery );
      for ( int i = 0; i < TF_NUM_OUT; i++ )
        glBeginQueryIndexed( GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, i, 
                             outquery[i] );
     
      // Transform feedback (bin points into 2 different lists)
      classifyPoints();
     
      // Query/print how many entries written
      GLint counts[ TF_NUM_OUT ];
      for ( int i = 0; i < TF_NUM_OUT; i++ )
      {
        glEndQueryIndexed ( GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, i );
        glGetQueryObjectiv( outquery[i], GL_QUERY_RESULT, &counts[i] );
        printf( "Num primitives written for output %d = %d\n", i, counts[i] );
      }
      glDeleteQueries( TF_NUM_OUT, outquery );
     
      // Dump TF output
      for ( int i = 0; i < TF_NUM_OUT; i++ )
      {
        printf( "Transform feedback output %d =", i );
        GLfloat *p = mapBuffer(i);
        for ( int j = 0; j < counts[ i ]; j++ )
        {
          printf( " %g", p[j] );
        }
        unmapBuffer(i);
        printf( "\n" );
      }
     
      glutSwapBuffers();
      glutPostRedisplay();
     
      check( "display" );
     
      exit(0);
    }
     
    //----------------------------------------------------------------------------
     
    void reshape(int w, int h) 
    {
      glViewport(0, 0, w, h);
    }
     
    //----------------------------------------------------------------------------
     
    void keyfunc( unsigned char key, int x, int y )
    {
      switch(key)
      {
        case 27 : exit(0); break;  // ESCape
      }
    }
     
    //----------------------------------------------------------------------------
     
    int main(int argc, char **argv)
    {
      glutInit( &argc, argv );
      glutInitWindowSize( 640, 480 );
      glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
      glutCreateWindow( "Transform Feedback" );
     
      glutReshapeFunc ( reshape );
      glutDisplayFunc ( display );
      glutKeyboardFunc( keyfunc );
     
      init();
     
      glutMainLoop();
      return 0;
    }

    Compile with:

    Code :
    g++ -std=c++11 -o tf_test tf_test.cxx -lglut -lGLU -lGL

    It should generate this output:

    Code :
    GL_MAX_GEOMETRY_OUTPUT_VERTICES                  = 1024
    GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS          = 1024
    GL_MAX_VERTEX_STREAMS                            = 4
    GL_MAX_TRANSFORM_FEEDBACK_BUFFERS                = 4
    GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 128
     
    Num primitives written for output 0 = 1
    Num primitives written for output 1 = 2
    Transform feedback output 0 = 1234
    Transform feedback output 1 = 5678 5678

    Works fine on NVidia. That said, that does "not" necessarily means there's no errors in it. But if it doesn't work for you on Intel, it could be that you're fighting a driver bug.

  3. #3
    Junior Member Newbie
    Join Date
    Apr 2016
    Location
    Berlin / Germany
    Posts
    25
    Thanks for replying. I'll test it and write a report. I hope to find time tomorrow...

    Okay...
    After some days of other work i just saw, that someone answered. Now i red, what you wrote. I'm not sure if i'm able to do this. Its quiet funny: i think, i'm a quiet good progrmmer as a non-professional (currently i think about maybe learning assembler to speed up my self-written interpreter), but i still have problems with any compiler-setup. How i work? Currently i use some kind of "package" which i downloaded at once. It contains a minGW-compiler, the wxWidgets library (which i use as UI) and the gl-library and the old-fashiond devC-IDE. Some weeks ago, i (once again) tried to compile my application using another IDE (code::blocks), without success.
    So, for me it might be a problem to compile a
    stand-alone GLUT test program.
    I'm also not sure if glut is included in my package. Anyway i'll take the time to find out if your code might help me, but it might take a while...

    By the way: i also thougt, it might be a driver-bug. So i downloaded the current one from Intel (mine was older). But nothing changed. This means, that i testet two versions of the driver with the same result. While HD4000 is a standard-GTX and transform-feedbacks are used by lots of applications, a driver-bug seems nearly impossible. To exclude this i also succesfully tried a web-page using WebGL-transormfeedback.
    Therefore i'm wondering, what the problem might be: two drivers tested, WebGL works and my program still crashes if i call "glTransformFeedbackVaryings".

    Best,
    Frank
    Last edited by art-ganseforth; 05-04-2018 at 08:50 AM. Reason: See post..

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •