GLSL не примет мое неявное приведение

Я изучаю OpenGL 3.3, используя некоторые учебные пособия (http://opengl-tutorial.org). В учебнике, который я использую, есть вершинный шейдер, который делает следующее:

Исходный код учебного шейдера

#version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;

// Values that stay constant for the whole mesh.
uniform mat4 MVP;

void main(){

    // Output position of the vertex, in clip space : MVP * position
    gl_Position =  MVP * vec4(vertexPosition_modelspace,1);

}

Тем не менее, когда я пытаюсь эмулировать такое же поведение в своем приложении, я получаю следующее:

error: implicit cast from "vec4" to "vec3".

Увидев это, я не был уверен, что это было из-за того, что я использовал шейдеры версии 4.2, а не 3.3, поэтому изменил все, чтобы соответствовать тому, что использовал автор, но впоследствии все еще получал ту же ошибку.

Итак, я изменил свой шейдер, чтобы сделать это:

Мой (последний) источник

#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;

uniform mat4 MVP;

void main()
{
    vec4 a = vec4(vertexPosition_modelspace, 1);    

    gl_Position.xyz = MVP * a;
}

Который, конечно, по-прежнему выдает ту же ошибку.

Кто-нибудь знает, почему это так, а также какое решение может быть для этого? Я не уверен, что это может быть мой код вызова (который я разместил на всякий случай).


Код вызова

static const GLfloat T_VERTEX_BUF_DATA[] = 
{
    // x, y z
    -1.0f, -1.0f, 0.0f,
     1.0f, -1.0f, 0.0f,
     0.0f, 1.0f, 0.0f
};

static const GLushort T_ELEMENT_BUF_DATA[] = 
{ 0, 1, 2 };

void TriangleDemo::Run(void)
{
    glClear(GL_COLOR_BUFFER_BIT);

    GLuint matrixID = glGetUniformLocation(mProgramID, "MVP");

    glUseProgram(mProgramID);

    glUniformMatrix4fv(matrixID, 1, GL_FALSE, &mMVP[0][0]); // This sends our transformation to the MVP uniform matrix, in the currently bound vertex shader 

    const GLuint vertexShaderID = 0;

    glEnableVertexAttribArray(vertexShaderID);
    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
    glVertexAttribPointer(
        vertexShaderID, // Specify the ID of the shader to point to (in this case, the shader is built in to GL, which will just produce a white triangle)
        3,              // Specify the number of indices per vertex in the vertex buffer  
        GL_FLOAT,       // Type of value the vertex buffer is holding as data
        GL_FALSE,       // Normalized? 
        0,              // Amount of stride
        (void*)0 );     // Offset within the array buffer

    glDrawArrays(GL_TRIANGLES, 0, 3); //0 => start index of the buffer, 3 => number of vertices

    glDisableVertexAttribArray(vertexShaderID);
}

void TriangleDemo::Initialize(void)
{
    glGenVertexArrays(1, &mVertexArrayID);

    glBindVertexArray(mVertexArrayID);

    glGenBuffers(1, &mVertexBuffer);

    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);

    glBufferData(GL_ARRAY_BUFFER, sizeof(T_VERTEX_BUF_DATA), T_VERTEX_BUF_DATA, GL_STATIC_DRAW );

    mProgramID = LoadShaders("v_Triangle", "f_Triangle");

    glm::mat4 projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f); // field of view, aspect ratio (4:3), 0.1 units near, to 100 units far

    glm::mat4 view  = glm::lookAt(
                                glm::vec3(4, 3, 3), // Camera is at (4, 3, 3) in world space
                                glm::vec3(0, 0, 0), // and looks at the origin
                                glm::vec3(0, 1, 0)  // this is the up vector - the head of the camera is facing upwards. We'd use (0, -1, 0) to look upside down
                            );

    glm::mat4 model = glm::mat4(1.0f); // set model matrix to identity matrix, meaning the model will be at the origin

    mMVP            = projection * view * model;

}

Примечания

  • Я в Visual Studio 2012
  • Я использую Shader Maker для редактирования GLSL.

person zeboidlund    schedule 10.10.2012    source источник


Ответы (2)


Я не могу сказать, что не так с кодом учебника.

Однако в «Моем последнем источнике» есть

gl_Position.xyz = MVP * a;

что выглядит странно, потому что вы присваиваете vec4 vec3.


РЕДАКТИРОВАТЬ

Я не могу воспроизвести вашу проблему.

Я использовал тривиальный фрагментный шейдер для тестирования...

#version 330 core

void main()
{
}

Тестирование "Учебного источника шейдера":

3.3.11762 Core Profile Context
Log: Vertex shader was successfully compiled to run on hardware.

Log: Fragment shader was successfully compiled to run on hardware.

Log: Vertex shader(s) linked, fragment shader(s) linked.

Тестирование "Мой последний источник":

3.3.11762 Core Profile Context
Log: Vertex shader was successfully compiled to run on hardware.
 WARNING: 0:11: warning(#402) Implicit truncation of vector from size 4 to size 3.

Log: Fragment shader was successfully compiled to run on hardware.

Log: Vertex shader(s) linked, fragment shader(s) linked.

И предупреждение исчезает после замены gl_Position.xyz на gl_Position.


Какая у вас установка? У вас есть правильная версия контекста OpenGL? glGetError() молчит?

Наконец, обновлены ли ваши драйверы графического процессора?

person Kos    schedule 10.10.2012
comment
Ваше первое упоминание, вероятно, было основной причиной проблемы :) - person zeboidlund; 26.10.2013

У меня были проблемы с некоторыми графическими процессорами (я полагаю, ATi), которые не любили целочисленные литералы, когда ожидалось число с плавающей запятой. Попробуйте изменить

gl_Position =  MVP * vec4(vertexPosition_modelspace,1);

To

gl_Position =  MVP * vec4(vertexPosition_modelspace, 1.0);
person Jacob Parker    schedule 10.10.2012
comment
У меня было такое на OpenGL ES 2 (WebGL), но никогда на 3.3 Core. (у меня радеон) - person Kos; 11.10.2012