无法读取传递到顶点着色器的值

时间:2016-07-04 20:07:38

标签: c++ opengl vertex-shader vertex-buffer vertex-array-object

我试图在OpenGL中围绕各种类型的GLSL着色器。 目前,我正在努力实现2d分层磁贴实现。由于某种原因,传递到我的着色器的int值始终为0(或更可能为null)。

我目前有2048x2048px的2d纹理,由20x20的瓷砖组成。我试图用它纹理一个四边形并根据我传入顶点着色器的整数块来改变图块的索引。

我正在通过vec2的浮点数来获取四边形的位置(实际上是一个TRIANGLE_STRIP)。我也试图传递6个代表6层瓷砖的整数。

我的意见:

// Build and compile our shader program
Shader ourShader("b_vertex.vertexShader", "b_fragment.fragmentShader");

const int floatsPerPosition = 2;
const int intsPerTriangle = 6;
const int numVertices = 4;
const int sizeOfPositions = sizeof(float) * numVertices * floatsPerPosition;
const int sizeOfColors = sizeof(int) * numVertices * intsPerTriangle;
const int numIndices = 4;
const int sizeOfIndices = sizeof(int) * numIndices;

float positions[numVertices][floatsPerPosition] =
{
    { -1, 1 },
    { -1, -1 },
    { 1, 1 },
    { 1, -1 },
};

// ints indicating Tile Index
int colors[numVertices][intsPerTriangle] =
{
    { 1, 2, 3, 4, 5, 6 },
    { 1, 2, 3, 4, 5, 6 },
    { 1, 2, 3, 4, 5, 6 },
    { 1, 2, 3, 4, 5, 6 },
};

// Indexes on CPU
int indices[numVertices] =
{
    0, 1, 2, 3,
}; 

我的设置:

GLuint vao, vbo1, vbo2, ebo; // Identifiers of OpenGL objects

glGenVertexArrays(1, &vao); // Create new VAO
                            // Binded VAO will store connections between VBOs and attributes
glBindVertexArray(vao);

glGenBuffers(1, &vbo1); // Create new VBO
glBindBuffer(GL_ARRAY_BUFFER, vbo1); // Bind vbo1 as current vertex buffer
                                     // initialize vertex buffer, allocate memory, fill it with data
glBufferData(GL_ARRAY_BUFFER, sizeOfPositions, positions, GL_STATIC_DRAW);
// indicate that current VBO should be used with vertex attribute with index 0
glEnableVertexAttribArray(0);
// indicate how vertex attribute 0 should interpret data in connected VBO
glVertexAttribPointer(0, floatsPerPosition, GL_FLOAT, GL_FALSE, 0, 0);

glGenBuffers(1, &vbo2); // Create new VBO
glBindBuffer(GL_ARRAY_BUFFER, vbo2); // Bind vbo2 as current vertex buffer
                                     // initialize vertex buffer, allocate memory, fill it with data
glBufferData(GL_ARRAY_BUFFER, sizeOfColors, colors, GL_STATIC_DRAW);
// indicate that current VBO should be used with vertex attribute with index 1
glEnableVertexAttribArray(1);
// indicate how vertex attribute 1 should interpret data in connected VBO
glVertexAttribPointer(1, intsPerTriangle, GL_INT, GL_FALSE, 0, 0);

// Create new buffer that will be used to store indices
glGenBuffers(1, &ebo);
// Bind index buffer to corresponding target
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
// ititialize index buffer, allocate memory, fill it with data
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeOfIndices, indices, GL_STATIC_DRAW);

// reset bindings for VAO, VBO and EBO
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);



// Load and create a texture 
GLuint texture1 = loadBMP_custom("uvtemplate3.bmp");

GLuint texture2 = loadBMP_custom("texture1.bmp");

我的抽奖:

// Game loop
while (!glfwWindowShouldClose(window))
{
    // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions
    glfwPollEvents();

    // Render
    // Clear the colorbuffer
    glClearColor(1.f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // Activate shader
    ourShader.Use();

    // Bind Textures using texture units
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture1);

    //add some cool params
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
    float borderColor[] = { 0.45f, 0.25f, 0.25f, 0.25f };
    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);

    glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture1"), 0);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, texture2);
    glUniform1i(glGetUniformLocation(ourShader.Program, "ourTexture2"), 1);

    // Draw container
    //glBindVertexArray(VAO);
    //glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    glBindVertexArray(vao);
    //glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    glDrawElements(GL_TRIANGLE_STRIP, numIndices, GL_UNSIGNED_INT, NULL);

    glBindVertexArray(0);

    // Swap the screen buffers
    glfwSwapBuffers(window);
}

我的着色器绝对有效,因为我可以通过硬编码来调整输出 vertexShader中的值。我的怀疑是我没有正确地传递值/正确的格式或者没有指出每个顶点需要包含int [6]的地方。

我无法从int Base [6]中的布局(location = 1)中读取任何内容;我已经尝试过我能想到的一切。单独声明每个int,尝试阅读两个ivec3,uint以及我能想到的其他内容,但是所有内容都返回0。

以下是我的顶点和片段着色器的完整性:

#version 330 core
layout (location = 0) in vec2 position;
layout (location = 1) in int Base[6];

out vec2 TexCoord;
out vec2 TexCoord2;
out vec2 TexCoord3;
out vec2 TexCoord4;
out vec2 TexCoord5;
out vec2 TexCoord6;

//  0.5f,  0.5f,// 0.0f,   118.0f, 0.0f, 0.0f,   0.0f, 0.0f, // Top Right
//  0.5f, -0.5f,// 0.0f,   118.0f, 1.0f, 0.0f,   0.0f,0.009765625f, // Bottom Right
//  -0.5f, -0.5f,// 0.0f,   118.0f, 0.0f, 1.0f,   0.009765625f, 0.009765625f, // Bottom Left
//  -0.5f,  0.5f//, 0.0f,   118.0f, 1.0f, 0.0f,   0.009765625f, 0.0f  // Top Left 

void main()
{

int curBase = Base[5];

int curVertex = gl_VertexID % 4;
vec2 texCoord = (curVertex == 0?
vec2(0.0,0.0):(
curVertex == 1?
vec2(0.0,0.009765625):(
curVertex == 2?
vec2(0.009765625,0.0):(
curVertex == 3?
vec2(0.009765625,0.009765625):(
vec2(0.0,0.0)))))
);
gl_Position = vec4(position, 0.0f, 1.0f);

TexCoord = vec2(texCoord.x + ((int(curBase)%102)*0.009765625f)
, (1.0 - texCoord.y) - ((int(curBase)/102)*0.009765625f));
//curBase = Base+1;
TexCoord2 = vec2(texCoord.x + ((int(curBase)%102)*0.009765625f)
, (1.0 - texCoord.y) - ((int(curBase)/102)*0.009765625f));
//curBase = Base+2;
TexCoord3 = vec2(texCoord.x + ((int(curBase)%102)*0.009765625f)
, (1.0 - texCoord.y) - ((int(curBase)/102)*0.009765625f));
}

片段:

#version 330 core
//in vec3 ourColor;
in vec2 TexCoord;
in vec2 TexCoord2;
in vec2 TexCoord3;
in vec2 TexCoord4;
in vec2 TexCoord5;
in vec2 TexCoord6;

out vec4 color;

// Texture samplers
uniform sampler2D ourTexture1;
uniform sampler2D ourTexture2;

void main()
{
color = (texture(ourTexture2, TexCoord )== vec4(1.0,0.0,1.0,1.0)?
(texture(ourTexture2, TexCoord2 )== vec4(1.0,0.0,1.0,1.0)?
(texture(ourTexture2, TexCoord3 )== vec4(1.0,0.0,1.0,1.0)?
(texture(ourTexture2, TexCoord4 )== vec4(1.0,0.0,1.0,1.0)?
(texture(ourTexture2, TexCoord5 )== vec4(1.0,0.0,1.0,1.0)?
(texture(ourTexture2, TexCoord6 )== vec4(1.0,0.0,1.0,1.0)?
    vec4(0.0f,0.0f,0.0f,0.0f)
:texture(ourTexture2, TexCoord6 ))
:texture(ourTexture2, TexCoord5 ))
:texture(ourTexture2, TexCoord4 ))
:texture(ourTexture2, TexCoord3 ))
:texture(ourTexture2, TexCoord2 ))
:texture(ourTexture2, TexCoord ));
}

1 个答案:

答案 0 :(得分:3)

这有两种不同的方式:

glVertexAttribPointer(1, intsPerTriangle, GL_INT, GL_FALSE, 0, 0);

GL中的顶点属性可以是标量或2到4个组件的向量。因此,size的{​​{1}}参数可以取值1,2,3或4.使用不同的值(glVertexAttribPointer)意味着调用只会生成{{1错误并且没有效果,所以你甚至不设置指针。

如果你想为每个顶点传递6个值,你可以使用6个不同的scalr属性(消耗6个属性槽),或者将它打包成一些向量,比如2个3d向量(仅消耗2个槽)。无论您选择哪种包装,您都需要为使用中的每个属性槽设置适当的attrib指针。

但是,intsPerTriangle == 6对于您的用例也是错误的功能。它定义了浮点属性,它们必须在着色器中将声明与GL_INVALID_VALUE / glVertexAttribPointer匹配。您可以输入float这一事实意味着GPU可以为您实时转换为浮点数。

如果您想使用vec*GL_INT(或其未签名的对应物)属性,则必须使用glVertexAttribIPointer(请注意 I 功能名称)设置属性时。