簡體   English   中英

無法讀取傳遞到頂點着色器的值

[英]Cannot Read Values Passed to Vertex Shader

我試圖在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 ));
}

這有兩種不同的錯誤:

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

GL中的頂點屬性可以是標量或2到4個組件的向量。 因此, glVertexAttribPointersize參數可以取值1,2,3或4.使用不同的值( intsPerTriangle == 6 )意味着調用只會生成GL_INVALID_VALUE錯誤並且沒有效果,所以你不要甚至設置指針。

如果要為每個頂點傳遞6個值,可以使用6個不同的scalr屬性(使用6個屬性槽),或將其打包到某些向量中,例如2個3d向量(僅消耗2個槽)。 無論您選擇何種包裝,您都需要為使用中的每個屬性槽設置適當的attrib指針。

但是, glVertexAttribPointer對於您的用例也是錯誤的功能。 它定義了浮點屬性,它必須在着色器中將聲明匹配為float / vec* 您可以輸入GL_INT這一事實意味着GPU可以為您實時轉換為浮點數。

如果要使用intivec (或其無符號對應物)屬性,則必須在設置屬性時使用glVertexAttribIPointer (注意該函數名稱中的I )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM