c++ - 为什么使用程序会导致我的形状消失?

标签 c++ opengl sfml glm-math

以下代码在屏幕上绘制了一个白色方 block 。如果我取消注释使用该程序的行,方 block 就会消失。

当我使用 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;
}

最佳答案

这是两件事的结合。

当我上次使用这段代码时,它与 GLM 0.9.7.6 一起使用,mat4() 生成了一个单位矩阵。然而,在该版本的 GLM 和我当前使用的版本 (0.9.9.5) 之间的某个时刻,mat4() 开始生成一个空矩阵。相反,您需要 mat4(1.0f)

此外,我对近平面和远平面使用了错误的值。我确实认为我拥有的值(value)观会奏效,但显然我不太了解幕后发生的事情。

关于c++ - 为什么使用程序会导致我的形状消失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56615890/

相关文章:

c++ - 简单代码的意外结果

c - 为什么 GLfloat 需要全局作用域?

java - OpenGL 深度缓冲区未应用

c++ - 多个 Cmake 文件和 SFML "fatal error: SFML/Graphics.hpp: No such file or directory"

c++ - 有比 JPEG 更快的有损压缩吗?

c++ - 将内存复制到 std::copy

C++ 头文件包括组织

qt - 如何从 QGraphicsItem::paint() 中将 QGLFrameBufferObject 绘制到画家上

shader - SFML 着色器制服 : passing my own class

c++ - 如何在 VertexArray 中翻转纹理?