2015-10-04 227 views
1

如何在片段着色器中使用不同的顏色輸出?Qt/OpenGL着色器問題

說,我vshader看起來是這樣的:

#version 330 

uniform mat4 mvpmatrix; 

layout(location=0) in vec4 position; 
layout(location=1) in vec2 texcoord; 

out vec2 out_texcoord; 

void main() 
{ 

    gl_Position = mvpmatrix * position;  

    out_texcoord = texcoord; 
} 

// fshader

#version 330 

uniform sampler2D texture; 
in vec2 out_texcoord; 
out vec4 out_color; 
out vec4 out_color2; 

void main() 
{   
    out_color = texture2D(texture, out_texcoord); 
    // out_color2 = vec3(1.0, 1.0, 1.0, 1.0); 
} 

訪問他們像這樣:

m_program->enableAttributeArray(0); // position 
m_program->setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(Data)); 

m_program->enableAttributeArray(1); // texture 
m_program->setAttributeBuffer(1, GL_FLOAT, sizeof(QVector3D), 2, sizeof(Data)); 

到目前爲止,一切使用的默認輸出片段着色器,這是一個紋理。但是如何訪問不同的片段輸出?我也必須使用佈局嗎?而且,它可能是一個愚蠢的問題......但是vshader/fshader的佈局位置是相互綁定的嗎?所以,如果我在AttributeArray(1)上啓用我的緩衝區,我不得不使用兩個着色器的佈局位置1?

回答

2

可以綁定其他屬性位置的色彩信息發送到您的片段着色器的任何時間,但讓我告訴你一個訣竅:)

我用2屬性的位置,一個代表頂點和其他的位置一個來表示頂點的顏色。

glBindAttribLocation(program_, 0, "vs_in_pos"); 
glBindAttribLocation(program_, 1, "vs_in_col"); 

這是我網的定義,其中頂點包含兩個三維矢量:

Vertex vertices[] = { 
     {glm::vec3(-1, -1, 1), glm::vec3(1, 0, 0)}, 
     {glm::vec3(1, -1, 1), glm::vec3(1, 0, 0)}, 
     {glm::vec3(-1, 1, 1), glm::vec3(1, 0, 0)}, 
     {glm::vec3(1, 1, 1), glm::vec3(1, 0, 0)}, 
     {glm::vec3(-1, -1, -1), glm::vec3(0, 1, 0)}, 
     {glm::vec3(1, -1, -1), glm::vec3(0, 1, 0)}, 
     {glm::vec3(-1, 1, -1), glm::vec3(0, 1, 0)}, 
     {glm::vec3(1, 1, -1), glm::vec3(0, 1, 0)}, 
    }; 
    GLushort indices[] = { 
     // Front 
     0, 1, 2, 2, 1, 3, 
     // Back 
     4, 6, 5, 6, 7, 5, 
     // Top 
     2, 3, 7, 2, 7, 6, 
     // Bottom 
     0, 5, 1, 0, 4, 5, 
     // Left 
     0, 2, 4, 4, 2, 6, 
     // Right 
     1, 5, 3, 5, 7, 3 
    }; 

這將是一個立方體。我會將這個預定義的顏色與計算值混合使用。這意味着立方體的顏色會因其位置而改變。設置爲RGB值的三維矢量和設置使用它在片段着色器:

loc_col_ = glGetUniformLocation(program_, "color"); 

現在在我的渲染功能,我把立方體在2D圈,移動它們,使它們旋轉:

for (int i = 0; i < num_of_cubes_; ++i) { 
     double fi = 2 * PI * (i/(double) num_of_cubes_); 
     glm::mat4 position = glm::translate<float>(cubes_radius_ * cos(fi), cubes_radius_ * sin(fi), 0); 
     glm::mat4 crackle = glm::translate<float>(0, 0.1 * (sin(2 * PI * (SDL_GetTicks()/500.0) + i)), 0); 
     glm::mat4 rotate = glm::rotate<float>(360 * (SDL_GetTicks()/16000.0), 0, 0, 1); 
     world_ = position * crackle * rotate; 
     glm::vec3 color = glm::vec3((1 + cos(fi)) * 0.5, (1 + sin(fi)) * 0.5, 1 - ((1 + cos(fi)) * 0.5)); 
     glUniformMatrix4fv(loc_world_, 1, GL_FALSE, &(world_[0][0])); 
     glUniform3fv(loc_col_, 1, &(color[0])); 
     glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0); 
    } 

你可以在這裏看到我不僅發送世界矩陣,還發送顏色矢量。在片段着色器 線性插補是通過混合()函數achived:

#version 130 

in vec3 vs_out_col; 
in vec3 vs_out_pos; 
out vec4 fs_out_col; 

uniform vec3 color; 

void main() { 
     fs_out_col = vec4(mix(color, vs_out_col, 0.5), 1); 
} 

顏色是在所傳遞的值呈現而vs_out_col從將其在「信道」 1

到達那裏的頂點着色器來

我希望你能理解我。

+0

Okey ...我已經過了,感謝分享! – danksch

1

頂點和片段着色器上的佈局位置是獨立的。 QT可能會誤導enableAttributeArray,因爲在OpenGL中,此函數被稱爲glEnableVertexAttribArray - 頂點是此處的關鍵字。因此,您可以將每個頂點數據僅傳遞到頂點着色器,然後使用輸入/輸出(插值)將其傳遞到片段着色器中。

如果你想使用片段着色器的多個輸出,你必須使用位置和Output buffers

This鏈接也應該是有幫助的,我會在稍後總結。

+0

好的,謝謝你的提示! – danksch