如何解决使用着色器GLEW绘制多个对象
我想使用三角形风扇绘制不同的图形,但是我不确定如何使程序绘制第二个图形。每当我想要更改颜色或绘制新图形时,是否需要第二个vertexShaderSource和第二个fragmentShaderSource?
代码如下:
#include <GL/glew.h>
#include <GL/glut.h>
#include <stdio.h>
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x,aPos.y,aPos.z,1.0);\n"
"}\0";
const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n""void main()\n"
"{\n"
" FragColor = vec4(1.0f,0.0f,0.0f);\n" // To set the color.
"}\n\0";
// Set of vertices for the different figures that make up the drawing.
float vertices[] = {
-0.8f,0.6f,// Center.
-0.8f,0.4f,-0.83f,0.44f,-0.87f,0.51f,-0.9f,0.57f,-0.93f,0.63f,-0.95f,0.69f,-0.97f,0.75f,-0.98f,0.8f,-0.91f,-0.85f,0.79f,-0.8f,0.77f,};
unsigned int VBO,VAO;
gluint vertexShader;
gluint fragmentShader;
gluint shaderProgram;
void display(void){
// Background color.
glClearColor(1.0f,1.0f,0.0f);
glClear(GL_COLOR_BUFFER_BIT);
gluseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLE_FAN,12);
glBindVertexArray(0);
glFlush();
}
// Main.
int main(int argc,char** argv){
glutinit(&argc,argv);
// Color mode.
glutinitdisplayMode(gluT_RGBA);
// Window size.
glutinitwindowSize(500,500);
// Title.
glutCreateWindow("Tarea 3: figura con curvas");
GLenum err = glewInit();
if(err!=GLEW_OK) {
printf("glewInit Failed: %s",glewGetErrorString(err));
exit(1);
}
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader,1,&vertexShaderSource,NULL);
glCompileShader(vertexShader);
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader,&fragmentShaderSource,NULL);
glCompileShader(fragmentShader);
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram,vertexShader);
glAttachShader(shaderProgram,fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glGenVertexArrays(1,&VAO);
glGenBuffers(1,&VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER,VBO);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3 * sizeof(float),(void*)0);
glEnabLevertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);
glutdisplayFunc(display);
glutMainLoop();
}
解决方法
不需要(或不建议)为网格使用不同的着色器。如果要绘制多个对象,则可以将网格的顶点属性放在单独的Vertex Buffer Object s中:
GLuint VBOs[2];
glGenBuffers(2,VBOs);
glBindBuffer(GL_ARRAY_BUFFER,VBOs[0]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices_1,GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,VBOs[1]);
glBufferData(GL_ARRAY_BUFFER,vertices_2,GL_STATIC_DRAW);
为每个网格指定一个Vertex Array Object:
GLuint VAOs[2];
glGenVertexArrays(2,VAOs);
glBindVertexArray(VAOs[0]);
glBindBuffer(GL_ARRAY_BUFFER,VBOs[0]);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3 * sizeof(float),(void*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(VAOs[1]);
glBindBuffer(GL_ARRAY_BUFFER,VBOs[1]);
glVertexAttribPointer(0,(void*)0);
glEnableVertexAttribArray(0);
在抽奖之前绑定VAO:
glBindVertexArray(VAOs[0]);
glDrawArrays(GL_TRIANGLE_FAN,12);
glBindVertexArray(VAOs[1]);
glDrawArrays(...);
当然,也可以将不同网格的所有顶点属性连续放在一个VBO的数据存储中。如果顶点规范相同,则可以使用一个VAO。
可以通过顶点着色器中的顶点变换来实现不同网格的不同位置。使用mat4
类型的Uniform 来转换网格的顶点:
#version 330 core
layout (location = 0) in vec3 aPos;
uniform mat4 u_model;
void main()
{
gl_Position = u_model * vec4(aPos.xyz,1.0);
}
进一步查看LearnOpenGL - Transformations。
如果两个图形相同,但是位置不同,则可以绘制两次相同的网格,但是必须更改模型转换u_model
。
您正在寻找Uniform buffer objects。
如果整个绘制调用只有一个值,则应该对着色器进行参数设置。首先要进行参数化的显而易见的事情是片段着色器中的颜色,然后在顶点着色器中添加投影矩阵。
从那时起,只要是同一3D模型,就可以在将新值设置为制服和绘制调用之间交替进行。
对于不同的型号,请参考@ rabbid76的答案。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。