mirror of
https://github.com/rwengine/openrw.git
synced 2024-09-18 16:32:32 +02:00
Use new drawing structures
This commit is contained in:
parent
975c7a5c32
commit
d9bb0be308
@ -7,6 +7,7 @@ class GeometryBuffer;
|
||||
class DrawBuffer {
|
||||
GLuint vao;
|
||||
|
||||
GLenum facetype;
|
||||
public:
|
||||
|
||||
DrawBuffer();
|
||||
@ -15,6 +16,12 @@ public:
|
||||
GLuint getVAOName() const
|
||||
{ return vao; }
|
||||
|
||||
void setFaceType(GLenum ft)
|
||||
{ facetype = ft; }
|
||||
|
||||
GLenum getFaceType() const
|
||||
{ return facetype; }
|
||||
|
||||
/**
|
||||
* Adds a Geometry Buffer to the Draw Buffer.
|
||||
*/
|
||||
|
@ -48,7 +48,6 @@ public:
|
||||
|
||||
GLint uniModel, uniProj, uniView, uniCol, uniAmbientCol, uniSunDirection, uniDynamicCol;
|
||||
GLint uniMatDiffuse, uniMatAmbient, uniFogStart, uniFogEnd;
|
||||
GLint posAttrib, normalAttrib, texAttrib, colourAttrib;
|
||||
GLuint worldProgram;
|
||||
GLuint skyProgram;
|
||||
GLint skyUniView, skyUniProj, skyUniTop, skyUniBottom;
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <loaders/rwbinarystream.h>
|
||||
#include "DrawBuffer.hpp"
|
||||
#include "GeometryBuffer.hpp"
|
||||
|
||||
/**
|
||||
* Frame
|
||||
@ -90,8 +92,27 @@ public:
|
||||
size_t numIndices;
|
||||
};
|
||||
|
||||
struct GeometryVertex {
|
||||
glm::vec3 position; /* 0 */
|
||||
glm::vec3 normal; /* 24 */
|
||||
glm::vec2 texcoord; /* 48 */
|
||||
glm::vec4 colour; /* 64 */
|
||||
|
||||
static const AttributeList vertex_attributes() {
|
||||
return {
|
||||
{ATRS_Position, 3, sizeof(GeometryVertex), 0ul},
|
||||
{ATRS_Normal, 3, sizeof(GeometryVertex), sizeof(float)*3},
|
||||
{ATRS_TexCoord, 2, sizeof(GeometryVertex), sizeof(float)*6},
|
||||
{ATRS_Colour, 4, sizeof(GeometryVertex), sizeof(float)*8}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
struct Geometry {
|
||||
GLuint VBO, EBO;
|
||||
DrawBuffer dbuff;
|
||||
GeometryBuffer gbuff;
|
||||
|
||||
GLuint EBO;
|
||||
|
||||
RW::BSGeometryBounds geometryBounds;
|
||||
|
||||
@ -100,39 +121,12 @@ public:
|
||||
FaceType facetype;
|
||||
|
||||
uint32_t flags;
|
||||
|
||||
size_t offsVert;
|
||||
std::vector<glm::vec3> vertices;
|
||||
size_t offsNormals;
|
||||
std::vector<glm::vec3> normals;
|
||||
size_t offsTexCoords;
|
||||
std::vector<glm::vec2> texcoords;
|
||||
size_t offsColours;
|
||||
std::vector<glm::vec4> colours;
|
||||
|
||||
size_t indicesCount;
|
||||
|
||||
std::vector<Material> materials;
|
||||
std::vector<SubGeometry> subgeom;
|
||||
|
||||
Geometry();
|
||||
~Geometry();
|
||||
|
||||
void setVertexData(const std::vector<glm::vec3>& vertices) {
|
||||
this->vertices = vertices;
|
||||
}
|
||||
void setColours(const std::vector<glm::vec4>& colours) {
|
||||
this->colours = colours;
|
||||
}
|
||||
void setTexCoords(const std::vector<glm::vec2>& coords) {
|
||||
this->texcoords = coords;
|
||||
}
|
||||
void setNormals(const std::vector<glm::vec3>& normals) {
|
||||
this->normals = normals;
|
||||
}
|
||||
void generateNormals();
|
||||
|
||||
void buildBuffers();
|
||||
};
|
||||
|
||||
struct Atomic {
|
||||
|
@ -88,8 +88,9 @@ Model* LoaderDFF::loadFromMemory(char *data, GameData *gameData)
|
||||
if (item.header.versionid < 0x1003FFFF)
|
||||
/*auto colors =*/ readStructure<RW::BSGeometryColor>(data, dataI);
|
||||
|
||||
std::vector<glm::vec4> colours;
|
||||
colours.resize(geometry.numverts);
|
||||
std::vector<Model::GeometryVertex> vertices;
|
||||
vertices.resize(geometry.numverts);
|
||||
|
||||
if ((geometry.flags & RW::BSGeometry::VertexColors) == RW::BSGeometry::VertexColors) {
|
||||
for (size_t v = 0; v < geometry.numverts; ++v) {
|
||||
auto s = readStructure<RW::BSColor>(data, dataI);
|
||||
@ -97,29 +98,24 @@ Model* LoaderDFF::loadFromMemory(char *data, GameData *gameData)
|
||||
size_t G = s % 256; s /= 256;
|
||||
size_t B = s % 256; s /= 256;
|
||||
size_t A = s % 256;
|
||||
colours[v] = glm::vec4(R/255.f, G/255.f, B/255.f, A/255.f);
|
||||
vertices[v].colour = glm::vec4(R/255.f, G/255.f, B/255.f, A/255.f);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// To save needing another shader, just insert a white colour for each vertex
|
||||
for (size_t v = 0; v < geometry.numverts; ++v) {
|
||||
colours[v] = glm::vec4(1.f);
|
||||
vertices[v].colour = glm::vec4(1.f, 1.f, 1.f, 1.f);
|
||||
}
|
||||
}
|
||||
geom->setColours(colours);
|
||||
|
||||
/** TEX COORDS **/
|
||||
if ((geometry.flags & RW::BSGeometry::TexCoords1) == RW::BSGeometry::TexCoords1 ||
|
||||
(geometry.flags & RW::BSGeometry::TexCoords2) == RW::BSGeometry::TexCoords1) {
|
||||
std::vector<glm::vec2> texcoords;
|
||||
texcoords.resize(geometry.numverts);
|
||||
for (size_t v = 0; v < geometry.numverts; ++v) {
|
||||
texcoords[v] = readStructure<glm::vec2>(data, dataI);
|
||||
vertices[v].texcoord = readStructure<glm::vec2>(data, dataI);
|
||||
}
|
||||
geom->setTexCoords(texcoords);
|
||||
}
|
||||
|
||||
//geometryStruct.triangles.reserve(geometry.numtris);
|
||||
for (int j = 0; j < geometry.numtris; ++j) {
|
||||
readStructure<RW::BSGeometryTriangle>(data, dataI);
|
||||
}
|
||||
@ -128,23 +124,20 @@ Model* LoaderDFF::loadFromMemory(char *data, GameData *gameData)
|
||||
geom->geometryBounds = readStructure<RW::BSGeometryBounds>(data, dataI);
|
||||
|
||||
/** VERTICES **/
|
||||
std::vector<glm::vec3> positions;
|
||||
positions.resize(geometry.numverts);
|
||||
for (size_t v = 0; v < geometry.numverts; ++v) {
|
||||
positions[v] = readStructure<glm::vec3>(data, dataI);
|
||||
vertices[v].position = readStructure<glm::vec3>(data, dataI);
|
||||
}
|
||||
geom->setVertexData(positions);
|
||||
|
||||
|
||||
/** NORMALS **/
|
||||
if ((geometry.flags & RW::BSGeometry::StoreNormals) == RW::BSGeometry::StoreNormals) {
|
||||
std::vector<glm::vec3> normals;
|
||||
normals.reserve(geometry.numverts);
|
||||
for (size_t v = 0; v < geometry.numverts; ++v) {
|
||||
normals[v] = readStructure<glm::vec3>(data, dataI);
|
||||
vertices[v].normal = readStructure<glm::vec3>(data, dataI);
|
||||
}
|
||||
geom->setNormals(normals);
|
||||
}
|
||||
else {
|
||||
for (size_t v = 0; v < geometry.numverts; ++v) {
|
||||
vertices[v].normal = glm::vec3(0.f, 0.f, 1.f);
|
||||
}
|
||||
// Generate normals.
|
||||
/*geometryStruct.normals.resize(geometry.numverts);
|
||||
for (auto &subgeom : geometryStruct.subgeom) {
|
||||
@ -242,6 +235,7 @@ Model* LoaderDFF::loadFromMemory(char *data, GameData *gameData)
|
||||
geom->subgeom.resize(meshplg.numsplits);
|
||||
geom->facetype = static_cast<Model::FaceType>(meshplg.facetype);
|
||||
size_t meshplgI = sizeof(RW::BSBinMeshPLG);
|
||||
size_t sgstart = 0;
|
||||
for(size_t i = 0; i < meshplg.numsplits; ++i)
|
||||
{
|
||||
auto plgHeader = extsec.readSubStructure<RW::BSMaterialSplit>(meshplgI);
|
||||
@ -249,6 +243,8 @@ Model* LoaderDFF::loadFromMemory(char *data, GameData *gameData)
|
||||
geom->subgeom[i].material = plgHeader.index;
|
||||
geom->subgeom[i].indices = new uint32_t[plgHeader.numverts];
|
||||
geom->subgeom[i].numIndices = plgHeader.numverts;
|
||||
geom->subgeom[i].start = sgstart;
|
||||
sgstart += plgHeader.numverts;
|
||||
for (int j = 0; j < plgHeader.numverts; ++j) {
|
||||
geom->subgeom[i].indices[j] = extsec.readSubStructure<uint32_t>(meshplgI);
|
||||
meshplgI += sizeof(uint32_t);
|
||||
@ -257,8 +253,29 @@ Model* LoaderDFF::loadFromMemory(char *data, GameData *gameData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
geom->buildBuffers();
|
||||
|
||||
/* Upload Vertex Data */
|
||||
|
||||
/* uploadVertices uses magic to determine what is inside vertices */
|
||||
geom->gbuff.uploadVertices(vertices);
|
||||
/* dbuff asks gbuff for it's contents */
|
||||
geom->dbuff.addGeometry(&geom->gbuff);
|
||||
|
||||
/* TODO: Migrate indicies to new framework */
|
||||
glGenBuffers(1, &geom->EBO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geom->EBO);
|
||||
|
||||
size_t icount = std::accumulate(
|
||||
geom->subgeom.begin(),
|
||||
geom->subgeom.end(), 0u,
|
||||
[](size_t a, const Model::SubGeometry& b) {return a + b.numIndices;});
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * icount, 0, GL_STATIC_DRAW);
|
||||
for(auto& sg : geom->subgeom) {
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,
|
||||
sg.start * sizeof(uint32_t),
|
||||
sizeof(uint32_t) * sg.numIndices,
|
||||
sg.indices);
|
||||
}
|
||||
|
||||
geom->clumpNum = clumpID;
|
||||
|
||||
|
@ -5,9 +5,9 @@
|
||||
/* TODO: Come up with a more elegant solution to "WHICH ARRAY IS IT?" */
|
||||
std::map<AttributeSemantic, GLuint> semantic_to_attrib_array = {
|
||||
{ATRS_Position, 0},
|
||||
{ATRS_Normal, 4},
|
||||
{ATRS_Colour, 8},
|
||||
{ATRS_TexCoord, 12}
|
||||
{ATRS_Normal, 1},
|
||||
{ATRS_Colour, 2},
|
||||
{ATRS_TexCoord, 3}
|
||||
};
|
||||
|
||||
DrawBuffer::DrawBuffer()
|
||||
|
@ -14,11 +14,11 @@
|
||||
#include <cmath>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
const char *vertexShaderSource = "#version 130\n"
|
||||
"in vec3 position;"
|
||||
"in vec3 normal;"
|
||||
"in vec2 texCoords;"
|
||||
"in vec4 colour;"
|
||||
const char *vertexShaderSource = "#version 130\n#extension GL_ARB_explicit_attrib_location : enable\n"
|
||||
"layout(location = 0) in vec3 position;"
|
||||
"layout(location = 1) in vec3 normal;"
|
||||
"layout(location = 2) in vec4 colour;"
|
||||
"layout(location = 3) in vec2 texCoords;"
|
||||
"out vec3 Normal;"
|
||||
"out vec2 TexCoords;"
|
||||
"out vec4 Colour;"
|
||||
@ -136,12 +136,7 @@ GTARenderer::GTARenderer(GameWorld* engine)
|
||||
glAttachShader(worldProgram, fragmentShader);
|
||||
glLinkProgram(worldProgram);
|
||||
glUseProgram(worldProgram);
|
||||
|
||||
posAttrib = glGetAttribLocation(worldProgram, "position");
|
||||
texAttrib = glGetAttribLocation(worldProgram, "texCoords");
|
||||
normalAttrib = glGetAttribLocation(worldProgram, "normal");
|
||||
colourAttrib = glGetAttribLocation(worldProgram, "colour");
|
||||
|
||||
|
||||
uniModel = glGetUniformLocation(worldProgram, "model");
|
||||
uniView = glGetUniformLocation(worldProgram, "view");
|
||||
uniProj = glGetUniformLocation(worldProgram, "proj");
|
||||
@ -385,6 +380,8 @@ void GTARenderer::renderWorld()
|
||||
}
|
||||
transparentDrawQueue.clear();
|
||||
|
||||
glBindVertexArray( vao );
|
||||
|
||||
glUseProgram(skyProgram);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, skydomeVBO);
|
||||
@ -478,27 +475,12 @@ bool GTARenderer::renderFrame(Model* m, ModelFrame* f, const glm::mat4& matrix,
|
||||
return true;
|
||||
}
|
||||
|
||||
static GLuint currentVBO = 0;
|
||||
|
||||
bool GTARenderer::renderSubgeometry(Model* model, size_t g, size_t sg, const glm::mat4& matrix, GTAObject* object, bool queueTransparent)
|
||||
{
|
||||
if(currentVBO != model->geometries[g]->VBO) {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, model->geometries[g]->VBO);
|
||||
|
||||
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)model->geometries[g]->offsVert);
|
||||
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)model->geometries[g]->offsTexCoords);
|
||||
glVertexAttribPointer(normalAttrib, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)model->geometries[g]->offsNormals);
|
||||
glVertexAttribPointer(colourAttrib, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*)model->geometries[g]->offsColours);
|
||||
glEnableVertexAttribArray(posAttrib);
|
||||
glEnableVertexAttribArray(texAttrib);
|
||||
glEnableVertexAttribArray(normalAttrib);
|
||||
glEnableVertexAttribArray(colourAttrib);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->geometries[g]->EBO);
|
||||
|
||||
currentVBO = model->geometries[g]->VBO;
|
||||
}
|
||||
|
||||
glBindVertexArray(model->geometries[g]->dbuff.getVAOName());
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->geometries[g]->EBO);
|
||||
|
||||
auto& subgeom = model->geometries[g]->subgeom[sg];
|
||||
|
||||
if (model->geometries[g]->materials.size() > subgeom.material) {
|
||||
|
@ -6,6 +6,13 @@ GeometryBuffer::GeometryBuffer()
|
||||
|
||||
}
|
||||
|
||||
GeometryBuffer::~GeometryBuffer()
|
||||
{
|
||||
if(vbo != 0) {
|
||||
glDeleteBuffers(1, &vbo);
|
||||
}
|
||||
}
|
||||
|
||||
void GeometryBuffer::uploadVertices(GLsizei num, GLsizeiptr size, const GLvoid* mem)
|
||||
{
|
||||
if(vbo == 0) {
|
||||
|
@ -6,122 +6,13 @@
|
||||
|
||||
|
||||
Model::Geometry::Geometry()
|
||||
: VBO(0), EBO(0),
|
||||
flags(0)
|
||||
: flags(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Model::Geometry::~Geometry()
|
||||
{
|
||||
if(VBO != 0) {
|
||||
glDeleteBuffers(1, &VBO);
|
||||
}
|
||||
if(EBO != 0) {
|
||||
glDeleteBuffers(1, &EBO);
|
||||
}
|
||||
}
|
||||
|
||||
void Model::Geometry::generateNormals()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Model::Geometry::buildBuffers()
|
||||
{
|
||||
// OpenGL buffer stuff
|
||||
glGenBuffers(1, &VBO);
|
||||
glGenBuffers(1, &EBO);
|
||||
|
||||
size_t buffsize = (vertices.size() * sizeof(glm::vec3))
|
||||
+ texcoords.size() * sizeof(glm::vec2)
|
||||
+ normals.size() * sizeof(glm::vec3)
|
||||
+ colours.size() * sizeof(glm::vec4);
|
||||
|
||||
// Vertices
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, buffsize, NULL, GL_STATIC_DRAW);
|
||||
|
||||
size_t dataOffset = 0;
|
||||
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
0,
|
||||
(vertices.size() * sizeof(glm::vec3)),
|
||||
vertices.data()
|
||||
);
|
||||
offsVert = dataOffset;
|
||||
dataOffset += (vertices.size() * sizeof(glm::vec3));
|
||||
|
||||
if(texcoords.size() > 0)
|
||||
{
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
dataOffset,
|
||||
(texcoords.size() * sizeof(glm::vec2)),
|
||||
texcoords.data()
|
||||
);
|
||||
offsTexCoords = dataOffset;
|
||||
dataOffset += (texcoords.size() * sizeof(glm::vec2));
|
||||
}
|
||||
else {
|
||||
offsTexCoords = -1;
|
||||
}
|
||||
|
||||
if(normals.size() > 0)
|
||||
{
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
dataOffset,
|
||||
(normals.size() * sizeof(glm::vec3)),
|
||||
normals.data()
|
||||
);
|
||||
offsNormals = dataOffset;
|
||||
dataOffset += (normals.size() * sizeof(glm::vec3));
|
||||
}
|
||||
else {
|
||||
offsNormals = -1;
|
||||
}
|
||||
|
||||
if(colours.size() > 0)
|
||||
{
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
dataOffset,
|
||||
colours.size() * sizeof(glm::vec4),
|
||||
colours.data()
|
||||
);
|
||||
offsColours = dataOffset;
|
||||
}
|
||||
else {
|
||||
offsColours = -1;
|
||||
}
|
||||
|
||||
size_t Ecount = 0;
|
||||
for(size_t i = 0; i < subgeom.size(); ++i)
|
||||
{
|
||||
subgeom[i].start = Ecount;
|
||||
Ecount += subgeom[i].numIndices;
|
||||
}
|
||||
indicesCount = Ecount;
|
||||
|
||||
// Allocate complete EBO buffer.
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
glBufferData(
|
||||
GL_ELEMENT_ARRAY_BUFFER,
|
||||
sizeof(uint32_t) * indicesCount,
|
||||
nullptr,
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
// Upload each subgeometry
|
||||
for(size_t i = 0; i < subgeom.size(); ++i)
|
||||
{
|
||||
glBufferSubData(
|
||||
GL_ELEMENT_ARRAY_BUFFER,
|
||||
subgeom[i].start * sizeof(uint32_t),
|
||||
sizeof(uint32_t) * subgeom[i].numIndices,
|
||||
subgeom[i].indices);
|
||||
}
|
||||
}
|
||||
|
||||
ModelFrame::ModelFrame(ModelFrame* parent, glm::mat3 dR, glm::vec3 dT)
|
||||
|
Loading…
Reference in New Issue
Block a user