Почему при использовании программы моя фигура исчезает? - PullRequest
1 голос
/ 16 июня 2019

Следующий код рисует белый квадрат на экране.Если я раскомментирую строку, в которой используется программа, квадрат исчезнет.

Когда я отлаживаю программу с помощью GLIntercept, текстура появляется в папке с именем Images, и в журнале говорится, что шейдеры скомпилированы.Тем не менее, это также говорит о том, что программа ссылается, но не проверяет.

Я изучал это в течение нескольких часов и понятия не имею, куда идти.

// Vertex.vert
#version 150 core

in vec3 in_position;
in vec2 in_texture;

out vec2 Texture;

uniform mat4 in_model;
uniform mat4 in_view;
uniform mat4 in_projection;

void main()
{
    gl_Position = in_projection * in_view * in_model * vec4(in_position, 1.0);
    Texture = in_texture;
}

// Fragment.frag
#version 150 core

in vec2 Texture;

out vec4 Colour;

uniform sampler2D Sampler2D;

void main()
{
    Colour = texture(Sampler2D, Texture);
}

// Source.cpp
#include <cfloat>
#include <iostream>
#include <string>
#include <vector>

#include <GL/glew.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/transform.hpp>

#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>

#include "Archive.h"

using namespace glm;
using namespace sf;
using namespace std;

struct Camera
{
    vec3 Position = { 0.0f, 0.0f, 1.0f };
    vec3 Target = { 0.0f, 0.0f, 0.0f };
    vec3 Up = { 0.0f, 1.0f, 0.0f };

    float Fovy = 74.0f;
    float Aspect = 16.0f / 9.0f;
    float ZNear = FLT_MIN;
    float ZFar = FLT_MAX;

    mat4 View;
    mat4 Projection;
};

struct Actor
{
    vec3 Scale = { 1.0f, 1.0f, 1.0f };
    vec3 Rotation = { 0.0f, 0.0f, 0.0f };
    vec3 Position = { 0.0f, 0.0f, 0.0f };

    vector<GLfloat> Vertices;
    vector<GLuint> Elements;

    GLuint Texture;

    Actor(string fileName)
    {
        Image image;

        if (!image.loadFromFile(fileName + ".png"))
        {
            cerr << "ERROR: Unable to load texture" << endl;
        }

        glGenTextures(1, &Texture);
        glBindTexture(GL_TEXTURE_2D, Texture);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.getSize().x, image.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glGenerateMipmap(GL_TEXTURE_2D);

        // Draw a square instead of the actual model
        Vertices.push_back(-1.0f); Vertices.push_back(-1.0f); Vertices.push_back(0.0f); Vertices.push_back(0.0f); Vertices.push_back(0.0f);
        Vertices.push_back(1.0f);  Vertices.push_back(-1.0f); Vertices.push_back(0.0f); Vertices.push_back(1.0f); Vertices.push_back(0.0f);
        Vertices.push_back(1.0f);  Vertices.push_back(1.0f);  Vertices.push_back(0.0f); Vertices.push_back(1.0f); Vertices.push_back(1.0f);
        Vertices.push_back(-1.0f); Vertices.push_back(1.0f);  Vertices.push_back(0.0f); Vertices.push_back(0.0f); Vertices.push_back(1.0f);

        Elements.push_back(0); Elements.push_back(1); Elements.push_back(2);
        Elements.push_back(2); Elements.push_back(3); Elements.push_back(0);
    }
};

GLuint CreateShader(GLenum shaderType, string fileName, Archive& archive)
{
    string source;

    archive.open(fileName);
    source.resize(archive.getSize());
    archive.read(&source[0], archive.getSize());

    GLuint shader = glCreateShader(shaderType);
    const char* pointer = source.c_str();

    glShaderSource(shader, 1, &pointer, nullptr);
    glCompileShader(shader);

    GLsizei length;

    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);

    if (length > 1)
    {
        GLchar* infoLog = new GLchar[length];

        glGetShaderInfoLog(shader, length, &length, infoLog);

        cerr << infoLog << endl;

        delete[] infoLog;
    }

    return shader;
}

GLuint CreateProgram(GLuint vertex, GLuint fragment)
{
    GLuint program = glCreateProgram();

    glAttachShader(program, vertex);
    glAttachShader(program, fragment);

    glLinkProgram(program);

    GLsizei length;

    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);

    if (length > 1)
    {
        GLchar* infoLog = new GLchar[length];

        glGetProgramInfoLog(program, length, &length, infoLog);

        cerr << infoLog << endl;

        delete[] infoLog;
    }

    return program;
}

int main(int argc, char* argv[])
{
    Window window(VideoMode(1920, 1080), "");

    window.setVerticalSyncEnabled(true);

    if (!window.setActive(true))
    {
        cerr << "ERROR: Unable to set the window as the current target for OpenGL rendering" << endl;

        return 1;
    }

    glewExperimental = GL_TRUE;

    if (glewInit() != GLEW_OK)
    {
        cerr << "ERROR: Unable to initialise GLEW" << endl;

        return 1;
    }

    Archive shaders("Shaders.lea");
    Archive models("Models.lea");

    Actor actor("tree01");

    GLuint vertex = CreateShader(GL_VERTEX_SHADER, "Vertex.vert", shaders);
    GLuint fragment = CreateShader(GL_FRAGMENT_SHADER, "Fragment.frag", shaders);
    GLuint program = CreateProgram(vertex, fragment);

    GLuint vertexArray;
    GLuint vertexBuffer;
    GLuint elementBuffer;

    glGenVertexArrays(1, &vertexArray);
    glBindVertexArray(vertexArray);

    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);

    glGenBuffers(1, &elementBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);

    // glUseProgram(program);

    GLint position = glGetAttribLocation(program, "in_position");

    glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, 0);
    glEnableVertexAttribArray(position);

    GLint texture = glGetAttribLocation(program, "in_texture");

    glVertexAttribPointer(texture, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (void*)(sizeof(GLfloat) * 3));
    glEnableVertexAttribArray(texture);

    GLint projection = glGetUniformLocation(program, "in_projection");
    GLint view = glGetUniformLocation(program, "in_view");
    GLint model = glGetUniformLocation(program, "in_model");

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    Camera camera;

    while (window.isOpen())
    {
        // Input handling code omitted

        camera.View = lookAt(camera.Position, camera.Target, camera.Up);
        camera.Projection = perspective(radians(camera.Fovy), camera.Aspect, camera.ZNear, camera.ZFar);

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUniformMatrix4fv(projection, 1, GL_FALSE, value_ptr(camera.Projection));
        glUniformMatrix4fv(view, 1, GL_FALSE, value_ptr(camera.View));

        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * actor.Vertices.size(), &actor.Vertices[0], GL_STATIC_DRAW);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * actor.Elements.size(), &actor.Elements[0], GL_STATIC_DRAW);

        mat4 transform = translate(mat4(), actor.Position);
        transform *= rotate(transform, actor.Rotation.z, vec3(0.0f, 0.0f, 1.0f));
        transform *= rotate(transform, actor.Rotation.y, vec3(0.0f, 1.0f, 0.0f));
        transform *= rotate(transform, actor.Rotation.x, vec3(1.0f, 0.0f, 0.0f));
        transform *= scale(transform, actor.Scale);

        glUniformMatrix4fv(model, 1, GL_FALSE, value_ptr(transform));

        glBindTexture(GL_TEXTURE_2D, actor.Texture);

        glDrawElements(GL_TRIANGLES, actor.Elements.size(), GL_UNSIGNED_INT, 0);

        window.display();
    }

    glUseProgram(0);

    glDisableVertexAttribArray(texture);
    glDisableVertexAttribArray(position);

    glDeleteBuffers(1, &elementBuffer);
    glDeleteBuffers(1, &vertexBuffer);

    glDeleteVertexArrays(1, &vertexArray);

    glDetachShader(program, fragment);
    glDetachShader(program, vertex);

    glDeleteShader(fragment);
    glDeleteShader(vertex);

    glDeleteProgram(program);

    return 0;
}

1 Ответ

1 голос
/ 16 июня 2019

Это была комбинация двух вещей.

Когда я последний раз использовал этот код, он был с GLM 0.9.7.6, а mat4() генерировал матрицу тождественности. Однако в какой-то момент между этой версией GLM и той, которую я сейчас использую (0.9.9.5), mat4() начал генерировать пустую матрицу. Вместо этого вам нужно mat4(1.0f).

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

...