2016-07-04 35 views
1

OpenGL에서 다양한 유형의 GLSL 쉐이더를 머리로 감싸려고합니다. 현재 2D 레이어드 타일 구현에 어려움을 겪고 있습니다. 어떤 이유로 쉐이더에 전달되는 int 값은 항상 0 (또는 null 일 가능성이 높습니다)입니다.버텍스 쉐이더에 전달 된 값을 읽을 수 없습니다.

현재 2020 개의 타일로 구성된 2048x2048px 2d 텍스처가 있습니다. 나는 그것으로 한 쿼드를 텍스처링하려고하고 있으며, 버텍스 쉐이더에 전달한 int 블록을 기반으로 타일의 인덱스를 변경하려고합니다.

쿼드 (실제로는 TRIANGLE_STRIP)의 위치에 대해 float vec2를 전달합니다. 또한 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]이 정점 당 포함될 필요가있는 곳을 나타내지 않습니다.

내 레이아웃 (location = 1)에서 int Base [6]의 내용을 읽을 수 없습니다. 나는 내가 생각할 수있는 모든 것에 관해서 노력했다. 각각 두 개의 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

이 두 가지 방법으로 잘못 :

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

GL의 정점 속성은 스칼라 또는 2 - 4 구성 요소의 벡터가 될 수 있습니다. 따라서 매개 변수는 glVertexAttribPointer의 값을 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

감사합니다. 나는 그것을 처음 세 가지와 함께 사용하게했다. 따라서 6 개의 정수를 2 개의 ivec3으로 전달하려면 두 번째 ivec3에 대해 다른 vbo를 작성해야합니까? – RIanGillis

+0

@RIanGillis : \ * sigh \ * 내가 좋아하는 질문은 왜 버퍼 객체 생성과 정점 속성 지정 코드가 혼합되어있는 지경이다. 사용하는 버텍스 속성의 수는 그 속성이 제공하는 버퍼 객체의 수와 아무런 관련이 없습니다. 물론 하나의 속성이 여러 버퍼에서 올 수는 없습니다. 원하는 경우 모든 정점 데이터를 하나의 버퍼에 저장할 수 있습니다. –

+0

그래서 내가 대신 glVertexAttribPointer의 보폭과 오프셋을 조정하여 마지막 세 int를 건너 뛰고 동일한 데이터를 가리키는 다른 glVertexAttribPointer를 만들지 만 다른 오프셋을 사용하여 마지막 세 가지만 가져옵니다. 감사! – RIanGillis