![](/img/trans.png)
[英]How to use QPainter and OpenGL with shaders in parallel with Qt5.9
[英]Issues with shaders in 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)上啟用緩沖區,我將被迫使用BOTH着色器的布局位置1?
您可以綁定另一個屬性位置,以便隨時向片段着色器發送顏色信息,但讓我告訴您另一個技巧:)
我使用2屬性位置,一個用於表示頂點的位置,另一個用於表示頂點的顏色。
glBindAttribLocation(program_, 0, "vs_in_pos");
glBindAttribLocation(program_, 1, "vs_in_col");
這是我的網格定義,其中Vertex包含兩個3D矢量:
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值設置3D矢量並設置為在片段着色器中使用它:
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);
}
你可以在這里看到我不僅發送世界矩陣,還發送顏色矢量。 片段着色器中的線性插值由mix()函數實現:
#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中到達的。
我希望你能理解我。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.