Текстуры не рисовать OpenGL - PullRequest
0 голосов
/ 08 мая 2018

У меня странное поведение при попытке нарисовать текстуру в OpenGL. В настоящее время все, что делает эта программа для меня, это рисование цвета фона без указания нарисованной текстуры. Я только что перешел из Visual Studio (где этот код производит правильный вывод) для компиляции в командной строке. Этот код должен раскрасить фон и нарисовать одну текстуру в центре экрана.

Я обеспокоен тем, что, возможно, предоставил неверные библиотеки для компиляции, поскольку все, что я делаю, одинаково. Однако разные библиотеки всегда говорили, что они несовместимы.

Основной код:

#define GLEW_STATIC
#include <GL/glew.h> // window management library
#include <GL/glfw3.h>
#include <GL/glm.hpp>
#include <GL/gtc/matrix_transform.hpp> //

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

int main(int argc, char** argv){

    //Initialize GLFW and GLEW...
    //Setup and combine shaders...

    GLint vertex_att = glGetAttribLocation(program, "vertex");
    glVertexAttribPointer(vertex_att, 2, GL_FLOAT, GL_FALSE, 7*sizeof(GLfloat), 0);
    glEnableVertexAttribArray(vertex_att);

    GLint color_att = glGetAttribLocation(program, "color");
    glVertexAttribPointer(color_att, 3, GL_FLOAT, GL_FALSE, 7*sizeof(GLfloat), (void *) (2 *sizeof(GLfloat)));
    glEnableVertexAttribArray(color_att);

    GLint tex_att = glGetAttribLocation(program, "uv");
    glVertexAttribPointer(tex_att, 2, GL_FLOAT, GL_FALSE, 7*sizeof(GLfloat), (void *) (5 *sizeof(GLfloat)));
    glEnableVertexAttribArray(tex_att);

    glUseProgram(program);

    GLuint texture;
    glGenTextures(1, &texture);
    setthisTexture(texture, "./black.png");

    // Create geometry of the square
    int size = CreateSquare();

    while (!glfwWindowShouldClose(window)){
        // Clear background
        glClearColor(viewport_background_color_g[0], 
                     viewport_background_color_g[1],
                     viewport_background_color_g[2], 0.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        //set displacement - 'program' being the shader program
        int matrixLocation = glGetUniformLocation(program, "x");

        glm::mat4 translate = glm::mat4();
        translate = glm::translate(translate, glm::vec3(0.0f, 0.0f, 0.0f));

        glUniformMatrix4fv(matrixLocation, 1, GL_FALSE, &translate[0][0]);
        glBindTexture(GL_TEXTURE_2D, texture);
        glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);

        glfwPollEvents();

        glfwSwapBuffers(window);
    }
}

Вершинный шейдер:

#version 130

in vec2 vertex;
in vec3 color;
in vec2 uv;
out vec2 uv_interp;

// Uniform (global) buffer
uniform mat4 x;

// Attributes forwarded to the fragment shader
out vec4 color_interp;

void main(){
    vec4 t;
    t = vec4(vertex, 0.0, 1.0);
    gl_Position = x*t;

    color_interp = vec4(color, 1.0);
    uv_interp = uv;
}

Фрагмент шейдера:

#version 130

in vec4 color_interp;
in vec2 uv_interp;

uniform sampler2D onetex;

void main(){
    vec4 color = texture2D(onetex, uv_interp);
    gl_FragColor = vec4(color.r,color.g,color.b,color.a);
    if(gl_FragColor.a < 0.9){
        discard;
    }
}

setthisTexture:

void setthisTexture(GLuint w, const char *fname)
{
    glBindTexture(GL_TEXTURE_2D, w);

    int width, height, nrChannels;
    unsigned char* image = stbi_load(fname, &width, &height, &nrChannels, 0);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
    stbi_image_free(image);

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

CreateSquare:

int CreateSquare(void) {

    // The face of the square is defined by four vertices and two triangles

    // Number of attributes for vertices and faces
    //  const int vertex_att = 7;  // 7 attributes per vertex: 2D (or 3D) position (2), RGB color (3), 2D texture coordinates (2)
    //  const int face_att = 3; // Vertex indices (3)

    GLfloat vertex[]  = {
        //  square (two triangles)
        //  Position     Color                  Texcoords
        -0.5f, 0.5f,     1.0f, 0.0f, 0.0f,      0.0f, 0.0f, // Top-left
        0.5f, 0.5f,      0.0f, 1.0f, 0.0f,      1.0f, 0.0f, // Top-right
        0.5f, -0.5f,     0.0f, 0.0f, 1.0f,      1.0f, 1.0f, // Bottom-right
        -0.5f, -0.5f,    1.0f, 1.0f, 1.0f,      0.0f, 1.0f  // Bottom-left
    };

    GLuint face[] = {
        0, 1, 2, // t1
        2, 3, 0  //t2
    };

    GLuint vbo, ebo;

    // Create buffer for vertices
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW);

    // Create buffer for faces (index buffer)
    glGenBuffers(1, &ebo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(face), face, GL_STATIC_DRAW);

    // Return number of elements in array buffer
    return sizeof(face);
}

1 Ответ

0 голосов
/ 08 мая 2018

Для использования glVertexAttribPointer необходимо связать именованный буферный объект GL_ARRAY_BUFFER или передать указатель на данные вершины.

В вашем случае это означает, что

int size = CreateSquare();

должно быть сделано до

GLint vertex_att = glGetAttribLocation(program, "vertex");
glVertexAttribPointer(vertex_att, 2, GL_FLOAT, GL_FALSE, 7*sizeof(GLfloat), 0);
glEnableVertexAttribArray(vertex_att);

.....


Обратите внимание, что в функции CreateSquare указанный буферный объект vbo связан:

glBindBuffer(GL_ARRAY_BUFFER, vbo);

, который используется glVertexAttribPointer звонками.


См. Спецификация профиля совместимости API OpenGL 4.6; 10.3.9. Вершинные массивы в буферных объектах; страница 409 :

Точка привязки объекта буфера добавляется к состоянию клиента, связанному с каждым тип и индекс массива вершин. Команды, которые определяют местоположения и организации из вершинных массивов скопировать имя объекта буфера, который связан с ARRAY_- BUFFER к точке привязки, соответствующей типу массива вершин или индексу указано. Например, команда VertexAttribPointer копирует значение ARRAY_BUFFER_BINDING (запрашиваемое имя привязки буфера, соответствующее к целевому ARRAY_BUFFER) к переменной состояния клиента VERTEX_ATTRIB_- ARRAY_BUFFER_BINDING для указанного индекса.

...