Странное поведение OpenGL/glGetUniformLocation()

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

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

#version 420 core

layout(location = 0) in vec2 p_rect;
layout(location = 1) in vec2 p_clipRect;

out vec2 texturePoint;

void main()
{
    gl_Position = vec4( p_rect, 0.0, 1.0 );
    texturePoint = p_clipRect;
}

Фрагментный шейдер:

#version 420 core

uniform sampler2D p_texture;

in vec2 texturePoint;

out vec4 outColor;

void main()
{
    outColor = texture( p_texture, texturePoint );
}

Код OpenGL:

glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, texture );
GLint texture_id( glGetUniformLocation( programId, "p_texture" ) );
glUniform1i( texture_id, texture );

// Element
static const GLushort element[] = { 0, 1, 2, 3 };
GLuint element_id;
glGenBuffers( 1, &element_id );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, element_id );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( element ), element, GL_STATIC_DRAW );

// Vertex data
struct VertexInput
{
    GLfloat m_rect[ 8 ];
    GLfloat m_clipRect[ 8 ];
}
vertex;

// fill it up with data
GLfloat vertex_data[] =
{
    -1.0f, -1.0f,
    -1.0f,  1.0f,
    1.0f, -1.0f,
    1.0f,  1.0f,
    0.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 0.0f,
    1.0f, 1.0f,
};

memcpy( &vertex, &vertex_data, sizeof( vertex_data ) );

// VBO
GLuint vertex_id;
glGenBuffers( 1, &vertex_id );
glBindBuffer( GL_ARRAY_BUFFER, vertex_id );
glBufferData( GL_ARRAY_BUFFER, sizeof(vertex), &vertex, GL_STATIC_DRAW );

glEnableVertexAttribArray( 0 );
glEnableVertexAttribArray( 1 );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_TRUE, 0, (void*)offsetof( VertexInput, m_rect ) );
glVertexAttribPointer( 1, 2, GL_FLOAT, GL_TRUE, 0, (void*)offsetof( VertexInput, m_clipRect ) );

// render the VBO
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, element_id );
glDrawElements( GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, (void*)0 );

// clean it up ;-)
glDisableVertexAttribArray( 0 );
glDisableVertexAttribArray( 1 );

Странная вещь:

Случай 1: если programId является фактическим идентификатором программы, я получаю texture_id = 0, но шейдер не получает никакой информации... ничего не происходит...

Случай 2: если programId не является фактическим идентификатором программы, я получаю texture_id = -1, но мой код ВИДИТ изображение идеально (ИЗНОС).

Дело в том, что... Я знаю, что это все еще неправильно. Мне нужно иметь возможность дать информацию шейдеру, а затем отрендерить... Я действительно не знаю, как работает случай 2, но дело в том, что мне нужно дать больше информации шейдерам, как и другие текстуры, MVP матрица и так сын. Я не могу этого сделать. Что не так? Как указать правильное значение идентификатора моей программы и получить эту информацию в шейдере?


person Wagner Patriota    schedule 29.01.2013    source источник


Ответы (1)


glActiveTexture( GL_TEXTURE0 );
...
glUniform1i( texture_id, texture );

Попробуйте это вместо этого:

glActiveTexture( GL_TEXTURE0 + 0 );
...
glUniform1i( texture_id, 0 );

Униформам сэмплера должен быть присвоен индекс желаемого текстурного модуля, а не идентификатор объекта текстуры.

person genpfault    schedule 29.01.2013
comment
юниформы сэмплера принимают номер блока текстуры, а не токен блока текстуры: glActiveTexture(GL_TEXTURE0 + n); glUniform(…, n); - person datenwolf; 30.01.2013
comment
Идеальный! некоторые тонкие детали мы опустили... большое спасибо! теперь это работает! - person Wagner Patriota; 30.01.2013
comment
@Wagner: Если это работает, вы должны принять его ответ, используя зеленую галочку слева. - person Nicol Bolas; 30.01.2013