1

私はOpenGLのさまざまなタイプのGLSLシェーダを頭で囲んでいます。 現時点では、2d階層化タイルの実装に苦労しています。何らかの理由で、シェーダに渡されるint値は常に0(またはnullの可能性が高い)です。頂点シェーダに渡された値を読み取ることができません

私は現在20x20タイルで構成される2048x2048px 2dテクスチャを持っています。私はそれで1クワッドをテクスチャしようとしており、頂点シェーダに渡すintのブロックに基づいてタイルのインデックスを変更しようとしています。

私は、クワッドの位置(実際にはTRIANGLE_STRIP)のvec2を渡しています。私はまた、タイルの6つのレイヤーを表す6 intsを渡そうとしています。

マイ入力:

// 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]が頂点ごとに含まれる必要があることを示すものではないということです。

私のレイアウト(location = 1)からint Base [6]で何も読み取ることができません。私は考えることができるすべてについて試しました。宣言は、それぞれ2つのivec3年代、UINT、これまで他に何私は考えることができを読み取ろうとする、個別にint型以外のすべては、以下の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)); 
} 

答えて

3

これは、2つの異なる方法で間違っている:

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スロットのみを消費する)のようないくつかのベクトルにパックします。あなたが選んだパッキングに関係なく、使用中の属性スロットごとに適切な属性ポインタ設定が必要です。

しかし、glVertexAttribPointerも、あなたのユースケースでは間違った機能です。 浮動小数点属性を定義しています。一致する宣言はシェーダー内でfloat/vec*とする必要があります。 GL_INTを入力できるということは、GPUが浮動小数点への変換を実行できることを意味します。

あなたがintまたはivec(またはその符号なし対応)を使用する場合は、属性の属性を設定するとき、あなたは(その関数名にIに注意してください)glVertexAttribIPointerを使用する必要があります。

+0

ありがとうございます!私はそれを最初の3つと一緒に働かせました。だから、2つのivec3として6つのintを渡したいのであれば、2番目のivec3のために別のvboを作らなければならないでしょうか? – RIanGillis

+0

@RIanGillis:\ * sigh \ *あなたのような質問は、バッファオブジェクトの作成と頂点属性指定コードが混在しているため、私は軽視する*チュートリアルです。使用する頂点属性の数には、その属性が由来するバッファオブジェクトの数とは何も関係ありません(もちろん、1つの属性が複数のバッファから来ることはできません)。必要に応じて、すべての頂点データを1つのバッファに入れることができます。 –

+0

それでは、glVertexAttribPointerのストライドとオフセットを調整して、最後の3つのintをスキップし、別のglVertexAttribPointerを作成して同じデータを指すが、別のオフセットを使用して最後の3つだけをピックアップする必要があるということです。ありがとう! – RIanGillis

関連する問題