在OpenGL / SDL2教程中,纹理采样坐标看似按2比例缩放

最高

我编写了一个简单的OpenGL程序,以采样256x256 PNG纹理并将其渲染到窗口中的矩形上。为此,我非常依赖教程。当我几乎完全按照本教程进行操作(进行最小的更改以便将SDL2用于[x])时,纹理无法正确渲染,并且似乎以某种方式被缩小了2倍。这是源代码的第一个版本,以及结果的屏幕截图:

// Link statically with GLEW
#define GLEW_STATIC

// Headers
#include <GL/glew.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_opengl.h>

// Shader sources
const GLchar* vertexSource = R"glsl(
    #version 150 core
    in vec2 position;
    in vec2 color;
    out vec2 Color;
    void main()
    {
        Color = color;
        gl_Position = vec4(position, 0.0, 1.0);
    }
)glsl";
const GLchar* fragmentSource = R"glsl(
    #version 150 core
    in vec2 Color;
    out vec4 outColor;
    uniform sampler2D tex;
    void main()
    {
        outColor = texture(tex,Color);
    }
)glsl";

int main()
{
    SDL_Init(SDL_INIT_VIDEO);

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);

    SDL_Window* window = SDL_CreateWindow("OpenGL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI);

    SDL_GLContext context = SDL_GL_CreateContext(window);
    glViewport(0, 0, 800, 600);

    // Initialize GLEW
    glewExperimental = GL_TRUE;
    glewInit();

    // Create Vertex Array Object
    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    // Create a Vertex Buffer Object and copy the vertex data to it
    GLuint vbo;
    glGenBuffers(1, &vbo);

    GLfloat vertices[] = {
//         x      y     u     v
        -0.5f,  0.5f, 0.0f, 0.0f, // Top-left
         0.5f,  0.5f, 1.0f, 0.0f, // Top-right
         0.5f, -0.5f, 1.0f, 1.0f, // Bottom-right
        -0.5f, -0.5f, 0.0f, 1.0f // Bottom-left
    };

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

    // Create an element array
    GLuint ebo;
    glGenBuffers(1, &ebo);

    GLuint elements[] = {
        0, 1, 2,
        2, 3, 0
    };

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);

    // Create and compile the vertex shader
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexSource, NULL);
    glCompileShader(vertexShader);

    // Create and compile the fragment shader
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
    glCompileShader(fragmentShader);

    // Link the vertex and fragment shader into a shader program
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glBindFragDataLocation(shaderProgram, 0, "outColor");
    glLinkProgram(shaderProgram);
    glUseProgram(shaderProgram);

    // Specify the layout of the vertex data
    GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
    glEnableVertexAttribArray(posAttrib);
    glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);

    GLint colAttrib = glGetAttribLocation(shaderProgram, "color");
    glEnableVertexAttribArray(colAttrib);
    glVertexAttribPointer(colAttrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));

    GLuint tex;
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);

    SDL_Surface* surface = IMG_Load("../textures/16x16-sb-ascii.png");

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, surface->w, surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
    SDL_FreeSurface(surface);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

    bool running = true;
    while (running)
    {
        SDL_Event windowEvent;
        while (SDL_PollEvent(&windowEvent))
        {
            switch (windowEvent.type)
            {
            case SDL_QUIT:
                running = false;
                break;
            }
        }

        // Clear the screen to black
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // Draw a rectangle from the 2 triangles using 6 indices
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

        // Swap buffers
        SDL_GL_SwapWindow(window);
    }

    glDeleteProgram(shaderProgram);
    glDeleteShader(fragmentShader);
    glDeleteShader(vertexShader);

    glDeleteBuffers(1, &ebo);
    glDeleteBuffers(1, &vbo);

    glDeleteVertexArrays(1, &vao);

    SDL_Quit();

    return 0;
}

初步结果

作为参考,这是实际的纹理文件:

原始纹理文件

如您所见,在矩形的不同象限中,纹理似乎已变成四倍,而下面的两个副本则被莫名其妙地损坏了。

可以预料到,将所有纹理坐标标准化为0.5会按预期比例生成纹理的单个副本,尽管仍然可以看到许多奇怪的黄色/蓝色伪像,以及边缘周围一些非常细微的噪点伪像:

    GLfloat vertices[] = {
//         x      y     u     v
        -0.5f,  0.5f, 0.0f, 0.0f, // Top-left
         0.5f,  0.5f, 0.5f, 0.0f, // Top-right
         0.5f, -0.5f, 0.5f, 0.5f, // Bottom-right
        -0.5f, -0.5f, 0.0f, 0.5f // Bottom-left
    };

缩小坐标后的结果。

我正在预装了Ubuntu 18.04.4 LTS的戴尔笔记本电脑上进行此操作。我的显卡是Intel UHD Graphics 630(Coffeelake 3x8 GT2)。

运行glxinfo | grep“ OpenGL版本”给出以下结果:OpenGL版本字符串:3.0 Mesa 19.2.8。

对于缩放或蓝色/黄色伪影的任何帮助将不胜感激。谢谢!

拉比德76

The generated texture image is a luminance/alpha image and has just one color channel and one alpha channel. Thus you have to use the format GL_RG when you specify the 2 dimensional texture image by glTexImage2D:

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG, surface->w, surface->h, 0, 
             GL_RG, GL_UNSIGNED_BYTE, surface->pixels);

Either set a Swizzle mask to read the green and blue color from the red color channel and the alpha value from the green color channel:

GLint swizzleMask[] = {GL_RED, GL_RED, GL_RED, GL_GREEN};
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);

or use Swizzling to get the red color channel and the alpha channel when you do the texture lookup in the fragment shader:

#version 150 core

in vec2 Color;
out vec4 outColor;
uniform sampler2D tex;

void main()
{
    outColor = texture(tex,Color).rrrg;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在SDL2中显示OpenGL纹理

来自分类Dev

缩放纹理opengl 2

来自分类Dev

从SDL2表面创建OpenGL纹理-奇怪的像素值

来自分类Dev

iOS SDL2 OpenGL ES无法绘制纹理

来自分类Dev

SDL2 + OpenGL彩色几何

来自分类Dev

SDL2 OpenGL 窗口立即关闭

来自分类Dev

带有OpenGL纹理的SDL2显示不正确

来自分类Dev

如何将opengl 3.3渲染为SDL2纹理?

来自分类Dev

SDL Surface的openGL纹理

来自分类Dev

OpenGL纹理坐标错误

来自分类Dev

在AWS EC2上运行OpenGL + SDL2

来自分类Dev

使用SDL2指定OpenGL版本

来自分类Dev

我是否正在删除sdl2和opengl?

来自分类Dev

OpenGL + SDL2 +计算着色器=黑屏

来自分类Dev

在OpenGL中绘制2D纹理

来自分类Dev

SDL多重采样和OpenGL

来自分类Dev

OpenGL:即时更改纹理坐标

来自分类Dev

OpenGL 3.2球形-纹理坐标

来自分类Dev

模型纹理坐标opengl的问题

来自分类Dev

在OpenGL + SDL2中无法将Alpha通道设置为0

来自分类Dev

Xcode:SDL2 + OpenGL 3.2:窗口未显示在示例代码中

来自分类Dev

SDL2和SDL_opengl_glext.h未定义外部

来自分类Dev

SDL2 SDL_CreateRenderer降级了OpenGL上下文,可以防止吗?

来自分类Dev

SDL2 SDL_CreateRenderer降级了OpenGL上下文,可以防止吗?

来自分类Dev

SDL2和SDL_opengl_glext.h未定义外部

来自分类Dev

从数据到OpenGL 2D纹理

来自分类Dev

什么是使用OpenGL的纹理下采样(缩小)?

来自分类Dev

没有纹理绑定的OpenGL采样

来自分类Dev

openGL单通道纹理始终采样0