AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / user-22405300

Creui's questions

Martin Hope
Creui
Asked: 2023-08-17 22:29:09 +0800 CST

OpenGL 中的非渐变颜色变化

  • 6

我正在尝试逐渐将三角形的颜色更改为光谱上的每种颜色。颜色基本上在渲染循环的每次迭代中增量变化,并将颜色信息传递给统一变量。问题在于它在多次迭代之间存在滞后并且不会逐渐改变。主程序上的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 的代码(从绿色逐渐变为无)可以完美地工作。

LearnOpenGL 三角形逐渐由绿变无

c
  • 1 个回答
  • 38 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve