简体   繁体   中英

Rotated GLSL texture is pixelated

I've made a program that displays some textures depending on the given input and can rotate, resize and move the textures depending on the given input. The program works perfectly fine but when I rotate the textures the edges appear to be pixelated, like this:

在此处输入图像描述

Is there a way for me to smoothen out these edges?

Here are my shaders and texture classes:

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

Here is my 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 just calculates points)

I'm using ubuntu, GLAD, GLFW.

This appears to be a classic example of Aliasing . We can fix this by enabling MSAA .

GLFW has an inbuilt way of doing that. Put this before you create the window:

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

Edit -

You have to call glfwWindowHint(GLFW_SAMPLES, 4) in between glfwInit and glfwCreateWindow .

Also, in case OpenGL doesn't enable multisampling by default, do

glEnable(GL_MULTISAMPLE);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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