因此,我制作了具有三个主要文件的程序:
当我实现对象类时(在我只有椭圆形对象之前,然后我决定制作一个矩形并发现一些共同点),我遇到了一个问题,那就是在屏幕上什么也没出现。 >
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), ¢er);
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;
}
答案 0 :(得分:1)
经过多次尝试,我终于找到了问题所在:
在GLObjects.h文件中,我将一些变量声明为静态变量,因为如果不这样做,它将生成一些多定义错误。将它们声明为静态可以解决该问题,但会创建另一个问题,因为现在每个文件都有这些变量的副本。
因此,为了解决该问题,我要做的是将这些变量声明为extern,然后在GLObject.cpp文件中定义它们。