旋转的GLSL纹理是像素化的

pexxcrt2  于 2022-09-26  发布在  其他
关注(0)|答案(1)|浏览(161)

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

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

以下是我的着色器和纹理类:

纹理.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);
}

Texture.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);
}

以下是我的texture.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,高兴,GLFW。

gz5pxeao

gz5pxeao1#

这似乎是Aliasing的一个经典例子。我们可以通过启用MSAA来修复此问题。

GLFW有一种内在的方法来做到这一点。在创建窗口之前放入以下内容:

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

编辑-

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

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

glEnable(GL_MULTISAMPLE);

相关问题