首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用顶点缓冲区和纹理缓冲区的OpenGL C++顺序

使用顶点缓冲区和纹理缓冲区的OpenGL C++顺序
EN

Stack Overflow用户
提问于 2014-06-10 12:57:14
回答 1查看 657关注 0票数 0

我在我的三角形条上装纹理有问题。我跟随着安东·格德兰教程,在我的主程序失败后,我回到了基础上,尝试做一个简单的正方形,把他的纹理放在上面(头骨和十字骨)。

我从他的“你好三角”页面中完全复制和粘贴了代码,这是可行的,但一旦尝试在上面的纹理教程中加入代码(并将三角形更改为正方形),我所得到的只是一个没有纹理的大白方。

我用glGetShaderiv()检查了我的着色器的状态,它们返回了正数,我检查了加载的图像,看看像素数据是否合理,所以我认为我的错误是声明了我的VBO,或者我使用它们的顺序/参数。

下面是我复制的完整代码,它在Visual 2013中编译得很好,但输出不是预期的。

我使用的是GLEW和GLFW的静态库,以及STBI图像头

代码语言:javascript
复制
#include <GL/glew.h> // include GLEW and new version of GL on Windows
#include <GL/glfw3.h> // GLFW helper library
#include <stdio.h>
#define STB_IMAGE_IMPLEMENTATION
#include <stb/stb_image.h>

const char* vertex_shader =
"#version 400\n"
"in vec3 vp;"
"layout (location=1) in vec2 vt; // per-vertex texture co-ords"
"out vec2 texture_coordinates; "
"void main () {"
"  gl_Position = vec4 (vp, 1.0);"
"  texture_coordinates = vt; "
"}";

const char* fragment_shader =
"#version 400\n"
"in vec2 texture_coordinates;"
"uniform sampler2D basic_texture;"
"out vec4 frag_colour;"
"void main () {"
"vec4 texel = texture(basic_texture, texture_coordinates);"
"frag_colour = texel; "
"}";

float points[] = {
    -0.5f, -0.5f, 0.0f,
    -0.5f, 0.5f, 0.0f,
    0.5f, -0.5f, 0.0f,
    0.5f, 0.5f, 0.0f

};

float texcoords[] = {
    0.0f, 1.0f,
    0.0f, 0.0f,
    1.0, 0.0,
    1.0, 0.0,
    1.0, 1.0,
    0.0, 1.0
};

GLFWwindow* window;
unsigned int vt_vbo;
unsigned int tex = 0;
GLuint vao = 0;
GLuint vbo = 0;
GLuint shader_programme;

void initializeGL(){
    // start GL context and O/S window using the GLFW helper library
    if (!glfwInit()) {
        printf("ERROR: could not start GLFW3\n");
        return;
    }

    window = glfwCreateWindow(640, 480, "Texture Test", NULL, NULL);
    if (!window) {
        printf("ERROR: could not open window with GLFW3\n");
        glfwTerminate();
        return;
    }
    glfwMakeContextCurrent(window);

    // start GLEW extension handler
    glewExperimental = GL_TRUE;
    glewInit();

    // get version info
    const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string
    const GLubyte* version = glGetString(GL_VERSION); // version as a string
    printf("Renderer: %s\n", renderer);
    printf("OpenGL version supported %s\n", version);

    // tell GL to only draw onto a pixel if the shape is closer to the viewer
    glEnable(GL_DEPTH_TEST); // enable depth-testing
    glDepthFunc(GL_LESS); // depth-testing interprets a smaller value as "closer"
}

void startShaders(){

    GLuint vs = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vs, 1, &vertex_shader, NULL);
    glCompileShader(vs);
    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fs, 1, &fragment_shader, NULL);
    glCompileShader(fs);

    shader_programme = glCreateProgram();
    glAttachShader(shader_programme, fs);
    glAttachShader(shader_programme, vs);
    glLinkProgram(shader_programme);
    GLint vsstat;
    glGetShaderiv(vs, GL_COMPILE_STATUS, &vsstat);
    GLint fsstat;
    glGetShaderiv(fs, GL_COMPILE_STATUS, &fsstat);
    printf("%i\n%i\n", vsstat, fsstat);
}

void loadImage(){
    int x, y, n;
    int force_channels = 4;
    unsigned char* image_data = stbi_load("skulluvmap.png", &x, &y, &n, force_channels);
    if (!image_data) {
        printf("ERROR: could not load %s\n", "skulluvmap.png");
    }

    int width_in_bytes = x * 4;
    unsigned char *top = NULL;
    unsigned char *bottom = NULL;
    unsigned char temp = 0;
    int half_height = y / 2;


    for (int row = 0; row < half_height; row++) {
        top = image_data + row * width_in_bytes;
        bottom = image_data + (y - row - 1) * width_in_bytes;
        for (int col = 0; col < width_in_bytes; col++) {
            temp = *top;
            *top = *bottom;
            *bottom = temp;
            top++;
            bottom++;
        }
    }
    printf("first 4 bytes are: %i %i %i %i\n",
        image_data[0], image_data[1], image_data[2], image_data[3]
        );
    glGenTextures(1, &tex);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
    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_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}

void generateBuffers(){
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(float), points, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(0); // don't forget this!

    glGenBuffers(1, &vt_vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vt_vbo);
    glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(float), texcoords, GL_STATIC_DRAW);

    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(1); // don't forget this!
}

void mainLoop(){
    while (!glfwWindowShouldClose(window)) {
        // wipe the drawing surface clear
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
        int tex_loc = glGetUniformLocation(shader_programme, "basic_texture");
        glUseProgram(shader_programme);
        glUniform1i(tex_loc, 0); // use active texture 0
        // draw points 0-4 from the currently bound VAO with current in-use shader
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        // update other events like input handling 
        glfwPollEvents();
        // put the stuff we've been drawing onto the display
        glfwSwapBuffers(window);
    }
}

int main() {

    initializeGL();
    startShaders();
    loadImage();
    generateBuffers();
    mainLoop();

    // close GL context and any other GLFW resources
    glfwTerminate();
    return 0;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-06-10 13:45:08

您滥用了第二个缓冲区,它应该是带有texcoords的缓冲区。所以你真正想要实现的是,每个顶点都有一对纹理坐标。这意味着,实际上,纹理和弦数组应该存储4对,因为点数组中有4个三元组。所以这是第一个解决办法。你可能想让它看起来像:

代码语言:javascript
复制
float texcoords[] = {
0.0f, 1.0f,
0.0f, 0.0f,
1.0, 0.0,
1.0, 1.0,
};

那么在generateBuffers中,您的vt_vbo是错误的。数据应以这种方式传递:

代码语言:javascript
复制
glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(float), texcoords, GL_STATIC_DRAW);

因为您只想在那里传递8个值。每个顶点有2个纹理和弦。

编辑:

然而,这并不能完全解释为什么你的纹理没有出现。我主要认为您的texcoords指针可能有问题,但情况似乎并非如此。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24141595

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档