OpenGL / GLFW C ++程序未绘制任何内容

时间:2018-11-21 18:24:12

标签: c++ opengl glfw glew

因此,我制作了具有三个主要文件的程序:

  • 一个main.cpp文件,其中包含程序本身
  • 其中一个包含GLObject类,它是每个对象的基类
  • 一个包含Ellipse类的派生对象

当我实现对象类时(在我只有椭圆形对象之前,然后我决定制作一个矩形并发现一些共同点),我遇到了一个问题,那就是在屏幕上什么也没出现。 >

GLObject.cpp包含“ GLObjectsInit()”函数的定义,该函数设置绘图程序(draw_program)以及该程序中声明的unfiorm块的所有偏移量和矩阵步长。

void GLObjectsInit()
{
    CompileDrawProgram(); // Compiles the draw_program

    coord_loc = glGetAttribLocation(draw_program, "coord");
    color_loc = glGetAttribLocation(draw_program, "color");

    static const GLchar* uniformNames[4] = {
        "TransformBlock.res",
        "TransformBlock.tsl",
        "TransformBlock.rot",
        "TransformBlock.scale"
    };
    GLuint uniformIndices[4];
    glGetUniformIndices(draw_program, 4, uniformNames, uniformIndices);

    GLint uniformOffsets[4];
    GLint matrixStrides[4];
    glGetActiveUniformsiv(draw_program, 4, uniformIndices, GL_UNIFORM_OFFSET, uniformOffsets);
    glGetActiveUniformsiv(draw_program, 4, uniformIndices, GL_UNIFORM_MATRIX_STRIDE, matrixStrides);

    resolution_offset = uniformOffsets[0];
    translation_offset = uniformOffsets[1];
    rotation_matrix_offset = uniformOffsets[2];
    rotation_matrix_stride = uniformOffsets[2];
    scale_offset = uniformOffsets[3];
}

绘图程序:

顶点着色器:

#version 450 core
in vec4 coord;
in vec4 color;
layout(std140, binding = 0) uniform TransformBlock
{
    vec4 res;
    vec4 tsl;
    vec4 scale;
    mat4 rot;
} trs;

out vec4 color_vs;
void main(void)
{
    color_vs = color;
    gl_Position = ((coord * trs.scale * trs.rot) + trs.tsl) * trs.res;
}

片段着色器:

#version 450 core

out vec4 color;
in vec4 color_vs;

void main(void)
{
    color = color_vs;
}

.h文件仅包含要包含的标头和一些静态变量的声明(声​​明为静态以避免多定义错误):

#define _USE_MATH_DEFINES
#include <math.h>
#include <glm.hpp>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>

static GLuint draw_program;

static GLuint coord_loc, color_loc;
static GLuint resolution_offset, translation_offset, scale_offset;
static GLuint rotation_matrix_offset, rotation_matrix_stride;

椭圆对象有一些方法可以修改对象的位置和比例,还有一个draw()方法(我只写draw()方法和构造函数,因为我不认为其他方法会涉及问题)。

Ellipse.h:

#include "GLObject.h"

class Ellipse//: public GLObject
{
protected:
    GLuint points_buffer, uniforms_buffer, vao;
    vertex* points;
    unsigned int size;
    bool fill;

    double ang;
    glm::mat4 rotation_matrix;
    glm::vec4 center, scale;

public:
    void Draw();

    //Other methods

    Ellipse(double w, double h, glm::vec4 cen, bool fill, glm::vec4 col = glm::vec4(1, 1, 1, 1));
    Ellipse(double r, glm::vec4 cen, bool fill, glm::vec4 col = glm::vec4(1, 1, 1, 1)) :
        Ellipse(r, r, cen, fill, col) {}

    ~Ellipse();
};

Ellipse.cpp:

#include "Ellipse.h"
using namespace std;

void Ellipse::Draw()
{
    GLFWwindow* window = glfwGetCurrentContext();

    glUseProgram(draw_program);
    glBindVertexArray(vao);
    glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniforms_buffer);

    int w, h;   glm::vec4 res;
    glfwGetFramebufferSize(window, &w, &h);
    glViewport(0, 0, w, h);

    if (w > h) res = glm::vec4(static_cast<float>(h) / w, 1, 1, 1);
    else       res = glm::vec4(1, static_cast<float>(w) / h, 1, 1);

    glNamedBufferSubData(uniforms_buffer, resolution_offset, sizeof(glm::vec4), &res);

    if (fill) glDrawArrays(GL_TRIANGLES, 0, size);
    else      glDrawArrays(GL_LINES, 0, size);
}

Ellipse::Ellipse(double w, double h, glm::vec4 cen, bool fill, glm::vec4 col)
{
    // Calculate the ellipse

    glCreateVertexArrays(1, &vao);

    glCreateBuffers(1, &uniforms_buffer);
    glNamedBufferStorage(uniforms_buffer, sizeof(GLfloat) * 112, NULL, GL_DYNAMIC_STORAGE_BIT);

    glCreateBuffers(1, &points_buffer);
    glNamedBufferStorage(points_buffer, sizeof(vertex) * size, points, GL_DYNAMIC_STORAGE_BIT);
    glVertexArrayVertexBuffer(vao, 0, points_buffer, 0, sizeof(vertex));

    glVertexArrayAttribBinding(vao, coord_loc, 0);
    glVertexArrayAttribFormat(vao, coord_loc, 4, GL_FLOAT, GL_FALSE, offsetof(vertex, coord));
    glEnableVertexArrayAttrib(vao, coord_loc);

    glVertexArrayAttribBinding(vao, color_loc, 0);
    glVertexArrayAttribFormat(vao, color_loc, 4, GL_FLOAT, GL_FALSE, offsetof(vertex, color));
    glEnableVertexArrayAttrib(vao, color_loc);

    center = cen;   ang = 0;
    scale = glm::vec4(w, h, 1, 1);
    rotation_matrix = glm::mat4(1);

    glNamedBufferSubData(uniforms_buffer, scale_offset, sizeof(glm::vec4), &scale);
    glNamedBufferSubData(uniforms_buffer, translation_offset, sizeof(glm::vec4), &center);
    glNamedBufferSubData(uniforms_buffer, rotation_matrix_offset, sizeof(glm::mat4), &rotation_matrix[0]);
}

Ellipse::~Ellipse()
{
    glDeleteBuffers(1, &points_buffer);
    glDeleteBuffers(1, &uniforms_buffer);
    glDeleteVertexArrays(1, &vao);
    delete[] points;
}

主要是:

#include "Ellipse.h"
using namespace std;

int main()
{
    glfwInit();

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);

    GLFWwindow* window = glfwCreateWindow(500, 500, "Title", NULL, NULL);
    glfwMakeContextCurrent(window);

    glewExperimental = GL_TRUE;
    glewInit();

    glfwSwapInterval(1);

    GLObjectsInit();
    Ellipse ball1(0.25, 0.25, glm::vec4(0, 0, 0.5, 1), true);

    while (!glfwWindowShouldClose(window))
    {
        glfwPollEvents();
        glClear(GL_COLOR_BUFFER_BIT);
        ball1.Draw();
        glfwSwapBuffers(window);
    }
    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

1 个答案:

答案 0 :(得分:1)

经过多次尝试,我终于找到了问题所在:

在GLObjects.h文件中,我将一些变量声明为静态变量,因为如果不这样做,它将生成一些多定义错误。将它们声明为静态可以解决该问题,但会创建另一个问题,因为现在每个文件都有这些变量的副本。

因此,为了解决该问题,我要做的是将这些变量声明为extern,然后在GLObject.cpp文件中定义它们。