C++,OpengL 动画如何在直线移动时改变立方体的颜色?
C++, OpengGL animation how to change the color of the cubes when the line is moving?
我有这个 C++ 的 OpenGL 程序,它是一个移动的圆圈,在背景中有 vubes 和一条可以向上或向下移动的线,你可以按下 W 或 S 按钮。当线在屏幕中间时,线下方的立方体应为绿色,线上方的立方体颜色应为红色。
当线条向上移动时,立方体的颜色应该改变,所以当线条位于屏幕顶部时,每个立方体都需要是红色的。
在我的代码中,当我向上移动线时,它会在需要时更改其颜色,但立方体的颜色从 运行 开始到结束,无论我将线移动到哪里。
附上代码:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "glm/glm.hpp"
#include <array>
#include <vector>
#include <iostream>
#include <string>
#include <fstream>
#include <math.h>
#define COORDMIN -0.7
#define COORDMAX 0.7
#define PI 3.14159265359
using namespace std;
GLuint VBO;
GLuint VAO;
GLuint VBO1;
GLuint VAO1;
GLuint VBO2;
GLuint VAO2;
static int WIN_WIDTH = 600;
static int WIN_HEIGHT = 600;
float x = 0.0f;
float y = 0.0f;
float inc = 0.01f;
float inc1 = 0.01f;
bool up = true;
bool down = false;
float fel = 1.0f;
float le = -1.0f;
bool xDir = true;
bool yDir = false;
bool go = true;
GLfloat p;
std::vector<glm::vec3> linePoints;
glm::vec3 vertices[] = {
glm::vec3(-0.9f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor1
glm::vec3(-0.7f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor1
glm::vec3(-0.9f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 2
glm::vec3(-0.7f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 2
glm::vec3(-0.9f, 0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 3
glm::vec3(-0.7f, 0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, 0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, 0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, 0.5, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, 0.5, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, 0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, 0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, 0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, 0.5, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 3
glm::vec3(-0.9f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 4
glm::vec3(-0.7f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 4
glm::vec3(-0.9f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 5
glm::vec3(-0.7f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 5
glm::vec3(-0.9f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 6
glm::vec3(-0.7f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 6
glm::vec3(-0.9f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 7
glm::vec3(-0.7f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 7
glm::vec3(-0.9f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 8
glm::vec3(-0.7f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 8
glm::vec3(-0.9f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 9
glm::vec3(-0.7f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 9
glm::vec3(-0.9f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 9
glm::vec3(-0.7f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 9
};
float a = 0.0f;
float b = 0.95f;
float b1 = -0.95f;
glm::vec3 vertices2[4];
void genSzakasz(float a) {
vertices2[0] = glm::vec3(-1.0f, a, 0.0f);
vertices2[1] = glm::vec3(1.0f, a, 0.0f);
vertices2[2] = glm::vec3(1.0f, 1.0f, 0.0f);
vertices2[3] = glm::vec3(1.0f, 1.0f, 0.0f);
}
float RandomCoordGenerator()
{
float r3 = COORDMIN + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (COORDMAX - COORDMIN)));
return r3;
}
GLfloat radius = 0.2f; // first
GLfloat centerx = RandomCoordGenerator();
GLfloat centery = RandomCoordGenerator();
GLfloat novX = 0.002f;
GLfloat novY = 0.005f;
GLdouble updateFrequency = 0.01f, lastUpdate;
void korSzin()
{
for (int i = 0; i < 100; i++)
{
linePoints.push_back(
glm::vec3(
0.0f, 1.0f, 0.0f));
}
}
void generatePoints()
{
for (int i = 0; i < 100; i++)
{
linePoints.push_back(
glm::vec3(
centerx + radius * cos(i * (2 * 3.14159 / 100)),
centery + radius * sin(i * (2 * 3.14159 / 100)),
0));
}
korSzin();
}
GLuint renderingProgram; //kor
GLuint renderingProgram2; //pontok
GLuint renderingProgram3; //szakasz
bool checkOpenGLError() {
bool foundError = false;
int glErr = glGetError();
while (glErr != GL_NO_ERROR) {
cout << "glError: " << glErr << endl;
foundError = true;
glErr = glGetError();
}
return foundError;
}
void printShaderLog(GLuint shader) {
int len = 0;
int chWrittn = 0;
char* log;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
if (len > 0) {
log = (char*)malloc(len);
glGetShaderInfoLog(shader, len, &chWrittn, log);
cout << "Shader Info Log: " << log << endl;
free(log);
}
}
void printProgramLog(int prog) {
int len = 0;
int chWrittn = 0;
char* log;
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
if (len > 0) {
log = (char*)malloc(len);
glGetProgramInfoLog(prog, len, &chWrittn, log);
cout << "Program Info Log: " << log << endl;
free(log);
}
}
string readShaderSource(const char* filePath) {
string content;
ifstream fileStream(filePath, ios::in);
string line = "";
while (!fileStream.eof()) {
getline(fileStream, line);
content.append(line + "\n");
}
fileStream.close();
return content;
}
GLuint createShaderProgram() {
GLint vertCompiled;
GLint fragCompiled;
GLint linked;
string vertShaderStr = readShaderSource("vertexShader.glsl");
string fragShaderStr = readShaderSource("fragmentShader.glsl");
GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);
const char* vertShaderSrc = vertShaderStr.c_str();
const char* fragShaderSrc = fragShaderStr.c_str();
glShaderSource(vShader, 1, &vertShaderSrc, NULL);
glShaderSource(fShader, 1, &fragShaderSrc, NULL);
glCompileShader(vShader);
glCompileShader(vShader);
checkOpenGLError();
glGetShaderiv(vShader, GL_COMPILE_STATUS, &vertCompiled);
if (vertCompiled != 1) {
cout << "vertex compilation failed" << endl;
printShaderLog(vShader);
}
glCompileShader(fShader);
checkOpenGLError();
glGetShaderiv(vShader, GL_COMPILE_STATUS, &fragCompiled);
if (fragCompiled != 1) {
cout << "fragment compilation failed" << endl;
printShaderLog(fShader);
}
GLuint vfProgram = glCreateProgram();
glAttachShader(vfProgram, vShader);
glAttachShader(vfProgram, fShader);
glLinkProgram(vfProgram);
checkOpenGLError();
glGetProgramiv(vfProgram, GL_LINK_STATUS, &linked);
if (linked != 1) {
cout << "linking failed" << endl;
printProgramLog(vfProgram);
}
glDeleteShader(vShader);
glDeleteShader(fShader);
return vfProgram;
}
void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
float szakasz_y_koord = 0.0f;
if (key == GLFW_KEY_W && action == GLFW_PRESS)
{
if (a <= b) {
a += 0.2f;
genSzakasz(a);
szakasz_y_koord = a;
GLuint offsetLoc = glGetUniformLocation(renderingProgram, "szakasz_y_koord"); // mutató az "offsetX" értékre
glProgramUniform1f(renderingProgram, offsetLoc, a);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}
if (key == GLFW_KEY_S && action == GLFW_PRESS)
{
if (a >= b1) {
a -= 0.2f;
genSzakasz(a);
szakasz_y_koord = a;
GLuint offsetLoc = glGetUniformLocation(renderingProgram, "szakasz_y_koord"); // mutató az "offsetX" értékre
glProgramUniform1f(renderingProgram, offsetLoc, a);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
createShaderProgram();
}
genSzakasz(a);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}
void init(GLFWwindow* window) {
renderingProgram = createShaderProgram(); // minden mas
generatePoints();
genSzakasz(a);
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO1);
glGenVertexArrays(1, &VAO1);
glGenBuffers(1, &VBO2);
glGenVertexArrays(1, &VAO2);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, 200 * sizeof(glm::vec3), linePoints.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
renderingProgram2 = createShaderProgram();
glBindBuffer(GL_ARRAY_BUFFER, VBO1);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * 200, vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * 4, vertices2, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
Elsőként megadjuk ezt az azonosítószámot.
Utána az attribútum méretét (vec3, láttuk a shaderben).
Harmadik az adat típusa.
Negyedik az adat normalizálása, ez maradhat FALSE jelen példában.
Az attribútum értékek hogyan következnek egymás után? Milyen lépésköz után találom a következő vertex adatait?
Végül megadom azt, hogy honnan kezdődnek az értékek a pufferben. Most rögtön, a legelejétől veszem őket.*/
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)(100 * sizeof(glm::vec3)));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(VAO1);
glBindBuffer(GL_ARRAY_BUFFER, VBO1);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3) * 2, (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3) * 2, (void*)(sizeof(glm::vec3)));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(VAO2);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)(2 * sizeof(glm::vec3)));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void cleanUpScene()
{
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(renderingProgram);
}
void bounce(double currentTime) {
if (currentTime - lastUpdate >= updateFrequency)
{
y += inc1;
x += inc;
if (x > 1.5f) inc = -0.01; // jobb
if (x < -0.07f) inc = 0.01; //bal
if (y > 0.7f) inc1 = -0.01; // fennt
if (y < -0.9f) inc1 = 0.01; //lennt
GLuint offsetLoc = glGetUniformLocation(renderingProgram, "offsetX"); // mutató az "offsetX" értékre
glProgramUniform1f(renderingProgram, offsetLoc, x); // küldjük el az "x" értékét az "offsetX" számára
GLuint offsetLoc1 = glGetUniformLocation(renderingProgram, "offsetY"); // mutató az "offsetX" értékre
glProgramUniform1f(renderingProgram, offsetLoc1, y); // küldjük el az "x" értékét az "offsetX" számára
}
}
void display(GLFWwindow* window, double currentTime) {
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT); // fontos lehet minden egyes alkalommal törölni!
glUseProgram(renderingProgram);
glBindVertexArray(VAO);
glPointSize(30.0f);
bounce(glfwGetTime());
glDrawArrays(GL_TRIANGLE_FAN, 0, 100);
glUseProgram(renderingProgram2);
glBindVertexArray(VAO1);
glPointSize(10.0f);
glDrawArrays(GL_POINTS, 0, 100);
glUseProgram(renderingProgram2);
glBindVertexArray(VAO2);
glPointSize(30.0f);
glDrawArrays(GL_LINE_LOOP, 0, 2);
glBindVertexArray(0);
}
int main(void) {
if (!glfwInit()) { exit(EXIT_FAILURE); }
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
GLFWwindow* window = glfwCreateWindow(WIN_WIDTH, WIN_HEIGHT, "Draw a Line", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, keyCallback);
//glfwSetCursorPosCallback(window, cursorPosCallback);
glfwSetMouseButtonCallback(window, mouseButtonCallback);
if (glewInit() != GLEW_OK) { exit(EXIT_FAILURE); }
glfwSwapInterval(1);
init(window);
while (!glfwWindowShouldClose(window)) {
display(window, glfwGetTime());
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
cleanUpScene();
glfwTerminate();
exit(EXIT_SUCCESS);
}
这是我的顶点着色器:
#version 430
uniform float offsetX;
uniform float offsetY;
uniform float szakaszYkoord;
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 color;
out vec3 myColor;
void main(void)
{
gl_Position = vec4(aPos.x + offsetX, aPos.y + offsetY + szakaszYkoord, aPos.z, 1.0);
if ( aPos.y > szakaszYkoord){
myColor = vec3(1.0, 1.0, 0.0);
} else {
myColor = vec3(1.0, 0.0, 0.0);
}
}
这是我的片段着色器:
#version 430
in vec3 myColor;
out vec4 color;
void main(void)
{
color = vec4(myColor, 1.0);
}
我的问题是为什么线条的颜色在变化,而立方体的颜色却没有?当线移动时,我应该怎么做才能改变立方体的颜色?
将顶点坐标从顶点着色器传递到片段着色器并设置每个片段的颜色而不是每个顶点。
顶点着色器:
#version 430
uniform float offsetX;
uniform float offsetY;
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 color;
out vec3 vPos;
void main(void)
{
vPos = aPos + vec3(offsetX, offsetY, 0.0);
gl_Position = vec4(vPos, 1.0);
}
片段着色器
#version 430
uniform float szakasz_y_koord;
in vec3 vPos;
out vec4 color;
void main(void)
{
color = (vPos.y > szakasz_y_koord)
? vec4(1.0, 1.0, 0.0, 1.0)
: vec4(1.0, 0.0, 0.0, 1.0);
}
统一变量存储在着色器程序的默认统一块中。他们使用相同的着色器源代码生成 2 个程序对象。您只需要1个程序,完全可以删除第2个程序。
只要你在使用2个程序,你就必须在两个程序中更改统一变量。绘制圆时将“szakasz_y_koord”设置为-1.0,绘制点时将其设置为a
:
void display(GLFWwindow* window, double currentTime) {
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT); // fontos lehet minden egyes alkalommal törölni!
GLuint offsetLoc = glGetUniformLocation(renderingProgram, "szakasz_y_koord"); // mutató az "offsetX" értékre
glProgramUniform1f(renderingProgram, offsetLoc, -1.0);
glUseProgram(renderingProgram);
glBindVertexArray(VAO);
glPointSize(30.0f);
bounce(glfwGetTime());
glDrawArrays(GL_TRIANGLE_FAN, 0, 100);
GLuint offsetLoc2 = glGetUniformLocation(renderingProgram, "szakasz_y_koord"); // mutató az "offsetX" értékre
glProgramUniform1f(renderingProgram2, offsetLoc2, a);
glUseProgram(renderingProgram2);
glBindVertexArray(VAO1);
glPointSize(10.0f);
glDrawArrays(GL_POINTS, 0, 100);
glBindVertexArray(VAO2);
glPointSize(30.0f);
glDrawArrays(GL_LINE_LOOP, 0, 2);
glBindVertexArray(0);
}
我有这个 C++ 的 OpenGL 程序,它是一个移动的圆圈,在背景中有 vubes 和一条可以向上或向下移动的线,你可以按下 W 或 S 按钮。当线在屏幕中间时,线下方的立方体应为绿色,线上方的立方体颜色应为红色。
当线条向上移动时,立方体的颜色应该改变,所以当线条位于屏幕顶部时,每个立方体都需要是红色的。
在我的代码中,当我向上移动线时,它会在需要时更改其颜色,但立方体的颜色从 运行 开始到结束,无论我将线移动到哪里。
附上代码:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "glm/glm.hpp"
#include <array>
#include <vector>
#include <iostream>
#include <string>
#include <fstream>
#include <math.h>
#define COORDMIN -0.7
#define COORDMAX 0.7
#define PI 3.14159265359
using namespace std;
GLuint VBO;
GLuint VAO;
GLuint VBO1;
GLuint VAO1;
GLuint VBO2;
GLuint VAO2;
static int WIN_WIDTH = 600;
static int WIN_HEIGHT = 600;
float x = 0.0f;
float y = 0.0f;
float inc = 0.01f;
float inc1 = 0.01f;
bool up = true;
bool down = false;
float fel = 1.0f;
float le = -1.0f;
bool xDir = true;
bool yDir = false;
bool go = true;
GLfloat p;
std::vector<glm::vec3> linePoints;
glm::vec3 vertices[] = {
glm::vec3(-0.9f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor1
glm::vec3(-0.7f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, 0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor1
glm::vec3(-0.9f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 2
glm::vec3(-0.7f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, 0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 2
glm::vec3(-0.9f, 0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 3
glm::vec3(-0.7f, 0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, 0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, 0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, 0.5, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, 0.5, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, 0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, 0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, 0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, 0.5, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 3
glm::vec3(-0.9f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 4
glm::vec3(-0.7f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, 0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 4
glm::vec3(-0.9f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 5
glm::vec3(-0.7f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, 0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 5
glm::vec3(-0.9f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 6
glm::vec3(-0.7f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, -0.1f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 6
glm::vec3(-0.9f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 7
glm::vec3(-0.7f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, -0.3f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 7
glm::vec3(-0.9f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 8
glm::vec3(-0.7f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, -0.5f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 8
glm::vec3(-0.9f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 9
glm::vec3(-0.7f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, -0.7f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 9
glm::vec3(-0.9f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f), //sor 9
glm::vec3(-0.7f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.5f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.3f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(-0.1f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.1f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.3f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.5f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.7f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(0.9f, -0.9f, 0.0f), glm::vec3(1.0f, 1.0f, 1.0f),//sor 9
};
float a = 0.0f;
float b = 0.95f;
float b1 = -0.95f;
glm::vec3 vertices2[4];
void genSzakasz(float a) {
vertices2[0] = glm::vec3(-1.0f, a, 0.0f);
vertices2[1] = glm::vec3(1.0f, a, 0.0f);
vertices2[2] = glm::vec3(1.0f, 1.0f, 0.0f);
vertices2[3] = glm::vec3(1.0f, 1.0f, 0.0f);
}
float RandomCoordGenerator()
{
float r3 = COORDMIN + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (COORDMAX - COORDMIN)));
return r3;
}
GLfloat radius = 0.2f; // first
GLfloat centerx = RandomCoordGenerator();
GLfloat centery = RandomCoordGenerator();
GLfloat novX = 0.002f;
GLfloat novY = 0.005f;
GLdouble updateFrequency = 0.01f, lastUpdate;
void korSzin()
{
for (int i = 0; i < 100; i++)
{
linePoints.push_back(
glm::vec3(
0.0f, 1.0f, 0.0f));
}
}
void generatePoints()
{
for (int i = 0; i < 100; i++)
{
linePoints.push_back(
glm::vec3(
centerx + radius * cos(i * (2 * 3.14159 / 100)),
centery + radius * sin(i * (2 * 3.14159 / 100)),
0));
}
korSzin();
}
GLuint renderingProgram; //kor
GLuint renderingProgram2; //pontok
GLuint renderingProgram3; //szakasz
bool checkOpenGLError() {
bool foundError = false;
int glErr = glGetError();
while (glErr != GL_NO_ERROR) {
cout << "glError: " << glErr << endl;
foundError = true;
glErr = glGetError();
}
return foundError;
}
void printShaderLog(GLuint shader) {
int len = 0;
int chWrittn = 0;
char* log;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
if (len > 0) {
log = (char*)malloc(len);
glGetShaderInfoLog(shader, len, &chWrittn, log);
cout << "Shader Info Log: " << log << endl;
free(log);
}
}
void printProgramLog(int prog) {
int len = 0;
int chWrittn = 0;
char* log;
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
if (len > 0) {
log = (char*)malloc(len);
glGetProgramInfoLog(prog, len, &chWrittn, log);
cout << "Program Info Log: " << log << endl;
free(log);
}
}
string readShaderSource(const char* filePath) {
string content;
ifstream fileStream(filePath, ios::in);
string line = "";
while (!fileStream.eof()) {
getline(fileStream, line);
content.append(line + "\n");
}
fileStream.close();
return content;
}
GLuint createShaderProgram() {
GLint vertCompiled;
GLint fragCompiled;
GLint linked;
string vertShaderStr = readShaderSource("vertexShader.glsl");
string fragShaderStr = readShaderSource("fragmentShader.glsl");
GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);
const char* vertShaderSrc = vertShaderStr.c_str();
const char* fragShaderSrc = fragShaderStr.c_str();
glShaderSource(vShader, 1, &vertShaderSrc, NULL);
glShaderSource(fShader, 1, &fragShaderSrc, NULL);
glCompileShader(vShader);
glCompileShader(vShader);
checkOpenGLError();
glGetShaderiv(vShader, GL_COMPILE_STATUS, &vertCompiled);
if (vertCompiled != 1) {
cout << "vertex compilation failed" << endl;
printShaderLog(vShader);
}
glCompileShader(fShader);
checkOpenGLError();
glGetShaderiv(vShader, GL_COMPILE_STATUS, &fragCompiled);
if (fragCompiled != 1) {
cout << "fragment compilation failed" << endl;
printShaderLog(fShader);
}
GLuint vfProgram = glCreateProgram();
glAttachShader(vfProgram, vShader);
glAttachShader(vfProgram, fShader);
glLinkProgram(vfProgram);
checkOpenGLError();
glGetProgramiv(vfProgram, GL_LINK_STATUS, &linked);
if (linked != 1) {
cout << "linking failed" << endl;
printProgramLog(vfProgram);
}
glDeleteShader(vShader);
glDeleteShader(fShader);
return vfProgram;
}
void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
float szakasz_y_koord = 0.0f;
if (key == GLFW_KEY_W && action == GLFW_PRESS)
{
if (a <= b) {
a += 0.2f;
genSzakasz(a);
szakasz_y_koord = a;
GLuint offsetLoc = glGetUniformLocation(renderingProgram, "szakasz_y_koord"); // mutató az "offsetX" értékre
glProgramUniform1f(renderingProgram, offsetLoc, a);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}
if (key == GLFW_KEY_S && action == GLFW_PRESS)
{
if (a >= b1) {
a -= 0.2f;
genSzakasz(a);
szakasz_y_koord = a;
GLuint offsetLoc = glGetUniformLocation(renderingProgram, "szakasz_y_koord"); // mutató az "offsetX" értékre
glProgramUniform1f(renderingProgram, offsetLoc, a);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
createShaderProgram();
}
genSzakasz(a);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}
void init(GLFWwindow* window) {
renderingProgram = createShaderProgram(); // minden mas
generatePoints();
genSzakasz(a);
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO1);
glGenVertexArrays(1, &VAO1);
glGenBuffers(1, &VBO2);
glGenVertexArrays(1, &VAO2);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, 200 * sizeof(glm::vec3), linePoints.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
renderingProgram2 = createShaderProgram();
glBindBuffer(GL_ARRAY_BUFFER, VBO1);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * 200, vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * 4, vertices2, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
Elsőként megadjuk ezt az azonosítószámot.
Utána az attribútum méretét (vec3, láttuk a shaderben).
Harmadik az adat típusa.
Negyedik az adat normalizálása, ez maradhat FALSE jelen példában.
Az attribútum értékek hogyan következnek egymás után? Milyen lépésköz után találom a következő vertex adatait?
Végül megadom azt, hogy honnan kezdődnek az értékek a pufferben. Most rögtön, a legelejétől veszem őket.*/
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)(100 * sizeof(glm::vec3)));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(VAO1);
glBindBuffer(GL_ARRAY_BUFFER, VBO1);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3) * 2, (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3) * 2, (void*)(sizeof(glm::vec3)));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(VAO2);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), (void*)(2 * sizeof(glm::vec3)));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void cleanUpScene()
{
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(renderingProgram);
}
void bounce(double currentTime) {
if (currentTime - lastUpdate >= updateFrequency)
{
y += inc1;
x += inc;
if (x > 1.5f) inc = -0.01; // jobb
if (x < -0.07f) inc = 0.01; //bal
if (y > 0.7f) inc1 = -0.01; // fennt
if (y < -0.9f) inc1 = 0.01; //lennt
GLuint offsetLoc = glGetUniformLocation(renderingProgram, "offsetX"); // mutató az "offsetX" értékre
glProgramUniform1f(renderingProgram, offsetLoc, x); // küldjük el az "x" értékét az "offsetX" számára
GLuint offsetLoc1 = glGetUniformLocation(renderingProgram, "offsetY"); // mutató az "offsetX" értékre
glProgramUniform1f(renderingProgram, offsetLoc1, y); // küldjük el az "x" értékét az "offsetX" számára
}
}
void display(GLFWwindow* window, double currentTime) {
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT); // fontos lehet minden egyes alkalommal törölni!
glUseProgram(renderingProgram);
glBindVertexArray(VAO);
glPointSize(30.0f);
bounce(glfwGetTime());
glDrawArrays(GL_TRIANGLE_FAN, 0, 100);
glUseProgram(renderingProgram2);
glBindVertexArray(VAO1);
glPointSize(10.0f);
glDrawArrays(GL_POINTS, 0, 100);
glUseProgram(renderingProgram2);
glBindVertexArray(VAO2);
glPointSize(30.0f);
glDrawArrays(GL_LINE_LOOP, 0, 2);
glBindVertexArray(0);
}
int main(void) {
if (!glfwInit()) { exit(EXIT_FAILURE); }
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
GLFWwindow* window = glfwCreateWindow(WIN_WIDTH, WIN_HEIGHT, "Draw a Line", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, keyCallback);
//glfwSetCursorPosCallback(window, cursorPosCallback);
glfwSetMouseButtonCallback(window, mouseButtonCallback);
if (glewInit() != GLEW_OK) { exit(EXIT_FAILURE); }
glfwSwapInterval(1);
init(window);
while (!glfwWindowShouldClose(window)) {
display(window, glfwGetTime());
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
cleanUpScene();
glfwTerminate();
exit(EXIT_SUCCESS);
}
这是我的顶点着色器:
#version 430
uniform float offsetX;
uniform float offsetY;
uniform float szakaszYkoord;
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 color;
out vec3 myColor;
void main(void)
{
gl_Position = vec4(aPos.x + offsetX, aPos.y + offsetY + szakaszYkoord, aPos.z, 1.0);
if ( aPos.y > szakaszYkoord){
myColor = vec3(1.0, 1.0, 0.0);
} else {
myColor = vec3(1.0, 0.0, 0.0);
}
}
这是我的片段着色器:
#version 430
in vec3 myColor;
out vec4 color;
void main(void)
{
color = vec4(myColor, 1.0);
}
我的问题是为什么线条的颜色在变化,而立方体的颜色却没有?当线移动时,我应该怎么做才能改变立方体的颜色?
将顶点坐标从顶点着色器传递到片段着色器并设置每个片段的颜色而不是每个顶点。
顶点着色器:
#version 430
uniform float offsetX;
uniform float offsetY;
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 color;
out vec3 vPos;
void main(void)
{
vPos = aPos + vec3(offsetX, offsetY, 0.0);
gl_Position = vec4(vPos, 1.0);
}
片段着色器
#version 430
uniform float szakasz_y_koord;
in vec3 vPos;
out vec4 color;
void main(void)
{
color = (vPos.y > szakasz_y_koord)
? vec4(1.0, 1.0, 0.0, 1.0)
: vec4(1.0, 0.0, 0.0, 1.0);
}
统一变量存储在着色器程序的默认统一块中。他们使用相同的着色器源代码生成 2 个程序对象。您只需要1个程序,完全可以删除第2个程序。
只要你在使用2个程序,你就必须在两个程序中更改统一变量。绘制圆时将“szakasz_y_koord”设置为-1.0,绘制点时将其设置为a
:
void display(GLFWwindow* window, double currentTime) {
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT); // fontos lehet minden egyes alkalommal törölni!
GLuint offsetLoc = glGetUniformLocation(renderingProgram, "szakasz_y_koord"); // mutató az "offsetX" értékre
glProgramUniform1f(renderingProgram, offsetLoc, -1.0);
glUseProgram(renderingProgram);
glBindVertexArray(VAO);
glPointSize(30.0f);
bounce(glfwGetTime());
glDrawArrays(GL_TRIANGLE_FAN, 0, 100);
GLuint offsetLoc2 = glGetUniformLocation(renderingProgram, "szakasz_y_koord"); // mutató az "offsetX" értékre
glProgramUniform1f(renderingProgram2, offsetLoc2, a);
glUseProgram(renderingProgram2);
glBindVertexArray(VAO1);
glPointSize(10.0f);
glDrawArrays(GL_POINTS, 0, 100);
glBindVertexArray(VAO2);
glPointSize(30.0f);
glDrawArrays(GL_LINE_LOOP, 0, 2);
glBindVertexArray(0);
}