Estou tentando mudar gradualmente a cor de um triângulo para cada cor do espectro. A cor basicamente muda de forma incremental em cada iteração do loop de renderização e passa as informações de cor para uma variável uniforme. O problema é que está atrasado entre várias iterações e não muda gradualmente. Os valores rgb no programa principal estão mudando gradualmente, mas a cor do triângulo no final não. No entanto, não tive nenhum problema em fazer isso (mudança gradual de cores) em toda a janela sem um triângulo.
Aqui está o código do programa do espectro do triângulo e uma prévia de sua saída:
#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 do programa Spectrum Triangle:
#version 460 core
out vec4 FragColor;
uniform vec4 color;
void main(){
FragColor = color;
}
Vertex Shader do programa Spectrum Triangle:
#version 460 core
layout (location = 0) in vec3 aPos;
void main(){
gl_Position = vec4(aPos.xyz, 1.0);
}
Saída do programa do triângulo do espectro: o programa do triângulo do espectro NÃO altera as cores gradualmente
O código do programa de espectro simples com 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;
}
Saída do programa de espectro simples com GlClearColor: programa de espectro com glClearColor mudando gradualmente as cores
Já tentei mudar o ponto da lógica onde a cor é incrementada mas sem sucesso. Usar vec3 em vez de vec4 e ajustar o fragment shader também não ajudou. No entanto , replicar o código do LearnOpenGL , que muda de verde para nada gradualmente, funciona perfeitamente.
Triângulo LearnOpenGL mudando de verde para nada gradualmente