OpenGL纹理弯曲[重复]

Posted

技术标签:

【中文标题】OpenGL纹理弯曲[重复]【英文标题】:OpenGL texture crooked [duplicate] 【发布时间】:2014-11-06 15:55:32 【问题描述】:

我正在尝试在 OpenGL 中上传纹理,但纹理已弯曲。

#include <iostream>

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <SOIL/SOIL.h>

#define GLSL(version, shader) "#version " #version "\n" #shader

const char * vertShader = GLSL(430,

    in vec2 position;
    in vec2 texcoord;

    out vec2 coordinates;

    void main() 
        coordinates = texcoord;
        gl_Position = vec4(position, 0.0, 1.0);
    

);

const char * fragShader = GLSL(430,

    in vec2 coordinates;

    out vec4 color;

    uniform sampler2D texture;

    void main() 
        color = texture(texture, coordinates);
    

);

int main(int argc, char ** argv)

    if (not glfwInit())
    
        std::cerr << "Failed to initialize GLFW" << std::endl;
        return -1;
    

    GLFWwindow *window;
    window = glfwCreateWindow(720, 480, "Textures", 0, 0);

    if (not window)
    
        std::cerr << "Failed to open GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    

    glfwMakeContextCurrent(window);

    glewExperimental = true;

    if (glewInit() != GLEW_OK)
    
        std::cerr << "Failed to initialize GLEW" << std::endl;
        return -1;
    

    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    GLuint vbo;
    glGenBuffers(1, &vbo);

    GLfloat vertices[] = 
        -1.0f, +1.0f, 0.0f, 0.0f,
        +1.0f, +1.0f, 1.0f, 0.0f,
        +1.0f, -1.0f, 1.0f, 1.0f,
        -1.0f, -1.0f, 0.0f, 1.0f,
    ;

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

    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);

    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertShader, 0);
    glCompileShader(vertexShader);

    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragShader, NULL);
    glCompileShader(fragmentShader);

    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    glUseProgram(shaderProgram);

    GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
    GLint texAttrib = glGetAttribLocation(shaderProgram, "texcoord");

    glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0);
    glEnableVertexAttribArray(posAttrib);

    glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void *)(2 * sizeof(float)));
    glEnableVertexAttribArray(texAttrib);

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

    int width, height;

    unsigned char * image = SOIL_load_image("happyface.png", &width, &height, 0, SOIL_LOAD_RGB);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);

    SOIL_free_image_data(image);

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

    do 

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

        glfwPollEvents();
        glfwSwapBuffers(window);

     while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS
                        && glfwWindowShouldClose(window) == 0);

    glDeleteTextures(1, &tex);

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

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

    glDeleteVertexArrays(1, &vao);

    glfwTerminate();

    return 0;

我做错了什么?如您所见,纹理是弯曲的和重复的,但纹理只是一张笑脸。

结果如下:

这就是纹理:

【问题讨论】:

GL_UNPACK_ALIGNMENT 设置为1 有帮助吗? 不幸的是,它没有。 @yayuj 你一定是放错地方了。 【参考方案1】:

我不是 OpenGL 专家,但某些图形系统需要 2 或 4 像素宽的倍数的纹理。

你的纹理是 479 宽 - 添加另一列像素,我想你会没事的。

【讨论】:

也许你的意思是两种纹理的力量?因为 480 可以被 2 整除,但显然是 NPOT 纹理。 @Nazar554 确实,它不是 2 的幂,但显示的图像显然与每行偏移一个像素一致,而且我有 99% 的信心认为 480 宽图片不会显示这个。 现在工作很奇怪。谢谢你。 - 我读过一次,我认为它是固定的。 @MrAlmighty 它甚至可能是 SOIL_load_image 函数的限制,而不是 OpenGL 本身。 我认为是 OpenGL 本身,我正在阅读它,似乎两个的幂使得纹理针对图形硬件进行了优化。 - 即使现代硬件允许其他人没有二的力量,它也行不通。 (神秘)。

以上是关于OpenGL纹理弯曲[重复]的主要内容,如果未能解决你的问题,请参考以下文章

用opengl实现网格[重复]

Opengl 纹理映射和图像分辨率

纹理不填充图形 - OpenGL

使用 OpenGL 在 2d 对象上看不到我的纹理 [关闭]

✠OpenGL-8-阴影

OpenGL ES纹理