C++ OpenGL渲染两个不同颜色的矩形
Posted
技术标签:
【中文标题】C++ OpenGL渲染两个不同颜色的矩形【英文标题】:C++ OpenGL rendering two rectangles with different colors 【发布时间】:2016-07-06 22:07:28 【问题描述】:我试图创建两个具有两种不同颜色并朝相反方向移动的矩形对象。但是,我被困在用不同颜色渲染两个矩形(目前它们是相同的颜色)。
有什么办法呢?
代码如下:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include "ogldev_util.h"
#include "ogldev_math_3d.h"
GLuint VBO1;
GLuint VBO2;
GLuint gScaleLocation1;
GLuint gScaleLocation2;
const char* pVSFileName = "shader.vs";
const char* pFSFileName = "shader.fs";
static void RenderSceneCB()
glClear(GL_COLOR_BUFFER_BIT);
static float Scale1 = 0.0f;
Scale1 += 0.01f;
glUniform1f(gScaleLocation1, sinf(Scale1));
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO1);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
static float Scale2 = 0.0f;
Scale2 -= 0.01f;
glUniform1f(gScaleLocation2, sinf(Scale2));
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(0);
glutSwapBuffers();
static void InitializeGlutCallbacks()
glutDisplayFunc(RenderSceneCB);
glutIdleFunc(RenderSceneCB);
static void CreateVertexBuffer()
Vector3f Vertices[6];
Vertices[0] = Vector3f(1.0f, -0.5f, 0.0f);
Vertices[1] = Vector3f(1.0f, 0.5f, 0.0f);
Vertices[2] = Vector3f(3.0f, -0.5f, 0.0f);
Vertices[3] = Vector3f(1.0f, 0.5f, 0.0f);
Vertices[4] = Vector3f(3.0f, 0.5f, 0.0f);
Vertices[5] = Vector3f(3.0f, -0.5f, 0.0f);
glGenBuffers(1, &VBO1);
glBindBuffer(GL_ARRAY_BUFFER, VBO1);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
Vector3f Vertices2[6];
Vertices2[0] = Vector3f(-3.0f, -0.5f, 0.0f);
Vertices2[1] = Vector3f(-3.0f, 0.5f, 0.0f);
Vertices2[2] = Vector3f(-1.0f, -0.5f, 0.0f);
Vertices2[3] = Vector3f(-3.0f, 0.5f, 0.0f);
Vertices2[4] = Vector3f(-1.0f, 0.5f, 0.0f);
Vertices2[5] = Vector3f(-1.0f, -0.5f, 0.0f);
glGenBuffers(1, &VBO2);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, GL_STATIC_DRAW);
static void AddShader(GLuint ShaderProgram, const char* pShaderText, GLenum ShaderType)
GLuint ShaderObj = glCreateShader(ShaderType);
if (ShaderObj == 0)
fprintf(stderr, "Error creating shader type %d\n", ShaderType);
exit(1);
const GLchar* p[1];
p[0] = pShaderText;
GLint Lengths[1];
Lengths[0]= strlen(pShaderText);
glShaderSource(ShaderObj, 1, p, Lengths);
glCompileShader(ShaderObj);
GLint success;
glGetShaderiv(ShaderObj, GL_COMPILE_STATUS, &success);
if (!success)
GLchar InfoLog[1024];
glGetShaderInfoLog(ShaderObj, 1024, NULL, InfoLog);
fprintf(stderr, "Error compiling shader type %d: '%s'\n", ShaderType, InfoLog);
exit(1);
glAttachShader(ShaderProgram, ShaderObj);
static void CompileShaders()
GLuint ShaderProgram = glCreateProgram();
if (ShaderProgram == 0)
fprintf(stderr, "Error creating shader program\n");
exit(1);
string vs, fs;
if (!ReadFile(pVSFileName, vs))
exit(1);
;
if (!ReadFile(pFSFileName, fs))
exit(1);
;
AddShader(ShaderProgram, vs.c_str(), GL_VERTEX_SHADER);
AddShader(ShaderProgram, fs.c_str(), GL_FRAGMENT_SHADER);
GLint Success = 0;
GLchar ErrorLog[1024] = 0 ;
glLinkProgram(ShaderProgram);
glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &Success);
if (Success == 0)
glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog);
fprintf(stderr, "Error linking shader program: '%s'\n", ErrorLog);
exit(1);
glValidateProgram(ShaderProgram);
glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &Success);
if (!Success)
glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog);
fprintf(stderr, "Invalid shader program: '%s'\n", ErrorLog);
exit(1);
glUseProgram(ShaderProgram);
gScaleLocation1 = glGetUniformLocation(ShaderProgram, "gScale");
assert(gScaleLocation1 != 0xFFFFFFFF);
int main(int argc, char** argv)
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(1024, 768);
glutInitWindowPosition(100, 100);
glutCreateWindow("Tutorial 05");
InitializeGlutCallbacks();
// Must be done after glut is initialized!
GLenum res = glewInit();
if (res != GLEW_OK)
fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
return 1;
printf("GL version: %s\n", glGetString(GL_VERSION));
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
CreateVertexBuffer();
CompileShaders();
glutMainLoop();
return 0;
片段着色器
#version 330
out vec4 FragColor;
void main()
FragColor = vec4(1.0, 0.0, 0.0, 1.0);
【问题讨论】:
我们看不到您的着色器,但我看不到您设置任何颜色统一或顶点数组绑定。您需要将带有顶点的颜色作为不同的顶点数组绑定、统一变量或纹理推送。您也不需要在每次渲染时都设置顶点属性指针。您可能应该改用适当的 VAO,因此您可以交换您的 VAO 绑定来渲染多个网格。 【参考方案1】:这取决于。在这种情况下,最简单的方法是在片段着色器中添加uniform vec3 color;
和gl_FragColor = vec4(color, 1.0);
,然后在渲染每个矩形之前通过调用glUniform3f
将其初始化为所需的颜色。但是,随着矩形计数的增长,您最好创建顶点struct
,它不仅会携带坐标,还会携带颜色。
另外,我强烈推荐这个http://www.opengl-tutorial.org/ opengl 教程网站。
【讨论】:
我已经在片段着色器中添加了颜色,但是我如何将它调用为一绿一红? glUniform3f 的正确使用方法是什么? 您需要在glUseProgram
和glDrawArrays
之间的任意位置调用它。第一个参数是一个统一的位置,接下来是 3 - 矢量的每个分量(在这种情况下,颜色 - rgb。它们应该在 0.0 和 1.0 之间):glUniform3f(colorUniformLocation, r, g, b);
。在您的情况下,它是:glUniform1f(gScaleLocation1, sinf(Scale1));
之后的glUniform3f(colorUniformLocation, 1.0f, 0.0f, 0.0f);
和glUniform1f(gScaleLocation1, sinf(Scale2));
之后的glUniform3f(colorUniformLocation, 0.0f, 1.0f, 0.0f);
。以上是关于C++ OpenGL渲染两个不同颜色的矩形的主要内容,如果未能解决你的问题,请参考以下文章