通过顶点属性指针将颜色坐标传递到顶点着色器
Passing colour coords into a vertex shader through a vertex attrib pointer
我正在尝试将 vec3 颜色数据获取到顶点着色器(作为属性指针),然后将其传递到片段中以进行所有设置。
一切都是从无法将纹理坐标传递到顶点着色器开始的。我到处都看过,但找不到明确的解决方案。我可以(通过在顶点着色器中手动设置颜色),得到一个白色方块到渲染器,但是来自 VAO 的颜色数据似乎无法传递给它。
另外我确定着色器加载系统可以正常工作。我最好的想法是信息没有传递给顶点着色器的 'layout = 1',但我很可能是错的。
VAO/缓冲区/着色器设置
float vert[] = {
//Vert Locs Normal Coords
-0.5f,-0.5f, 1.0f,1.0f,1.0f, //0
0.5f,-0.5f, 1.0f,1.0f,1.0f, //1
0.5f,0.5f, 1.0f,1.0f,1.0f, //2
-0.5f, 0.5f, 1.0f,1.0f,1.0f, //3
};
unsigned int index[] = {
0,1,2, //Order of drawing vertices
2,3,0
};
unsigned int vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
unsigned int buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 5 * 4 * sizeof(float), vert, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT,GL_FALSE, 5 * sizeof(float), 0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float)));
glEnableVertexAttribArray(0); // vao ^^
unsigned int ibo;
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), index, GL_STATIC_DRAW);
Shader v("VertexN.shader", GL_VERTEX_SHADER);
Shader f("FragmentN.shader", GL_FRAGMENT_SHADER);
unsigned int shaders2[] = {v.id, f.id};
unsigned int program2 = Shader::getProgram(shaders2);
glUseProgram(0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
渲染循环
glClearColor(0, 0, 0, 1);
/* Render here */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glUseProgram(program2);
//tex.bind(slot);
glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); //Drawing mode, Type indecies , type of index buffer , pointer to index buffer
glfwSwapBuffers(window);
glfwPollEvents();
glFlush();
glBindVertexArray(0);
glUseProgram(0);
glActiveTexture(0);
顶点着色器
#version 330 core
layout(location = 0)in vec2 pos;
layout(location = 1)in vec3 normals;
out vec3 normal;
void main() {
normal = normals;
gl_Position = vec4(pos, 0.0f, 1.0f);
};
片段着色器
#version 330 core
layout(location = 0)out vec4 colour;
in vec3 normal;
void main() {
colour = vec4(normal, 1.0f);
};
我不知道这里的源代码注释是什么:
glEnableVertexAttribArray(0); // vao ^^
应该是这个意思。但是,我的印象是你误解了这个函数的作用。
GL 管理一组通用顶点属性(规范保证至少有 16 个,也许更多),并且对于每个这样的属性,数据可以来自数组。除了必须指定属性指针和数据格式之外,您还必须分别启用每个属性的数组。进行绘制调用时,对于每个顶点索引 i
,GPU 将获取 i
- 启用数组的每个属性的属性数组中的值。对于禁用数组的属性,它将在整个绘制调用中使用一个常量值。 (您可以在发出绘图调用之前通过 glVertexAttrib*()
familiy of functions 进行设置)。
因为您从未启用属性 1 的数组(着色器的 normals
输入),所有顶点都将看到属性 1 的当前值 - 很可能只是 vec4(0)
,因为那是初始默认值,您似乎从未更改过它。
解决方案当然是启用所有要从中获取的属性数组:
glEnableVertexAttribArray(1);
而且,当你在做的时候:在你的渲染循环中,你有
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
那是没有必要的。 VAO已经存储了这些信息,不需要重新绑定它来绘制。
我正在尝试将 vec3 颜色数据获取到顶点着色器(作为属性指针),然后将其传递到片段中以进行所有设置。
一切都是从无法将纹理坐标传递到顶点着色器开始的。我到处都看过,但找不到明确的解决方案。我可以(通过在顶点着色器中手动设置颜色),得到一个白色方块到渲染器,但是来自 VAO 的颜色数据似乎无法传递给它。
另外我确定着色器加载系统可以正常工作。我最好的想法是信息没有传递给顶点着色器的 'layout = 1',但我很可能是错的。
VAO/缓冲区/着色器设置
float vert[] = {
//Vert Locs Normal Coords
-0.5f,-0.5f, 1.0f,1.0f,1.0f, //0
0.5f,-0.5f, 1.0f,1.0f,1.0f, //1
0.5f,0.5f, 1.0f,1.0f,1.0f, //2
-0.5f, 0.5f, 1.0f,1.0f,1.0f, //3
};
unsigned int index[] = {
0,1,2, //Order of drawing vertices
2,3,0
};
unsigned int vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
unsigned int buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 5 * 4 * sizeof(float), vert, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT,GL_FALSE, 5 * sizeof(float), 0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float)));
glEnableVertexAttribArray(0); // vao ^^
unsigned int ibo;
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), index, GL_STATIC_DRAW);
Shader v("VertexN.shader", GL_VERTEX_SHADER);
Shader f("FragmentN.shader", GL_FRAGMENT_SHADER);
unsigned int shaders2[] = {v.id, f.id};
unsigned int program2 = Shader::getProgram(shaders2);
glUseProgram(0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
渲染循环
glClearColor(0, 0, 0, 1);
/* Render here */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glUseProgram(program2);
//tex.bind(slot);
glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); //Drawing mode, Type indecies , type of index buffer , pointer to index buffer
glfwSwapBuffers(window);
glfwPollEvents();
glFlush();
glBindVertexArray(0);
glUseProgram(0);
glActiveTexture(0);
顶点着色器
#version 330 core
layout(location = 0)in vec2 pos;
layout(location = 1)in vec3 normals;
out vec3 normal;
void main() {
normal = normals;
gl_Position = vec4(pos, 0.0f, 1.0f);
};
片段着色器
#version 330 core
layout(location = 0)out vec4 colour;
in vec3 normal;
void main() {
colour = vec4(normal, 1.0f);
};
我不知道这里的源代码注释是什么:
glEnableVertexAttribArray(0); // vao ^^
应该是这个意思。但是,我的印象是你误解了这个函数的作用。
GL 管理一组通用顶点属性(规范保证至少有 16 个,也许更多),并且对于每个这样的属性,数据可以来自数组。除了必须指定属性指针和数据格式之外,您还必须分别启用每个属性的数组。进行绘制调用时,对于每个顶点索引 i
,GPU 将获取 i
- 启用数组的每个属性的属性数组中的值。对于禁用数组的属性,它将在整个绘制调用中使用一个常量值。 (您可以在发出绘图调用之前通过 glVertexAttrib*()
familiy of functions 进行设置)。
因为您从未启用属性 1 的数组(着色器的 normals
输入),所有顶点都将看到属性 1 的当前值 - 很可能只是 vec4(0)
,因为那是初始默认值,您似乎从未更改过它。
解决方案当然是启用所有要从中获取的属性数组:
glEnableVertexAttribArray(1);
而且,当你在做的时候:在你的渲染循环中,你有
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
那是没有必要的。 VAO已经存储了这些信息,不需要重新绑定它来绘制。