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
Os canais da saída de cor do sombreador de fragmento devem estar no intervalo [0,0, 1,0], não [0,0, 255,0].
Divida
rgb[]
por 255 do lado do host como você está fazendo noglClearColor()
exemplo antes de passar os valores paraglUniform4f()
: