0
votes

I am trying to pass in a distance as a vertex attribute from my c++ code into the shader which draws a line between two vertices.

Currently one line has distance 0 (start), and the other has distance 1.0. I would expect this value to be interpolated just like the colors, but it does not seem to work. Thus I would expect half of the line to be red and the other green, but the whole line turns out green.

Fragment shader code below, where dist in the vertex shader comes in from layout(location = 2) in float in_dist and is passed out as out float dist (no operations performed).

in float dist;

Fragment getFragment() 
{
    Fragment frag;
    frag.depth = vs_positionScreenSpace.w;

    frag.gPosition = vs_gPosition;

    if(dist > 0.5){
        frag.color = vec4(1.0,0.0,0.0,1.0);
    }else{
        frag.color = vec4(0.0,1.0,0.0,1.0);
    }

    frag.gNormal = vec4(0.0, 0.0, 1.0, 0.0);

    return frag;
}

Vertex shader

layout(location = 0) in vec3 in_point_position;
layout(location = 1) in vec4 in_color;
layout(location = 2) in float in_dist;

out float dist;

void main() {

    //somestuff....

    dist = in_dist;
}
2
Post your vertex shader. I'm guessing that dist is being treated as a uniform rather than an interpolant. - 3Dave
It could also be that the location=2 is not well defined at glVertexAttribPointer. So, a MCVE, please. - Ripi2
With that shader, abbreviated though it is, I'd say that either @Ripi2 is correct, or you're not correctly setting the value in your vertex buffer. What does RenderDoc tell you? - 3Dave
@Ripi2 Thank you, it was the size of the glVertexAttribPointer that was wrong. - Hopploppa

2 Answers

3
votes

Workin' fine here:

screenshot of green-red line

MCVE:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <vector>
#include <iostream>
#include <cstdarg>

struct Program
{
    static GLuint Load( const char* shader, ... )
    {
        GLuint prog = glCreateProgram();
        va_list args;
        va_start( args, shader );
        while( shader )
        {
            const GLenum type = va_arg( args, GLenum );
            AttachShader( prog, type, shader );
            shader = va_arg( args, const char* );
        }
        va_end( args );
        glLinkProgram( prog );
        CheckStatus( prog );
        return prog;
    }

private:
    static void CheckStatus( GLuint obj )
    {
        GLint status = GL_FALSE;
        if( glIsShader(obj) ) glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
        if( glIsProgram(obj) ) glGetProgramiv( obj, GL_LINK_STATUS, &status );
        if( status == GL_TRUE ) return;
        GLchar log[ 1 << 15 ] = { 0 };
        if( glIsShader(obj) ) glGetShaderInfoLog( obj, sizeof(log), NULL, log );
        if( glIsProgram(obj) ) glGetProgramInfoLog( obj, sizeof(log), NULL, log );
        std::cerr << log << std::endl;
        std::exit( EXIT_FAILURE );
    }

    static void AttachShader( GLuint program, GLenum type, const char* src )
    {
        GLuint shader = glCreateShader( type );
        glShaderSource( shader, 1, &src, NULL );
        glCompileShader( shader );
        CheckStatus( shader );
        glAttachShader( program, shader );
        glDeleteShader( shader );
    }
};

const char* vert = R"GLSL(
#version 330 core
layout( location = 0 ) in vec4 inPos;
layout( location = 1 ) in float inDist;
out float dist;
void main()
{
    dist = inDist;
    gl_Position = inPos;
}
)GLSL";

const char* frag = R"GLSL(
#version 330 core
in float dist;
out vec4 outColor;
void main()
{
    if( dist > 0.5 )
    {
        outColor = vec4( 1.0, 0.0, 0.0, 1.0 );
    }
    else
    {
        outColor = vec4( 0.0, 1.0, 0.0, 1.0 );
    }
}
)GLSL";

int main( int argc, char** argv )
{
    glfwInit();
    glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
    glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
    glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
    GLFWwindow* window = glfwCreateWindow( 640, 480, "GLFW", NULL, NULL );
    glfwMakeContextCurrent( window );
    glewInit();
    glfwSwapInterval( 1 );

    GLuint prog = Program::Load( vert, GL_VERTEX_SHADER, frag, GL_FRAGMENT_SHADER, NULL );
    glUseProgram( prog );

    GLuint vao = 0;
    glGenVertexArrays( 1, &vao );
    glBindVertexArray( vao );

    GLuint vbo0 = 0;
    glGenBuffers( 1, &vbo0 );
    glBindBuffer( GL_ARRAY_BUFFER, vbo0 );
    std::vector<float> data0 =
    {
        -0.5f, -0.5f,
         0.5f,  0.5f,
    };
    glBufferData( GL_ARRAY_BUFFER, data0.size() * sizeof( std::vector<float>::value_type ), data0.data(), GL_STATIC_DRAW );
    glVertexAttribPointer( 0 , 2, GL_FLOAT, GL_FALSE, 0, 0 );
    glEnableVertexAttribArray( 0 );

    GLuint vbo1 = 0;
    glGenBuffers( 1, &vbo1 );
    glBindBuffer( GL_ARRAY_BUFFER, vbo1 );
    std::vector<float> data1 =
    {
        0.0f, 1.0f,
    };
    glBufferData( GL_ARRAY_BUFFER, data1.size() * sizeof( std::vector<float>::value_type ), data1.data(), GL_STATIC_DRAW );
    glVertexAttribPointer( 1 , 1, GL_FLOAT, GL_FALSE, 0, 0 );
    glEnableVertexAttribArray( 1 );

    while( !glfwWindowShouldClose( window ) )
    {
        glfwPollEvents();

        int w, h;
        glfwGetFramebufferSize( window, &w, &h );
        glViewport( 0, 0, w, h );

        glClear( GL_COLOR_BUFFER_BIT );

        glUseProgram( prog );
        glBindVertexArray( vao );
        glDrawArrays( GL_LINES, 0, 2 );

        glfwSwapBuffers( window );
    }

    glfwDestroyWindow( window );
    glfwTerminate();
}
0
votes

Solved; The issue turned out to not be in the shader code, but in how the vertex attribute was defined att glVertexAttributePointer.