繁体   English   中英

旋转的 GLSL 纹理是像素化的

[英]Rotated GLSL texture is pixelated

我制作了一个程序,它根据给定的输入显示一些纹理,并且可以根据给定的输入旋转、调整大小和移动纹理。 该程序运行良好,但是当我旋转纹理时,边缘似乎是像素化的,如下所示:

在此处输入图像描述

有没有办法让我平滑这些边缘?

这是我的着色器和纹理类:

纹理.vs:

#version 300 es
precision mediump float;
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;

out vec3 ourColor;
out vec2 TexCoord;

uniform mat4 transform;

void main()
{
    gl_Position = transform * vec4(aPos, 1.0f);

    ourColor = aColor;
    TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}

纹理.fs

#version 300 es
precision mediump float;
out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

// texture sampler
uniform sampler2D texture1;

void main()
{
    FragColor = texture(texture1, TexCoord);
}

这是我的纹理.cpp:

    Texture::Texture(int x, int y, int w, int h, int gw, int gh)
    {
        pos.TL_x = _VERTICIZE_X(x, gw);
        pos.TL_y = -_VERTICIZE_Y(y, gh);
        pos.TR_x = _VERTICIZE_X(x + w, gw);
        pos.TR_y = -_VERTICIZE_Y(y, gh);
        pos.BL_x = _VERTICIZE_X(x, gw);
        pos.BL_y = -_VERTICIZE_Y(y + h, gh);
        pos.BR_x = _VERTICIZE_X(x + w, gw);
        pos.BR_y = -_VERTICIZE_Y(y + h, gh);
    }

    void set_max_z(int z)
    {
        max_z = z;
    }

    int Texture::init(float ang_rad, float z)
    {

        shader = Shader("./src/opengl/shaders/image.vs", "./src/opengl/shaders/image.fs");

        this->angle = ang_rad;
        // build and compile our shader zprogram
        // ------------------------------------
        // set up vertex data (and buffer(s)) and configure vertex attributes
        // ------------------------------------------------------------------
        
        float vertices[32] = {
            // positions            // colors           // texture coords
            pos.TR_x, pos.TR_y, _VERTICIZE_Z(z, max_z),  1.0f, 0.0f, 1.0f,   1.0f, 0.0f, // top right
            pos.BR_x, pos.BR_y, _VERTICIZE_Z(z, max_z),  0.0f, 1.0f, 1.0f,   1.0f, 1.0f, // bottom right
            pos.BL_x, pos.BL_y, _VERTICIZE_Z(z, max_z),  0.0f, 0.0f, 1.0f,   0.0f, 1.0f, // bottom left
            pos.TL_x, pos.TL_y, _VERTICIZE_Z(z, max_z),  1.0f, 1.0f, 1.0f,   0.0f, 0.0f  // top left
        };

        unsigned int indices[] = {
            0, 1, 3, // first triangle
            1, 2, 3  // second triangle
        };

        glEnable(GL_DEPTH_TEST);

        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
        glGenBuffers(1, &EBO);

        glBindVertexArray(VAO);

        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

        // position attribute
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
        glEnableVertexAttribArray(0);
        // color attribute
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(3 * sizeof(float)));
        glEnableVertexAttribArray(1);
        // texture coord attribute
        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(6 * sizeof(float)));
        glEnableVertexAttribArray(2);

        // load and create a texture
        // -------------------------
        // texture 1
        // ----------
        glGenTextures(1, &texture);
        glBindTexture(GL_TEXTURE_2D, texture);

        // tell opengl for each sampler to which texture unit it belongs to (only has to be done once)
        // -------------------------------------------------------------------------------------------
        shader.use(); // don't forget to activate/use the shader before setting uniforms!
        // either set it manually like so:
        glUniform1i(glGetUniformLocation(shader.ID, "texture"), 0);

        return 0;
    }

    void Texture::render(int w, int h, uint8_t *buffer)
    {
        // If having trouble doing multiple textures, add "+ index to Active Texture."
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
        glGenerateMipmap(GL_TEXTURE_2D);

        glActiveTexture(GL_TEXTURE0);

        glm::mat4 transform = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first
        transform = glm::translate(transform, glm::vec3(0.0f, 0.0f, 0.0f));
        transform = glm::rotate(transform, glm::radians(this->angle), glm::vec3(0.0f, 0.0f, 1.0f));

        // get matrix's uniform location and set matrix
        shader.use();
        unsigned int transformLoc = glGetUniformLocation(shader.ID, "transform");
        glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(transform));

        glBindVertexArray(VAO);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
    }

    Texture::~Texture()
    {
        glDeleteVertexArrays(1, &VAO);
        glDeleteBuffers(1, &VBO);
        glDeleteBuffers(1, &EBO);
    }

    void Texture::framebuffer_size_callback(GLFWwindow *window, int width, int height)
    {
        // make sure the viewport matches the new window dimensions; note that width and
        // height will be significantly larger than specified on retina displays.
        glViewport(0, 0, width, height);
    }

(_VERTICIZE 只计算点数)

我正在使用 ubuntu、GLAD、GLFW。

这似乎是Aliasing的经典示例。 我们可以通过启用MSAA来解决这个问题。

GLFW 有一种内置的方式来做到这一点。 在创建 window 之前将其放入:

glfwWindowHint(GLFW_SAMPLES, 4); /* if effect is not strong enough, change to 8 */

编辑 -

您必须在glfwInitglfwCreateWindow之间调用glfwWindowHint(GLFW_SAMPLES, 4)

此外,如果 OpenGL 默认不启用多重采样,请执行

glEnable(GL_MULTISAMPLE);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM