Qt/OpenGL中的着色器问题
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)上启用缓冲区,我被迫使用两个着色器的布局位置1 ? 你可以绑定另一个属性位置来发送颜色信息到你的片段着色器,但让我告诉你另一个技巧:)
我使用了2个location属性,一个用来表示顶点的位置,另一个用来表示顶点的颜色。
glBindAttribLocation(program_, 0, "vs_in_pos");
glBindAttribLocation(program_, 1, "vs_in_col");
这是我的网格定义,其中顶点包含两个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中到达那里。
希望你能理解我。
顶点着色器和片段着色器的布局位置是独立的。QT可能会误导enableAttributeArray
,因为在OpenGL中这个函数被称为glEnableVertexAttribArray
- vertex是这里的关键字。所以你只能将每个顶点的数据传递到顶点着色器,然后使用in/out(插值)将其传递到片段着色器。
如果你想从片段着色器中使用多个输出,你必须使用位置和输出缓冲区。
这个链接应该也很有帮助,我稍后会总结。
相关文章:
- 在顶点着色器中使用 OpenGl 的未声明标识符,我在顶点着色器中绘制三角形时遇到问题
- 将旧管道转换为现代 openGL 时出现问题
- Qt OpenGL 渲染到纹理性能问题
- 我在 OpenGL 中显示图像时遇到问题
- OpenGL 相机移动程序顶点着色器问题
- Opengl问题:很可能是简单的纹理问题
- 从文件问题加载纹理 Android NDK 和 OpenGL
- 在OpenGL(GLM/C++)中使用四元数旋转时出现问题
- OpenGL中使用Freetype进行字体渲染的问题不起作用
- 如何在 Opengl 中使用多个纹理解决此问题
- 在 opengl 中翻译相机时遇到问题
- 使用 OpenGL .obj 法线时出现问题
- 圆形与方形碰撞检测以及需要响应C++ |OpenGL。我的问题就是这个"I need to keep the circle outside the square"
- opengl 飞行模拟器应用程序中的文本呈现问题
- OpenGL在Ortho和特点问题之间切换
- 绘制的 OpenGL 点消失,绘制调用和交换缓冲区问题
- 初始化多个纹理 OpenGL、SDL C++ 时出现问题
- 两个不同的对象 OpenGL.VAO VBO IBO 网格失真问题
- 显示素材问题(opengl)
- 聚光灯问题OpenGL