Почему мой код OpenGL не отображает клетчатую текстуру - PullRequest
0 голосов
/ 14 января 2019

Почему мой экран просто черный?

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
//#include "include/state.h"
//#include "include/state_machine.h"
//#include "include/renderable.h"


const int WIDTH = 800;
const int HEIGHT = 600;

// called when user resizes window
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
    glViewport(0, 0, width, height);
}

// called when we receive input
void processInput(GLFWwindow *window) {
    if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, 1);
}

GLuint get_checker_texture() {
    unsigned char texDat[64];
    for (int i = 0; i < 64; ++i)
        texDat[i] = ((i + (i / 8)) % 2) * 128 + 127;

    //upload to GPU texture
    GLuint tex;
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 8, 8, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, texDat);
    glGenerateMipmap(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, 0);

    return tex;
}

void draw_texture(GLuint texture, unsigned int vbo, unsigned int vao, unsigned int ebo) {
    glBindVertexArray(vao); 

    glBindTexture(GL_TEXTURE_2D, texture);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}

//void render_box(renderable* this, unsigned int vbo, unsigned int vao, unsigned int ebo) {
//    draw_texture(this->texture, this->x, this->y, this->z, vbo, vao, ebo);
//}

int main(int argc, char* argv[]) {
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    #ifdef __APPLE__
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // only on MACOS
    #endif

    // creating the window
    GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "OpenGL App", NULL, NULL);
    if (window == NULL) {
        printf("Failed to create GLFW window");
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);

    // hook on window resize
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        printf("Failed to initialize GLAD");
        return -1;
    }

    printf("OpenGL %d.%d\n", GLVersion.major, GLVersion.minor);

    glViewport(0, 0, WIDTH, HEIGHT);

    // just making sure the state machine works
    // for testing purposes only
    /*state_machine* sm = init_state_machine();
    state* state0 = init_state();

    state* state1 = init_state();
    state1->background_color->r = 1.0f;

    state* state2 = init_state();
    state2->background_color->g = 1.0f;

    ss_vector_append(sm->states, state0);
    ss_vector_append(sm->states, state1);
    ss_vector_append(sm->states, state2);*/

    //renderable* box = init_renderable(0.0f, 0.0f, 0.0f, &render_box);
    unsigned int tex = get_checker_texture();

    unsigned int vbo;
    glGenBuffers(1, &vbo);

    unsigned int vao;
    glGenVertexArrays(1, &vao);

    unsigned int ebo;
    glGenBuffers(1, &ebo);

    glBindVertexArray(vao);

    const char* vertex_shader_src =
        "#version 330 core\n"
        "layout (location = 0) in vec3 aPos;\n"
        "layout (location = 1) in vec3 aColor;\n"
        "layout (location = 2) in vec2 aTexCoord;\n"
        "\n"
        "out vec3 ourColor;\n"
        "out vec2 TexCoord;\n"
        "\n"
        "void main()\n"
        "{\n"
        "    gl_Position = vec4(aPos, 1.0);\n"
        "    ourColor = aColor;\n"
        "    TexCoord = aTexCoord;\n"
        "}";

    unsigned int vertex_shader;
    vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex_shader, 1, &vertex_shader_src, NULL);
    glCompileShader(vertex_shader); 

    int  success;
    char infoLog[512];
    glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);

    if (!success) {
        glGetShaderInfoLog(vertex_shader, 512, NULL, infoLog);
        printf("%s\n", infoLog);
    }

    const char* fragment_shader_src = 
        "#version 330 core\n"
        "out vec4 FragColor;\n"
        "\n" 
        "in vec3 ourColor;\n"
        "in vec2 TexCoord;\n"
        "\n"
        "uniform sampler2D ourTexture;\n"
        "\n"
        "void main()\n"
        "{\n"
        "    FragColor = texture(ourTexture, TexCoord);\n"
        "}";

    unsigned int fragment_shader;
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment_shader, 1, &fragment_shader_src, NULL);
    glCompileShader(fragment_shader);

    int  success0;
    char infoLog0[512];
    glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success0);

    if (!success0) {
        glGetShaderInfoLog(fragment_shader, 512, NULL, infoLog0);
        printf("%s\n", infoLog0);
    }

    unsigned int shaderProgram;
    shaderProgram = glCreateProgram();

    glAttachShader(shaderProgram, vertex_shader);
    glAttachShader(shaderProgram, fragment_shader);
    glLinkProgram(shaderProgram);

    int success1;
    char infoLog1[512];

    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success1);
    if(!success1) {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog1);
        printf("%s\n", infoLog1);
    }

    float vertices[] = {
         // positions          // colors           // texture coords
         0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f,   // top right
         0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f,   // bottom right
        -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,   // bottom left
        -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f    // top left 
    }; 

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

    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
    glEnableVertexAttribArray(2);

    // render loop
    while(!glfwWindowShouldClose(window)) {
        processInput(window);

        //state* current_state = ((state*)sm->states->items[sm->stateindex]);

        glClear(GL_COLOR_BUFFER_BIT);
        // render here
        glClearColor(
            0.0f,//current_state->background_color->r,        
            0.0f,//current_state->background_color->g, 
            0.0f,//current_state->background_color->b,
            0.0f//current_state->background_color->a
        );

        glUseProgram(shaderProgram);

        draw_texture(tex, vbo, vao, ebo);
        // for testing purposes only
        //sm->stateindex = sm->stateindex < 2 ? (sm->stateindex + 1) : 0;

        glfwSwapBuffers(window);
        glfwPollEvents();    
    }

    glfwTerminate();
    return 0;
}

Итак, я пытаюсь создать клетчатый узор, а затем нарисовать его на экране. Я следовал упражнениям на learnopengl.com ... Я не понимаю, что я делаю неправильно. Любая помощь?

Я использую язык C и OpenGL 4.5

Я пытаюсь изучить современный OpenGL, я использовал фиксированный конвейер, который во многих отношениях сильно отличался.

1 Ответ

0 голосов
/ 14 января 2019

Программа в ее нынешнем виде не заполняет буфер индекса элемента (ebo) данными. Без буфера индексов элементов glDrawElements не имеет ничего, чтобы рисовать индексы элементов, и поэтому ничего не будет делать.

РЕДАКТИРОВАТЬ 1: Также ваш объект буфера вершин (vbo) используется только для одного из 3 атрибутов, необходимых для ваших шейдеров. Вы устанавливаете только указатель атрибута координаты текстуры, но не положение и не цвета.

РЕДАКТ. 2: Кроме того, вы не устанавливаете форму сэмплера.

РЕДАКТИРОВАТЬ 3: И последнее, но не менее важное: вы создаете контекст основного профиля, но используете устаревший - и, следовательно, ядро ​​недоступно - формат текстуры GL_LUMINANCE. Вы должны использовать GL_RED для текстуры одного канала.


Исходный код исправленной программы, которая визуализирует текстуру шахматной доски:

#include <epoxy/gl.h>
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
//#include "include/state.h"
//#include "include/state_machine.h"
//#include "include/renderable.h"


const int WIDTH = 800;
const int HEIGHT = 600;

// called when user resizes window
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
    glViewport(0, 0, width, height);
}

// called when we receive input
void processInput(GLFWwindow *window) {
    if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, 1);
}

GLuint get_checker_texture() {
    unsigned char texDat[64];
    for (int i = 0; i < 64; ++i)
        texDat[i] = ((i + (i / 8)) % 2) * 128 + 127;

    //upload to GPU texture
    GLuint tex;
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 8, 8, 0, GL_RED, GL_UNSIGNED_BYTE, texDat);
    glGenerateMipmap(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, 0);

    return tex;
}

//void render_box(renderable* this, unsigned int vbo, unsigned int vao, unsigned int ebo) {
//    draw_texture(this->texture, this->x, this->y, this->z, vbo, vao, ebo);
//}

int main(int argc, char* argv[]) {
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    #ifdef __APPLE__
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // only on MACOS
    #endif

    // creating the window
    GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "OpenGL App", NULL, NULL);
    if (window == NULL) {
        printf("Failed to create GLFW window");
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);

    // hook on window resize
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    glViewport(0, 0, WIDTH, HEIGHT);

    // just making sure the state machine works
    // for testing purposes only
    /*state_machine* sm = init_state_machine();
    state* state0 = init_state();

    state* state1 = init_state();
    state1->background_color->r = 1.0f;

    state* state2 = init_state();
    state2->background_color->g = 1.0f;

    ss_vector_append(sm->states, state0);
    ss_vector_append(sm->states, state1);
    ss_vector_append(sm->states, state2);*/

    //renderable* box = init_renderable(0.0f, 0.0f, 0.0f, &render_box);
    unsigned int tex = get_checker_texture();

    const char* vertex_shader_src =
        "#version 330 core\n"
        "layout (location = 0) in vec3 aPos;\n"
        "layout (location = 1) in vec3 aColor;\n"
        "layout (location = 2) in vec2 aTexCoord;\n"
        "\n"
        "out vec3 ourColor;\n"
        "out vec2 TexCoord;\n"
        "\n"
        "void main()\n"
        "{\n"
        "    gl_Position = vec4(aPos, 1.0);\n"
        "    ourColor = aColor;\n"
        "    TexCoord = aTexCoord;\n"
        "}";

    unsigned int vertex_shader;
    vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex_shader, 1, &vertex_shader_src, NULL);
    glCompileShader(vertex_shader); 

    int  success;
    char infoLog[512];
    glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);

    if (!success) {
        glGetShaderInfoLog(vertex_shader, 512, NULL, infoLog);
        printf("%s\n", infoLog);
    }

    const char* fragment_shader_src = 
        "#version 330 core\n"
        "out vec4 FragColor;\n"
        "\n" 
        "in vec3 ourColor;\n"
        "in vec2 TexCoord;\n"
        "\n"
        "uniform sampler2D ourTexture;\n"
        "\n"
        "void main()\n"
        "{\n"
        "    FragColor = vec4(vec3(texture(ourTexture, TexCoord).r), 1.);\n"
        "}";

    unsigned int fragment_shader;
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment_shader, 1, &fragment_shader_src, NULL);
    glCompileShader(fragment_shader);

    int  success0;
    char infoLog0[512];
    glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success0);

    if (!success0) {
        glGetShaderInfoLog(fragment_shader, 512, NULL, infoLog0);
        printf("%s\n", infoLog0);
    }

    unsigned int shaderProgram;
    shaderProgram = glCreateProgram();

    glAttachShader(shaderProgram, vertex_shader);
    glAttachShader(shaderProgram, fragment_shader);
    glLinkProgram(shaderProgram);

    unsigned uniform_sampler_ourTexture = glGetUniformLocation(shaderProgram, "ourTexture");

    int success1;
    char infoLog1[512];

    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success1);
    if(!success1) {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog1);
        printf("%s\n", infoLog1);
    }

    float vertices[] = {
         // positions          // colors           // texture coords
         0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f,   // top right
         0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f,   // bottom right
        -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,   // bottom left
        -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f    // top left 
    }; 

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

    unsigned int vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    unsigned int vbo;
    glGenBuffers(1, &vbo);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(0 * sizeof(float)));
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
    glEnableVertexAttribArray(2);

    unsigned int ebo;
    glGenBuffers(1, &ebo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);

    // render loop
    while(!glfwWindowShouldClose(window)) {
        processInput(window);

        //state* current_state = ((state*)sm->states->items[sm->stateindex]);

        glClear(GL_COLOR_BUFFER_BIT);
        // render here
        glClearColor(
            0.2f,//current_state->background_color->r,        
            0.3f,//current_state->background_color->g, 
            0.3f,//current_state->background_color->b,
            1.0f//current_state->background_color->a
        );

        glUseProgram(shaderProgram);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, tex);
    glUniform1i(uniform_sampler_ourTexture, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

        glfwSwapBuffers(window);
        glfwPollEvents();    
    }

    glfwTerminate();
    return 0;
}
...