如何使用opengl将颜色应用于三角形
How to apply colour to a triangle with opengl
我正在尝试使用 openGL 创建一个简单的程序。目标是为每个顶点创建一个带有颜色的三角形。问题是我不知道如何将颜色应用到三角形的顶点。
我的顶点着色器:
#version 330
layout(location = 0) in vec4 vertex_position;
layout(location = 1) in vec4 vertex_color;
smooth out vec4 theColor;
void main()
{
gl_Position = vec4(vertex_position.x, vertex_position.y, vertex_position.z, 1.0);
theColor = vertex_color;
}
我的片段着色器:
#version 330
smooth in vec4 theColor;
out vec4 outColor;
void main()
{
outColor = theColor;
}
主要代码:
float vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f,
0.5f, 0.6f, 0.1f,
0.2f, 0.6, 0.3f,
0.1f, 0.23f, 0.78f
};
GLuint my_vao, my_vbo;
glGenVertexArrays(1, &my_vao);
glBindVertexArray(my_vao);
glGenBuffers(1, &my_vbo);
glBindBuffer(GL_ARRAY_BUFFER, my_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
// glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
// glVertexAttribPointer(3,4, GL_UNSIGNED_BYTE, GL_TRUE, 0, (void*)0);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(vao);
glViewport(0, 0, viewport_width, viewport_height);
glDrawArrays(GL_TRIANGLES, 0, 3);
swapBuffers();
顶点数组由顶点(前 3 个向量)和颜色值(后 3 个向量)组成。您可以在下图中看到我的结果:
我一直在尝试使用以下代码应用颜色:
glEnableVertexAttribArray(1);
glVertexAttribPointer(3,4, GL_UNSIGNED_BYTE, GL_TRUE, 0, (void*)0);
不幸的是,它不起作用,我不知道如何解决。有人可以帮我吗?
为了编译和加载我使用的着色器:
std::string loadVertexShader(const char* vertexPath)
{
std::string vertexCode;
std::ifstream vShaderFile;
vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try
{
vShaderFile.open(vertexPath);
std::stringstream vShaderStream;
vShaderStream << vShaderFile.rdbuf();
vShaderFile.close();
vertexCode = vShaderStream.str();
}
catch (std::ifstream::failure e)
{
std::cout << "ERROR::VERTEXSHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
}
return vertexCode;
}
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
std::string vertexVal = loadVertexShader("shader/vertexshader.shader");
const char* vShaderCode = vertexVal.c_str();
std::string fragmentVal = loadFragmentShader("shader/fragmentshader.shader");
const char* fShaderCode = fragmentVal.c_str();
glShaderSource(vertexShader, 1, &vShaderCode, NULL);
glCompileShader(vertexShader);
glShaderSource(fragmentShader, 1, &fShaderCode, NULL);
glCompileShader(fragmentShader);
GLint vertexStatus;
char vertexInfoLog[512];
char fragmentInfoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &vertexStatus);
GLint fragmentStatus;
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragmentStatus);
if (!vertexStatus)
{
glGetShaderInfoLog(vertexShader, 512, NULL, fragmentInfoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << fragmentInfoLog << std::endl;
}
if (!fragmentStatus)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, vertexInfoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << vertexInfoLog << std::endl;
}
首先,正如评论中的讨论所揭示的那样,您没有 link 您的程序。典型的着色器程序设置如下所示:
GLuint program = glCreateProgram();
glAttachShader(program, shader1);
glAttachShader(program, shader2);
...
glAttachShader(program, shaderN);
glLinkProgram(program); // <<<<<<<<< a-ha!
之后,一个好主意是检查程序 linkage 是否正常。可以找到完整着色器和程序设置的一个很好的例子 on OpenGL wiki。
程序成功 linkage 后,您甚至可以从程序中分离着色器 (glDetachShader
) 并删除它们 (glDeleteShader
) - 程序已经 linked,着色器现在没有用了(当然,除非你打算将它们附加到另一个程序)。
其次,您对 glVertexAttribPointer
的论点有点乱(这完全没问题 - 需要时间和精力来适应它们)。
void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized,
GLsizei stride, const GLvoid * pointer);
index
是属性索引 - 与着色器中指定的 location
相同,因此对于您的颜色属性,它应该是 1
。
size
是属性的维度,即分量个数;假设您使用的是 3-float RGB,大小应为 3
type
是组件的实际类型;在你的情况下,这些也是浮点数,所以 GL_FLOAT
stride
是相邻顶点的属性之间的距离,在你的例子中是3个浮点数,即12个字节;由于 vertices
数组中的相邻属性之间没有任何内容,我们实际上可以将其保留为零(对于坐标和颜色)
pointer
是指向实际属性数据的指针(或者,在您的情况下,VBO 中的偏移量);您将相同的指针传递给两个 glVertexAttribPointer
调用,而您的颜色值是坐标值 开始后的 9 个浮点数
所以,应该是
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (float const *)(nullptr) + 9);
我正在尝试使用 openGL 创建一个简单的程序。目标是为每个顶点创建一个带有颜色的三角形。问题是我不知道如何将颜色应用到三角形的顶点。
我的顶点着色器:
#version 330
layout(location = 0) in vec4 vertex_position;
layout(location = 1) in vec4 vertex_color;
smooth out vec4 theColor;
void main()
{
gl_Position = vec4(vertex_position.x, vertex_position.y, vertex_position.z, 1.0);
theColor = vertex_color;
}
我的片段着色器:
#version 330
smooth in vec4 theColor;
out vec4 outColor;
void main()
{
outColor = theColor;
}
主要代码:
float vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f,
0.5f, 0.6f, 0.1f,
0.2f, 0.6, 0.3f,
0.1f, 0.23f, 0.78f
};
GLuint my_vao, my_vbo;
glGenVertexArrays(1, &my_vao);
glBindVertexArray(my_vao);
glGenBuffers(1, &my_vbo);
glBindBuffer(GL_ARRAY_BUFFER, my_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
// glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
// glVertexAttribPointer(3,4, GL_UNSIGNED_BYTE, GL_TRUE, 0, (void*)0);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(vao);
glViewport(0, 0, viewport_width, viewport_height);
glDrawArrays(GL_TRIANGLES, 0, 3);
swapBuffers();
顶点数组由顶点(前 3 个向量)和颜色值(后 3 个向量)组成。您可以在下图中看到我的结果:
我一直在尝试使用以下代码应用颜色:
glEnableVertexAttribArray(1);
glVertexAttribPointer(3,4, GL_UNSIGNED_BYTE, GL_TRUE, 0, (void*)0);
不幸的是,它不起作用,我不知道如何解决。有人可以帮我吗?
为了编译和加载我使用的着色器:
std::string loadVertexShader(const char* vertexPath)
{
std::string vertexCode;
std::ifstream vShaderFile;
vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try
{
vShaderFile.open(vertexPath);
std::stringstream vShaderStream;
vShaderStream << vShaderFile.rdbuf();
vShaderFile.close();
vertexCode = vShaderStream.str();
}
catch (std::ifstream::failure e)
{
std::cout << "ERROR::VERTEXSHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
}
return vertexCode;
}
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
std::string vertexVal = loadVertexShader("shader/vertexshader.shader");
const char* vShaderCode = vertexVal.c_str();
std::string fragmentVal = loadFragmentShader("shader/fragmentshader.shader");
const char* fShaderCode = fragmentVal.c_str();
glShaderSource(vertexShader, 1, &vShaderCode, NULL);
glCompileShader(vertexShader);
glShaderSource(fragmentShader, 1, &fShaderCode, NULL);
glCompileShader(fragmentShader);
GLint vertexStatus;
char vertexInfoLog[512];
char fragmentInfoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &vertexStatus);
GLint fragmentStatus;
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragmentStatus);
if (!vertexStatus)
{
glGetShaderInfoLog(vertexShader, 512, NULL, fragmentInfoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << fragmentInfoLog << std::endl;
}
if (!fragmentStatus)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, vertexInfoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << vertexInfoLog << std::endl;
}
首先,正如评论中的讨论所揭示的那样,您没有 link 您的程序。典型的着色器程序设置如下所示:
GLuint program = glCreateProgram();
glAttachShader(program, shader1);
glAttachShader(program, shader2);
...
glAttachShader(program, shaderN);
glLinkProgram(program); // <<<<<<<<< a-ha!
之后,一个好主意是检查程序 linkage 是否正常。可以找到完整着色器和程序设置的一个很好的例子 on OpenGL wiki。
程序成功 linkage 后,您甚至可以从程序中分离着色器 (glDetachShader
) 并删除它们 (glDeleteShader
) - 程序已经 linked,着色器现在没有用了(当然,除非你打算将它们附加到另一个程序)。
其次,您对 glVertexAttribPointer
的论点有点乱(这完全没问题 - 需要时间和精力来适应它们)。
void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized,
GLsizei stride, const GLvoid * pointer);
index
是属性索引 - 与着色器中指定的location
相同,因此对于您的颜色属性,它应该是1
。size
是属性的维度,即分量个数;假设您使用的是 3-float RGB,大小应为3
type
是组件的实际类型;在你的情况下,这些也是浮点数,所以GL_FLOAT
stride
是相邻顶点的属性之间的距离,在你的例子中是3个浮点数,即12个字节;由于vertices
数组中的相邻属性之间没有任何内容,我们实际上可以将其保留为零(对于坐标和颜色)pointer
是指向实际属性数据的指针(或者,在您的情况下,VBO 中的偏移量);您将相同的指针传递给两个glVertexAttribPointer
调用,而您的颜色值是坐标值 开始后的 9 个浮点数
所以,应该是
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (float const *)(nullptr) + 9);