我正在尝试逐渐将三角形的颜色更改为光谱上的每种颜色。颜色基本上在渲染循环的每次迭代中增量变化,并将颜色信息传递给统一变量。问题在于它在多次迭代之间存在滞后并且不会逐渐改变。主程序上的rgb值是逐渐变化的,但最终三角形的颜色却没有变化。然而,我在没有三角形的整个窗口上执行此操作(逐渐改变颜色)没有问题。
以下是三角频谱程序的代码及其输出预览:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define GLFW_INCLUDE_NONE
#include "include/glad/glad.h"
#include <GLFW/glfw3.h>
void framebufferSizeCallback(GLFWwindow* window, int width, int height){
glViewport(0, 0, width, height);
}
void processInput(GLFWwindow* window){
;
}
char * parseFile(const char * fileName){
FILE *fp = fopen(fileName, "r");
if (!fp) perror(fileName),exit(1);
fseek(fp, 0L, SEEK_END); // go to the end
long lsize = ftell(fp); // size is how far it is from the start
rewind(fp); // reset to the start to prepare for reading
char *buffer = calloc(1, lsize+1); //assign (lsize) blocks of memory to buffer
if (!buffer) fclose(fp),fputs("Failed to allocate memory.",stderr),exit(1);
if(1!=fread(buffer,lsize,1,fp))
fclose(fp),free(buffer),fputs("Failed to read file.", stderr),exit(1);
fclose(fp);
return buffer;
}
int main(void){
glfwInit();
if (glfwInit() != GLFW_TRUE){
printf("Failed to initialize GLFW.");
glfwTerminate();
return -1;
}
glfwWindowHint(GLFW_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE);
int windowSize = 600;
GLFWwindow* window;
window = glfwCreateWindow(windowSize, windowSize, "spectrum", NULL, NULL);
if (window == NULL){
printf("Failed to create window.\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
printf("Failed to initialize GLAD.\n");
return 1;
}
glViewport(0, 0, windowSize, windowSize);
glfwSetFramebufferSizeCallback(window, framebufferSizeCallback);
/*------------------------------------------------------------------------*/
const char *vertexShader = parseFile("timeTriangleShaders/vert.glsl");
const char *fragmentShader = parseFile("timeTriangleShaders/frag.glsl");
unsigned int vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShaderID, 1, &vertexShader, NULL);
glCompileShader(vertexShaderID);
unsigned int fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShaderID, 1, &fragmentShader, NULL);
glCompileShader(fragmentShaderID);
unsigned int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShaderID);
glAttachShader(shaderProgram, fragmentShaderID);
glLinkProgram(shaderProgram);
free((char*)vertexShader);
free((char*)fragmentShader);
glDeleteShader(vertexShaderID);
glDeleteShader(fragmentShaderID);
/*------------------------------------------------------------------------*/
float vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
unsigned int VAO, VBO;
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, 1); // unbind VBO
glBindVertexArray(0); // unbind VAO
/*------------------------------------------------------------------------*/
float min = 0;
float max = 255;
float rgb[] = {min, max, min}; // g,r,b instead of r,g,b to emulate spectrum
int pos = 0;
int increment = 10;
while (!glfwWindowShouldClose(window)){
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
int colorUniformLocation = glGetUniformLocation(shaderProgram, "color");
if ((rgb[pos] >= max && increment > 0) || (rgb[pos] <= min && increment < 0)){
rgb[pos] = rgb[pos] > max ? max : min;
pos = pos == 2 ? 0 : ++pos;
increment = -increment;
}
else rgb[pos] += increment;
printf("rgb: (%3.f, %3.f, %3.f) | %3d\n", rgb[1], rgb[0], rgb[2], increment);
glUniform4f(colorUniformLocation, rgb[1], rgb[0], rgb[2], 1.0f);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
glfwTerminate();
return 0;
}
光谱三角形程序的Fragment Shader:
#version 460 core
out vec4 FragColor;
uniform vec4 color;
void main(){
FragColor = color;
}
光谱三角形程序的Vertex Shader:
#version 460 core
layout (location = 0) in vec3 aPos;
void main(){
gl_Position = vec4(aPos.xyz, 1.0);
}
光谱三角程序输出: 光谱三角程序不渐变颜色
使用 glClearColor 的简单光谱程序的代码:
#include <stdio.h>
// #define GLFW_INCLUDE_NONE
#include "include/glad/glad.h"
#include <GLFW/glfw3.h>
void framebufferSizeCallback(GLFWwindow* window, int width, int height){
glViewport(0, 0, width, height);
}
int main(void){
glfwInit();
if (glfwInit() != GLFW_TRUE){
printf("Failed to initialize GLFW.");
glfwTerminate();
return -1;
}
glfwWindowHint(GLFW_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE);
int windowSize = 600;
GLFWwindow* window;
window = glfwCreateWindow(windowSize, windowSize, "spectrum", NULL, NULL);
if (window == NULL){
printf("Failed to create window.\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
printf("Failed to initialize GLAD.\n");
return 1;
}
glViewport(0, 0, windowSize, windowSize);
glfwSetFramebufferSizeCallback(window, framebufferSizeCallback);
float min = 0;
float max = 255;
float rgb[] = {min, max, min}; // g,r,b instead of r,g,b to emulate spectrum
int pos = 0;
int increment = 10;
while (!glfwWindowShouldClose(window)){
glClearColor(rgb[1]/255, rgb[0]/255, rgb[2]/255, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
if ((rgb[pos] >= max && increment > 0) || (rgb[pos] <= min && increment < 0)){
rgb[pos] = rgb[pos] > max ? max : min;
pos = pos == 2 ? 0 : ++pos;
increment = -increment;
}
else rgb[pos] += increment;
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
使用 glClearColor 输出简单光谱程序: 使用 glClearColor 逐渐改变颜色的光谱程序
我尝试更改颜色增加的逻辑点,但无济于事。使用 vec3 而不是 vec4 然后调整片段着色器也没有帮助。然而,复制LearnOpenGL 的代码(从绿色逐渐变为无)可以完美地工作。