Интерполяция атрибута вершины - PullRequest
0 голосов
/ 15 ноября 2018

Я пытаюсь передать расстояние как атрибут вершины из моего кода на С ++ в шейдер, который рисует линию между двумя вершинами.

В настоящее время одна линия имеет расстояние 0 (начало), а другая - расстояние 1,0. Я ожидал бы, что это значение будет интерполировано так же, как цвета, но, похоже, оно не работает. Таким образом, я ожидаю, что половина линии будет красной, а другая - зеленой, но вся линия окажется зеленой.

Фрагмент кода шейдера ниже, где dist в вершинном шейдере берется из расположения (location = 2) в float in_dist и передается как out float dist (никаких операций не выполняется).

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;
}

Вершинный шейдер

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 ]

0 голосов
/ 16 ноября 2018

решаемые; Проблема оказалась не в коде шейдера, а в том, как был определен атрибут вершины att glVertexAttributePointer.

0 голосов
/ 15 ноября 2018

Здесь все в порядке:

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();
}
...