GLSL 1.4 questions

I’ve done quite a bit of work with earlier GLSL versions. They were lovely and simple. Take GL’s output, tweak how it was handled and done. Fairly easy to use, just 3D maths.

GLSL 1.4 on the other hand, I just can’t understand. There’s next to no simple documentation unlike the older versions, instead just badly written rubbish that’s only just borderline English. In older versions, I could just gl_FragColor/Data and set the pixel colour. There seems to be no such thing on 1.4, instead it’s piped to an out. Fine, but how exactly does one define what that “out” points to? Does it go to the render context? Does it go to a buffer and need copying there? How is it even chosen which “out” goes where?

If I want to send data directly to the pixel shader to be interpolated between vertices, is there a way to do that without using the vertex shader as a passthrough? Seems almost silly and redundant that texture coordinates are copy/pasted by the vertex shader.

The Khronos Group provides a lot of presentations:
http://www.khronos.org/developers/library/

Notably “Siggraph New Orleans 2009 - OpenGL BOF Slides”:
http://www.khronos.org/library/detail/siggraph-new-orleans-2009-opengl-bof-slides/

Look at the GLSL presentation:
http://www.khronos.org/developers/librar…graph-Aug09.pdf

Slides 16 to 28 are about porting a simple shader to core (1.5).

Seems like GLSL 1.4 was the focus of the latest OpenGL Shading Language book (aka the “Orange Book”). It’s a good read.

Just ask questions if you have some. Biggest change is that GLSL 1.3 ripped out the built-in identifiers (legacy vtx attribs, lights, materials, etc.). So you have to use your own.

In older versions, I could just gl_FragColor/Data and set the pixel colour. There seems to be no such thing on 1.4, instead it’s piped to an out. Fine, but how exactly does one define what that “out” points to?

glBindFragDataLocation( pgm, buffer_idx, name_str );

pg. 240 in the Orange Book

If I want to send data directly to the pixel shader to be interpolated between vertices, is there a way to do that without using the vertex shader as a passthrough? Seems almost silly and redundant that texture coordinates are copy/pasted by the vertex shader.

With the fixed function pipe gone, you always have to have a vertex shader, so yes.

Shouldn’t seem silly. The input of the vertex shader execution unit is different from the output. You may have one attribute, 2, 5, 10, whatever, bound to potentially random vertex attribute indices. Making building these vertex shader permutations built-in functionality doesn’t really score anything for most folks. So no special case for that. Your vert shader just ends up being really, really simple :slight_smile:

I’ve encountered a problem. I have a few custom shaders working beautifully to render a nice gradient sky, bumpmapped clouds (procedural) and the sun but when I come to draw the world to a FBO (because I want to downscale the image and then blend according to depth to produce a simplistic focal blur later on) it seemingly ignores the FBO and renders straight out to the viewport. The framebuffer appears to be complete according to the test function. I have bound the out variable properly. ( glBindFragDataLocation( gluiTerrainShader, 0, “v4DiffuseOut” ); ) I can confirm that aside from going straight to the viewport rather than into my texture the shader works properly. My shaders are as follows:


uint8_t ui8Shader_Terrain_Vertex[] =
"#version 140
"

"in vec3 v3Vertex;"

"uniform mat4 m4Transform;"

"void main()"
"{"

"   gl_Position = m4Transform * vec4( v3Vertex, 1.0 );"

"}";

uint8_t ui8Shader_Terrain_Fragment[] =
"#version 140
"

"out vec4 v4DiffuseOut;"

"void main()"
"{"

   v4DiffuseOut = vec4( 1, 0, 0, 1.0 );

}

I am enabling the VBO like this at render time:


                    glBindFramebuffer( GL_FRAMEBUFFER, gluiPipelineFBO );

                    GLuint gluiBuffersToUse[ 1 ] = { GL_COLOR_ATTACHMENT0 };

                    glDrawBuffers( 1, gluiBuffersToUse );

The FBO is being setup like this:


        glGenTextures( 1, &gluiPipelineDiffuse );

        if( gluiPipelineDiffuse == 0 )
        {

            RETURN_FAILURE FAILURE_LOW_MEMORY;

        }

        glGenFramebuffers( 1, &gluiPipelineFBO );

        if( gluiPipelineFBO == 0 )
        {

            RETURN_FAILURE FAILURE_LOW_MEMORY;

        }

        glBindFramebuffer( GL_FRAMEBUFFER, gluiPipelineFBO );

        glGenRenderbuffers( 1, &gluiPipelineDepth );

        if( gluiPipelineDepth == 0 )
        {

            glBindFramebuffer( GL_FRAMEBUFFER, 0 );

            RETURN_FAILURE FAILURE_LOW_MEMORY;

        }

        uiPOTScreenWidth = 1;

        while( uiPOTScreenWidth < tsCurrentConfiguration.uiScreenWidth )
        {

            uiPOTScreenWidth <<= 1;

        }

        uiPOTScreenHeight = 1;

        while( uiPOTScreenHeight < tsCurrentConfiguration.uiScreenHeight )
        {

            uiPOTScreenHeight <<= 1;

        }

        glBindRenderbuffer( GL_RENDERBUFFER, gluiPipelineDepth );

        glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tsCurrentConfiguration.uiScreenWidth, tsCurrentConfiguration.uiScreenHeight );

        glBindTexture( GL_TEXTURE_2D, gluiPipelineDiffuse );
        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, uiPOTScreenWidth, uiPOTScreenHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );

        glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gluiPipelineDiffuse, 0 );

        glBindTexture( GL_TEXTURE_2D, 0 );

        printf( "%d %d
", uiPOTScreenWidth, uiPOTScreenHeight );
        //glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gluiPipelineSpecular, 0 );
        //glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gluiPipelineNormal, 0 );
        //glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, gluiPipelineNormalised, 0 );
        //glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, gluiPipelineDiffuseLight, 0 );
        //glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, GL_TEXTURE_2D, gluiPipelineSpecularLight, 0 );

        if( glCheckFramebufferStatus( GL_FRAMEBUFFER ) != GL_FRAMEBUFFER_COMPLETE )
        {

            glBindFramebuffer( GL_FRAMEBUFFER, 0 );

            RETURN_FAILURE FAILURE_GENERIC;

        }

        //Celestial shader...
        gluiTerrainVertex = glCreateShader( GL_VERTEX_SHADER );

        if( gluiTerrainVertex == 0 )
        {

            RETURN_FAILURE FAILURE_LOW_MEMORY;

        }

        gluiTerrainFragment = glCreateShader( GL_FRAGMENT_SHADER );

        if( gluiTerrainFragment == 0 )
        {

            RETURN_FAILURE FAILURE_LOW_MEMORY;

        }

        gluiTerrainShader = glCreateProgram();

        if( gluiTerrainShader == 0 )
        {

            RETURN_FAILURE FAILURE_LOW_MEMORY;

        }

        const GLchar * glcAltVertex = ( GLchar * ) ui8Shader_Terrain_Vertex;
        const GLchar * glcAltFragment = ( GLchar * ) ui8Shader_Terrain_Fragment;

        //Now let's add the source code...
        glShaderSource( gluiTerrainVertex, 1, &glcAltVertex, NULL );
        glShaderSource( gluiTerrainFragment, 1, &glcAltFragment, NULL );

        glCompileShader( gluiTerrainVertex );
        glCompileShader( gluiTerrainFragment );

        //Put them all together...
        glAttachShader( gluiTerrainShader, gluiTerrainVertex );
        glAttachShader( gluiTerrainShader, gluiTerrainFragment );

        glBindFragDataLocation( gluiTerrainShader, 0, "v4DiffuseOut" );

        glLinkProgram( gluiTerrainShader );

        #ifdef DEBUG_COMMENTS_RENDERER

            ShaderDebug( gluiTerrainVertex );
            ShaderDebug( gluiTerrainFragment );
            ProgramDebug( gluiTerrainShader );

        #endif

        glUseProgram( gluiTerrainShader );

        glUniform1i( glGetUniformLocation( gluiTerrainShader, "s2DNormal" ), 0 );

        gliTerrainVarVertex = glGetAttribLocation( gluiTerrainShader, "v3Vertex" );
        gliTerrainVarTexCoord = glGetAttribLocation( gluiTerrainShader, "v2TexCoord" );
        gliTerrainVarTransform = glGetUniformLocation( gluiTerrainShader, "m4Transform" );
        gliTerrainVarNormal = glGetUniformLocation( gluiTerrainShader, "v3Normal" );
        gliTerrainVarTangent = glGetUniformLocation( gluiTerrainShader, "v3Tangent" );
        gliTerrainVarBitangent = glGetUniformLocation( gluiTerrainShader, "v3Bitangent" );

        glUseProgram( 0 );

        glBindFramebuffer( GL_FRAMEBUFFER, 0 );

I presumed the framebuffer had to be bound when binding the output. Is this the case?

It just ignores the FBO. I have no explanation. I can’t understand it.

Oh, and thanks for your posts. They were quite insightful.

Barring GL errors, your last glBindFramebuffer should be where your rendering goes (binding 0 meaning use the system framebuffer).

That’s the end of the setup phase. There’s stuff before and after the world that doesn’t go into the FBO (the sky, UI) so it’s toggled on/off accordingly.

glGetError returns 0.

Thanks for your suggestions.

On a supplementary note, moving the calls to toggle glFramebuffer out of a display list have stopped the objects being rendered full stop. Getting there, I guess.

FINAL SUPPLEMENT:
I had a leftover glEnable of GL_LIGHTING earlier in the code, which, in combination with no lights being enabled, was blacking out the shaderless render window.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.