2014-12-11 76 views
0

我似乎無法得到這個OpenGL程序來渲染一個四合一後,我添加一個VAO。OpenGL 3.3 2D渲染:VAO配置不正確?

假設程序正確初始化沒有錯誤,以下是填充VAO的代碼。

float quad[] = 
    { 
     //verts  colors 
     32.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Top-left 
     32.0f, 32.0f, 0.0f, 1.0f, 0.0f, // Top-right 
     0.0f, 32.0f, 0.0f, 0.0f, 1.0f, // Bottom-right 
     0.0f, 0.0f, 1.0f, 1.0f, 1.0f // Bottom-left 
    }; 

float textureCoords[] = 
    { 
     0.0f, 0.0f, //x 
     0.5f, 0.0f, //w 
     0.5f, 0.5f, //y 
     0.0f, 0.5f //h 
    }; 

float elements[] = 
    { 
     0,1,2, 
     2,3,0 
    }; 

//loadShaders compiles and links both shaders 
GLuint shaders = loadShaders("vertexShader.c", "fragmentShader.c"); 
GLuint VAO, VBO[2], EBO; 


glGenVertexArrays(1, &VAO); 

glGenBuffers(2, VBO); 
glGenBuffers(1, &EBO); 

//bind VAO 
glBindVertexArray(VAO); 

glUseProgram(shaders); 

//quad and color data 
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]); 
glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW); 
GLint quadAttrib = glGetAttribLocation(shaders, "quad"); 
glEnableVertexAttribArray(quadAttrib);//target 'quad' in shader 
glVertexAttribPointer(quadAttrib, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0); 
//color data 
GLint colorAttrib = glGetAttribLocation(shaders, "color"); 
glEnableVertexAttribArray(colorAttrib);//target 'color' in shader 
glVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat))); 

//UV data 
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]); 
glBufferData(GL_ARRAY_BUFFER, sizeof(textureCoords), textureCoords, GL_STATIC_DRAW); 
GLint uvAttrib = glGetAttribLocation(shaders, "uvCoords");//target 'uvCoords' in shaders 
glEnableVertexAttribArray(uvAttrib); 
glVertexAttribPointer(uvAttrib, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0); 


//TEXTURES 
//laod and use textures 
GLuint textures[2]; 
glGenTextures(2, textures); 


int texWidth, texHeigth; 
unsigned char *image; 

//activate texture 0 
glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, textures[0]); 
image = SOIL_load_image("atlas.png", &texWidth, &texHeigth, 0, SOIL_LOAD_RGB); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texWidth, texHeigth, 0, GL_RGB, GL_UNSIGNED_BYTE, image); 
SOIL_free_image_data(image); 
glUniform1i(glGetUniformLocation(shaders, "img1"), 0); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 


//element buffer data 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW); 

//UNIFORMS 

//projection matrix 
GLint projectionUniform = glGetUniformLocation(shaders, "projection"); 
glm::mat4 orthoProjection = glm::ortho(0.0f, static_cast<float>(480), 0.0f, static_cast<float>(272)); 
glUniformMatrix4fv(projectionUniform, 1, GL_FALSE, glm::value_ptr(orthoProjection)); 
//model view projection 
GLint modelViewUniform = glGetUniformLocation(shaders, "modelView"); 


//unbind VAO and current shader, the VAO remembers the bound shader 
glBindVertexArray(0); 
glUseProgram(0); 

我假定的VAO現已保持軌道的以下內容:

  • 的四緩衝器「VBO [0]」和其對應的attribPointer「quadAttrib」在「四」着色器
  • 顏色緩衝器 '相同VBO [0]' 和在着色器及其相應的attribPointer 'colorAttrib' 到 '顏色'
  • 的UV緩衝器 'VBO [1]' 和其對應的attribPointer 'uvAttrib' 到 'uvCoords'着色器
  • 即當前的紋理單元(0)對應於加載質地和結合在片段着色器「IMG1」以及其參數
  • 的EBO其爲界GL_ELEMENT_ARRAY_BUFFER
  • 投影矩陣和其均勻
  • 模型矩陣的處理程序
  • VAO綁定時正在使用的着色器程序?不知道,我還是明確的程序

在主迴路後來使用的唯一着色器程序,如果我嘗試以下,沒有獲取得出:

// Clear the screen to black 
    glClearColor(0.2f, 0.0f, 0.0f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT); 

    //draw the quad within this VAO 
    glBindVertexArray(VAO); 
glUseProgram(shaders); 

    glm::mat4 model; 

    model = glm::translate(glm::mat4(1.0f), glm::vec3(newTransX, newTransY, newTransZ)); 
    model = glm::scale(model, glm::vec3(newScale)); 

    model = glm::rotate(
     model, 
     (GLfloat)clock()/(GLfloat)CLOCKS_PER_SEC * 10000.0f, 
     glm::vec3(0.0f, 0.0f, 1.0f) 
    );  

// upload the uniform matrix, modelViewUniform should be already linked to the shader uniform through the VAO 

    glUniformMatrix4fv(modelViewUniform, 1, GL_FALSE, glm::value_ptr(model)); 


    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 

    glBindVertexArray(0); 

    SDL_GL_SwapWindow(window); 

頂點着色器:

#version 330 

in vec2 quad; 
in vec3 color; 
in vec2 uvCoords; 

out vec3 Color; 
out vec2 UVCoords; 


uniform mat4 modelView; 
uniform mat4 projection; 

void main() 
{ 
    Color = color; 
    UVCoords = uvCoords; 

    gl_Position = projection * modelView * vec4(quad, 0.0f, 1.0f); 
} 

片段着色器:

#version 330 

in vec3 Color;//not in use, simple pipeline test 
in vec2 UVCoords; 

out vec4 outColor; 

uniform sampler2D img1; 


void main() 
{ 
    vec4 finalTexture = texture(img1, UVCoords); 
    outColor = finalTexture; 
} 

上午什麼我做錯了?我知道模型視圖和投影矩陣中的值是正確的,因爲程序的工作原理如果我從不使用VAO。

我是否假設VAO記得比實際記錄的更多?如果不是,我做錯了什麼?

+0

這是一個很大的假設。你是否用'glGetError(void)'檢查錯誤狀態?由於你的程序無法在VAO上運行,你是否在創建和綁定時檢查了錯誤? – Freddy 2014-12-11 05:33:49

+0

顯然,OpenGL在優化「顏色」屬性是因爲它沒有在着色器中使用,而且它沒有正確的綁定。即使我更改要使用的顏色,問題仍然存在。它沒有畫任何東西。 – 2014-12-11 06:00:05

回答

1

這不可能是正確的:

float elements[] = 
{ 
    0,1,2, 
    2,3,0 
}; 

不能使用浮動頂點指數。基於傳遞給glDrawElements()類型,這應該是:

GLuint elements[] = 
{ 
    0,1,2, 
    2,3,0 
}; 

至於在VAO跟蹤的狀態:不,它不會堅持到所有的狀態。它只跟蹤頂點屬性設置狀態。從你的清單:

的四緩衝器 'VBO [0]',其着色器

是相應attribPointer 'quadAttrib' 到 「四」。更確切地說,VBO /指針與位置quadAttrib相關聯,並且該關聯在VAO中被跟蹤。您從着色器查詢quadAttrib,但VAO狀態不包含與着色器的任何直接關聯。

顏色緩衝器 '相同VBO [0]' 和在着色器

同樣在這裏其相應attribPointer 'colorAttrib' 到 '顏色'。

的UV緩衝器 'VBO [1]' 和在着色器

在這裏其相應attribPointer 'uvAttrib' 到 'uvCoords'。

即當前的紋理單元(0)對應於加載質地和結合在片段着色器「IMG1」以及其參數

號即無關與頂點屬性狀態。

是爲界,GL_ELEMENT_ARRAY_BUFFER

是的EBO。

投影矩陣和其均勻

號均勻值是程序狀態的一部分。

的處理程序模型矩陣

那是在使用,而VAO是必然的着色器程序?

+0

謝謝,你的確是對的。但是這是否意味着我必須在渲染之前重新綁定VAO之後重新綁定製服和紋理? – 2014-12-11 20:00:55