1
0
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:
Daniel Evans 2014-02-10 08:55:01 +00:00
parent 975c7a5c32
commit d9bb0be308
8 changed files with 90 additions and 193 deletions

View File

@ -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.
*/

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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()

View File

@ -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) {

View File

@ -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) {

View File

@ -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)