Files
wc3re/render/Object.cc

108 lines
3.0 KiB
C++

#include <glbinding/gl/gl.h>
#include <glm/gtx/transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "Object.hh"
#include "ProgramProvider.hh"
#include "Renderer.hh"
#include "ObjDecoder.hh"
using namespace gl;
namespace render {
namespace {
struct VertexAttribs {
int32_t vertex[3];
uint16_t texCoords[2];
} __attribute__((__packed__));
}
Object::Object(Renderer& renderer, ObjDecoder& obj)
: Drawable(renderer),
vbo_()
{
program_ = ProgramProvider::getInstance().getProgram("object", "object");
auto& tris = obj.getTriangles();
auto& quads = obj.getQuads();
numVertices_ = (tris.size()*3+quads.size()*6);
vbo_ = VBOManager::getInstance().alloc(sizeof(VertexAttribs)*numVertices_);
glGenVertexArrays(1, &vertexArray_.get());
std::vector<VertexAttribs> vertexAttribs;
vertexAttribs.reserve(numVertices_);
auto& vertices = obj.getVertices();
for (auto& tri : tris) {
for (unsigned i = 0;i < 3;++i) {
VertexAttribs attrs;
std::copy(vertices.at(tri.vertIdx[i]).begin(), vertices.at(tri.vertIdx[i]).end(),
attrs.vertex);
std::copy(tri.texCoords[i].begin(), tri.texCoords[i].end(),
attrs.texCoords);
vertexAttribs.push_back(attrs);
}
}
for (auto& quad : quads) {
for (unsigned i = 0;i < 3;++i) {
VertexAttribs attrs;
std::copy(vertices.at(quad.vertIdx[i]).begin(), vertices.at(quad.vertIdx[i]).end(),
attrs.vertex);
std::copy(quad.texCoords[i].begin(), quad.texCoords[i].end(),
attrs.texCoords);
vertexAttribs.push_back(attrs);
}
for (unsigned i = 0;i < 3;++i) {
VertexAttribs attrs;
std::copy(vertices.at(quad.vertIdx[i+1]).begin(), vertices.at(quad.vertIdx[i+1]).end(),
attrs.vertex);
std::copy(quad.texCoords[i+1].begin(), quad.texCoords[i+1].end(),
attrs.texCoords);
vertexAttribs.push_back(attrs);
}
}
// std::vector<VertexAttribs> vertexAttribs = {
// {{-1500, -1500, 0}, {0, 0}},
// {{-1500, 1500, 0}, {0, 0}},
// {{1500, -1500, 0}, {0, 0}},
// {{1500, 1500, 0}, {0, 0}}};
glBindBuffer(GL_ARRAY_BUFFER, vbo_.getVBOId());
glBindVertexArray(vertexArray_);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_INT, GL_FALSE, sizeof(VertexAttribs),
vbo_.getOfs(offsetof(VertexAttribs, vertex)));
glBufferSubData(GL_ARRAY_BUFFER, vbo_.getBase(),
sizeof(VertexAttribs)*numVertices_,
vertexAttribs.data());
mvp_ = glm::perspectiveFov(75.0f, static_cast<float>(renderer.getWidth()),
static_cast<float>(renderer.getHeight()),
100.f, 20000.0f) *
glm::lookAt(glm::vec3(0.0f, 0.0f, 10000),
glm::vec3(0.0f, 0.0f, 0),
glm::vec3(0, 1, 0));
}
void Object::draw()
{
glDisable(GL_CULL_FACE);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glUseProgram(program_);
glUniformMatrix4fv(0, 1, GL_FALSE, glm::value_ptr(mvp_));
glBindVertexArray(vertexArray_);
glDrawArrays(GL_TRIANGLES, 0, numVertices_);
}
}