opengl 简单的渐变效果

l0oc07j2  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(202)

我需要编写片段着色器,使三角形具有简单的渐变效果。也就是说,使其透明度从左到右逐渐降低。我尝试了这个方法,但失败了:


# version 120

uniform float startX = gl_FragCoord.x;
void main(void) {
    gl_FragColor[0] = 0.0;
    gl_FragColor[1] = 0.0;
    gl_FragColor[2] = 1.0;
    gl_FragColor[3] = startX / gl_FragCoord.x;
}

完整代码:


# include <cstdlib>

# include <iostream>

using namespace std;

# include <GL/glew.h>

# include <SDL.h>

GLuint program;
GLint attribute_coord2d;

bool init_resources(void)
{
    GLint compile_ok, link_ok = GL_FALSE;

    GLuint vs = glCreateShader(GL_VERTEX_SHADER);
    const char* vs_source = R"(
        #version 120
        attribute vec2 coord2d;
        void main(void) {
            gl_Position = vec4(coord2d, 0.0, 1.0);
        }
    )";
    glShaderSource(vs, 1, &vs_source, NULL);
    glCompileShader(vs);
    glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_ok);
    if (!compile_ok) {
        cerr << "Error in vertex shader" << endl;
        return false;
    }

    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
    const char* fs_source = R"(
        #version 120
        uniform float startX = gl_FragCoord.x;
        void main(void) {
            gl_FragColor[0] = 0.0;
            gl_FragColor[1] = 0.0;
            gl_FragColor[2] = 1.0;
            gl_FragColor[3] = startX / gl_FragCoord.x;
        }
    )";
    glShaderSource(fs, 1, &fs_source, NULL);
    glCompileShader(fs);
    glGetShaderiv(fs, GL_COMPILE_STATUS, &compile_ok);
    if (!compile_ok) {
        cerr << "Error in fragment shader" << endl;
        return false;
    }

    program = glCreateProgram();
    glAttachShader(program, vs);
    glAttachShader(program, fs);
    glLinkProgram(program);
    glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
    if (!link_ok) {
        cerr << "Error in glLinkProgram" << endl;
        return false;
    }

    const char* attribute_name = "coord2d";
    attribute_coord2d = glGetAttribLocation(program, attribute_name);
    if (attribute_coord2d == -1) {
        cerr << "Could not bind attribute " << attribute_name << endl;
        return false;
    }

    return true;
}

void render(SDL_Window* window)
{
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glUseProgram(program);

    glEnableVertexAttribArray(attribute_coord2d);
    GLfloat triangle_vertices[] = {
        0.0,  0.8,
       -0.8, -0.8,
        0.8, -0.8,
    };

    glVertexAttribPointer(attribute_coord2d, 2, GL_FLOAT, GL_FALSE, 0, triangle_vertices);

    glDrawArrays(GL_TRIANGLES, 0, 3);

    glDisableVertexAttribArray(attribute_coord2d);

    SDL_GL_SwapWindow(window);
}

void free_resources()
{
    glDeleteProgram(program);
}

void mainLoop(SDL_Window* window)
{
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    while (true)
    {
        SDL_Event ev;
        while (SDL_PollEvent(&ev))
        {
            if (ev.type == SDL_QUIT)
                return;
        }
        render(window);
    }
}

int main(int argc, char* argv[])
{
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window* window = SDL_CreateWindow("My First Triangle", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL);
    SDL_GL_CreateContext(window);

    GLenum glew_status = glewInit();
    if (glew_status != GLEW_OK) {
        cerr << "Error: glewInit: " << glewGetErrorString(glew_status) << endl;
        return EXIT_FAILURE;
    }

    if (!init_resources())
        return EXIT_FAILURE;

    mainLoop(window);

    free_resources();
    return EXIT_SUCCESS;
}

怎么做才对?

3hvapo4f

3hvapo4f1#

v不能使用gl_FragCoord.x初始化统一。统一初始化在链接时确定。
uniform float startX = gl_FragCoord.x;

uniform float startX;

您必须使用glUniform1f设置取消格式。
gl_FragCoord.xy不是顶点坐标。gl_FragCoord.xy是以像素为单位的窗口坐标。您必须将gl_FragCoord.xy除以视窗的大小:


# version 120

void main(void) {
    gl_FragColor = vec4(0.0, 0.0, 0.0, gl_FragCoord.x / 640.0);
}

或者将coord2d传递给片段着色器:
第一个
或者使用颜色属性:
第一个

相关问题