Skip to content

Commit

Permalink
use index buffer and defer buffer write to first frame
Browse files Browse the repository at this point in the history
  • Loading branch information
RobertBColton committed Jun 17, 2018
1 parent 992042d commit f1e4b09
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 108 deletions.
6 changes: 4 additions & 2 deletions ENIGMAsystem/SHELL/Graphics_Systems/Direct3D9/DX9screen.cpp
Expand Up @@ -18,7 +18,7 @@
#include "Graphics_Systems/graphics_mandatory.h"
#include "Graphics_Systems/General/GSsprite.h"
#include "Graphics_Systems/General/GSbackground.h"
#include "Graphics_Systems/General/GStiles.h"
#include "Graphics_Systems/General/GStilestruct.h"
#include "Graphics_Systems/General/GSscreen.h"
#include "Graphics_Systems/General/GSd3d.h"
#include "Graphics_Systems/General/GSvertex.h"
Expand Down Expand Up @@ -141,12 +141,14 @@ static inline void draw_insts()
*/
static inline int draw_tiles()
{
enigma::load_tiles();
for (enigma::diter dit = drawing_depths.rbegin(); dit != drawing_depths.rend(); dit++)
{
if (dit->second.tiles.size())
{
auto buffers = tile_layer_buffers[dit->second.tiles[0].depth];
for (auto &t : tile_layer_metadata[dit->second.tiles[0].depth]){
enigma_user::vertex_submit(tile_layer_buffers[dit->second.tiles[0].depth], enigma_user::pr_trianglelist, t[0], t[1], t[2]);
enigma_user::index_submit(buffers.second, buffers.first, enigma_user::pr_trianglelist, t[0], t[1], t[2]);
}
}
enigma::inst_iter* push_it = enigma::instance_event_iterator;
Expand Down
156 changes: 61 additions & 95 deletions ENIGMAsystem/SHELL/Graphics_Systems/General/GStiles.cpp
Expand Up @@ -18,30 +18,35 @@
#include "GSprimitives.h"
#include "GSbackground.h"
#include "GStextures.h"
#include "GStiles.h"
#include "GSvertex.h"
#include "GStiles.h"
#include "GStilestruct.h"
#include "GSvertex_impl.h"

#include "Universal_System/depth_draw.h"
#include "Universal_System/background.h"
#include "Universal_System/background_internal.h"

#include <algorithm>

std::map<int,int> tile_layer_buffers;
//Tile vector holds several values, like number of vertices to render, texture to use and so on
//The structure is like this [render batch][batch info]
//batch info - 0 = texture to use, 1 = vertices to render,
std::map<int,std::vector<std::vector<int> > > tile_layer_metadata;

// not allowed to include mathnc.h outside of SHELLmain
namespace enigma_user {
bool point_in_rectangle(ma_scalar px, ma_scalar py, ma_scalar x1, ma_scalar y1, ma_scalar x2, ma_scalar y2);
}

namespace enigma
{
static void draw_tile(int index, int back, gs_scalar left, gs_scalar top, gs_scalar width, gs_scalar height, gs_scalar x, gs_scalar y, gs_scalar xscale, gs_scalar yscale, int color, double alpha)
std::map<int,std::pair<int, int> > tile_layer_buffers;
//Tile vector holds several values, like number of vertices to render, texture to use and so on
//The structure is like this [render batch][batch info]
//batch info - 0 = texture to use, 1 = vertices to render,
std::map<int,std::vector<std::vector<int> > > tile_layer_metadata;

bool tiles_are_dirty = true;

bkinxop bkinxcomp;

static void draw_tile(int &ind, int index, int vertex, int back, gs_scalar left, gs_scalar top, gs_scalar width, gs_scalar height, gs_scalar x, gs_scalar y, gs_scalar xscale, gs_scalar yscale, int color, double alpha)
{
if (!enigma_user::background_exists(back)) return;
get_background(bck2d,back);
Expand All @@ -53,40 +58,33 @@ namespace enigma
tbx1 = tbx+left/tbw, tbx2 = tbx1 + width/tbw,
tby1 = tby+top/tbh, tby2 = tby1 + height/tbh;

//TODO: The model should probably be populated manually along with indicies. The _end() calls a lot of useless code now. Upside is that this needs to be done once.
enigma_user::vertex_position(index, xvert1, yvert1);
enigma_user::vertex_texcoord(index, tbx1, tby1);
enigma_user::vertex_color(index, color, alpha);

enigma_user::vertex_position(index, xvert2, yvert1);
enigma_user::vertex_texcoord(index, tbx2, tby1);
enigma_user::vertex_color(index, color, alpha);

enigma_user::vertex_position(index, xvert1, yvert2);
enigma_user::vertex_texcoord(index, tbx1, tby2);
enigma_user::vertex_color(index, color, alpha);

enigma_user::vertex_position(index, xvert1, yvert2);
enigma_user::vertex_texcoord(index, tbx1, tby2);
enigma_user::vertex_color(index, color, alpha);

enigma_user::vertex_position(index, xvert2, yvert1);
enigma_user::vertex_texcoord(index, tbx2, tby1);
enigma_user::vertex_color(index, color, alpha);

enigma_user::vertex_position(index, xvert2, yvert2);
enigma_user::vertex_texcoord(index, tbx2, tby2);
enigma_user::vertex_color(index, color, alpha);
/*
enigma_user::d3d_model_vertex_texture_color(index, xvert1, yvert1, tbx1, tby1, color, alpha);
enigma_user::d3d_model_vertex_texture_color(index, xvert2, yvert1, tbx2, tby1, color, alpha);
enigma_user::d3d_model_vertex_texture_color(index, xvert1, yvert2, tbx1, tby2, color, alpha);
enigma_user::d3d_model_vertex_texture_color(index, xvert2, yvert2, tbx2, tby2, color, alpha);
*/
enigma_user::vertex_position(vertex, xvert1, yvert1);
enigma_user::vertex_texcoord(vertex, tbx1, tby1);
enigma_user::vertex_color(vertex, color, alpha);

enigma_user::vertex_position(vertex, xvert2, yvert1);
enigma_user::vertex_texcoord(vertex, tbx2, tby1);
enigma_user::vertex_color(vertex, color, alpha);

enigma_user::vertex_position(vertex, xvert1, yvert2);
enigma_user::vertex_texcoord(vertex, tbx1, tby2);
enigma_user::vertex_color(vertex, color, alpha);

enigma_user::vertex_position(vertex, xvert2, yvert2);
enigma_user::vertex_texcoord(vertex, tbx2, tby2);
enigma_user::vertex_color(vertex, color, alpha);

IndexBuffer* indexBuffer = indexBuffers[index];
int indices[] = {ind + 0, ind + 1, ind + 2, ind + 2, ind + 1, ind + 3};
indexBuffer->indices.insert(indexBuffer->indices.end(), indices, indices + 6);
ind += 4;
}

void load_tiles()
{
if (!tiles_are_dirty) return;
tiles_are_dirty = false;

static int vertexFormat = -1;
if (vertexFormat == -1) {
enigma_user::vertex_format_begin();
Expand All @@ -96,32 +94,37 @@ namespace enigma
vertexFormat = enigma_user::vertex_format_end();
}
static int vertexBuffer = enigma_user::vertex_create_buffer();
static int indexBuffer = enigma_user::index_create_buffer();
enigma_user::vertex_clear(vertexBuffer);
enigma_user::index_clear(indexBuffer);
enigma_user::vertex_begin(vertexBuffer, vertexFormat);
enigma_user::index_begin(indexBuffer, enigma_user::index_type_ushort);

int prev_bkid;
int vertex_start = 0;
int vertex_count = 0;
int index_start = 0;
int index_count = 0;
int vertex_ind = 0;
for (enigma::diter dit = drawing_depths.rbegin(); dit != drawing_depths.rend(); dit++){
if (dit->second.tiles.size())
{
//TODO: Should they really be sorted by background? This may help batching, but breaks compatiblity. Nothing texture atlas wouldn't solve.
sort(dit->second.tiles.begin(), dit->second.tiles.end(), bkinxcomp);
tile_layer_buffers[dit->second.tiles[0].depth] = vertexBuffer;
tile_layer_buffers[dit->second.tiles[0].depth] = { vertexBuffer, indexBuffer };
for(std::vector<tile>::size_type i = 0; i != dit->second.tiles.size(); ++i)
{
tile t = dit->second.tiles[i];
if (i==0){ prev_bkid = t.bckid; }
draw_tile(vertexBuffer, t.bckid, t.bgx, t.bgy, t.width, t.height, t.roomX, t.roomY, t.xscale, t.yscale, t.color, t.alpha);
vertex_count += 6;
draw_tile(vertex_ind, indexBuffer, vertexBuffer, t.bckid, t.bgx, t.bgy, t.width, t.height, t.roomX, t.roomY, t.xscale, t.yscale, t.color, t.alpha);
index_count += 6;
if (prev_bkid != t.bckid || i == dit->second.tiles.size()-1){ //Texture switch has happened. Create new batch
get_background(bck2d,prev_bkid);
tile_layer_metadata[dit->second.tiles[0].depth].push_back( std::vector< int >(3) );
tile_layer_metadata[dit->second.tiles[0].depth].back()[0] = bck2d->texture;
tile_layer_metadata[dit->second.tiles[0].depth].back()[1] = vertex_start;
tile_layer_metadata[dit->second.tiles[0].depth].back()[2] = vertex_count;
tile_layer_metadata[dit->second.tiles[0].depth].back()[1] = index_start;
tile_layer_metadata[dit->second.tiles[0].depth].back()[2] = index_count;

vertex_start += vertex_count;
vertex_count = 0;
index_start += index_count;
index_count = 0;

prev_bkid = t.bckid;
}
Expand All @@ -131,65 +134,26 @@ namespace enigma
}

enigma_user::vertex_end(vertexBuffer);
enigma_user::index_end(indexBuffer);
enigma_user::vertex_freeze(vertexBuffer);
enigma_user::index_freeze(indexBuffer);
}

void delete_tiles()
{
for (enigma::diter dit = drawing_depths.rbegin(); dit != drawing_depths.rend(); dit++){
if (dit->second.tiles.size()){
tile_layer_metadata[dit->second.tiles[0].depth].clear();
enigma_user::vertex_delete_buffer( tile_layer_buffers[dit->second.tiles[0].depth] );
auto buffers = tile_layer_buffers[dit->second.tiles[0].depth];
enigma_user::vertex_delete_buffer(buffers.first);
enigma_user::index_delete_buffer(buffers.second);
}
}
}

void rebuild_tile_layer(int layer_depth)
{
/*
int prev_bkid;
for (enigma::diter dit = drawing_depths.rbegin(); dit != drawing_depths.rend(); dit++){
if (dit->second.tiles.size())
{
if (dit->second.tiles[0].depth != layer_depth)
continue;
//TODO: Should they really be sorted by background? This may help batching, but breaks compatiblity. Nothing texture atlas wouldn't solve.
//sort(dit->second.tiles.begin(), dit->second.tiles.end(), bkinxcomp);
int index = tile_layer_buffers[dit->second.tiles[0].depth];
if (enigma_user::d3d_model_exists( index )) {
enigma_user::d3d_model_clear( index );
tile_layer_metadata[dit->second.tiles[0].depth].clear();
} else {
index = enigma_user::d3d_model_create(false);
tile_layer_buffers[dit->second.tiles[0].depth] = index;
}
int vert_size = 0;
int vert_start = 0;
for(std::vector<tile>::size_type i = 0; i != dit->second.tiles.size(); ++i)
{
tile t = dit->second.tiles[i];
if (i==0){ prev_bkid = t.bckid; }
draw_tile(index, t.bckid, t.bgx, t.bgy, t.width, t.height, t.roomX, t.roomY, t.xscale, t.yscale, t.color, t.alpha);
if (prev_bkid != t.bckid || i == dit->second.tiles.size()-1){ //Texture switch has happened. Create new batch
get_background(bck2d,prev_bkid);
tile_layer_metadata[dit->second.tiles[0].depth].push_back( std::vector< int >(3) );
tile_layer_metadata[dit->second.tiles[0].depth].back()[0] = bck2d->texture;
tile_layer_metadata[dit->second.tiles[0].depth].back()[1] = vert_start;
tile_layer_metadata[dit->second.tiles[0].depth].back()[2] = vert_size;
//printf("Texture id = %i and vertices to render = %i and start = %i\n", prev_bkid, vert_size, vert_start );
vert_start += vert_size;
vert_size = 0;
//printf("Texture switch at i = %i and now texture = %i\n", i, prev_bkid );
prev_bkid = t.bckid;
}
vert_size+=6;
//printf("Tile = %i, vertices = %i, prev_bkid = %i, t.bckid = %i, size() = %i\n", i, vert_size,prev_bkid, t.bckid, dit->second.tiles.size() );
}
tile_layer_metadata[dit->second.tiles[0].depth].back()[2] += 6; //Add last quad
break;
}
}*/
tiles_are_dirty = true;
}
}

Expand Down Expand Up @@ -504,7 +468,9 @@ bool tile_layer_delete(int layer_depth)
{
if (dit->second.tiles[0].depth != layer_depth)
continue;
vertex_delete_buffer(tile_layer_buffers[dit->second.tiles[0].depth]);
auto buffers = enigma::tile_layer_buffers[dit->second.tiles[0].depth];
vertex_delete_buffer(buffers.first);
index_delete_buffer(buffers.second);
dit->second.tiles.clear();
return true;
}
Expand Down Expand Up @@ -537,7 +503,7 @@ bool tile_layer_depth(int layer_depth, int depth)
{
if (dit->second.tiles[0].depth != layer_depth)
continue;
tile_layer_buffers[depth] = tile_layer_buffers[layer_depth];
enigma::tile_layer_buffers[depth] = enigma::tile_layer_buffers[layer_depth];
for(std::vector<enigma::tile>::size_type i = 0; i != dit->second.tiles.size(); i++)
{
enigma::tile t = dit->second.tiles[i];
Expand Down
6 changes: 0 additions & 6 deletions ENIGMAsystem/SHELL/Graphics_Systems/General/GStiles.h
Expand Up @@ -19,12 +19,6 @@

#include "Universal_System/scalar.h"

#include <map>
#include <vector>

extern std::map<int,int> tile_layer_buffers;
extern std::map<int,std::vector<std::vector<int> > > tile_layer_metadata;

namespace enigma_user
{
int tile_add(int background, int left, int top, int width, int height, int x, int y, int depth, double xscale = 1.0, double yscale = 1.0, double alpha = 1, int color = 0xFFFFFF);
Expand Down
16 changes: 15 additions & 1 deletion ENIGMAsystem/SHELL/Graphics_Systems/General/GStilestruct.h
Expand Up @@ -15,16 +15,30 @@
*** with this code. If not, see <http://www.gnu.org/licenses/>
**/

#ifdef INCLUDED_FROM_SHELLMAIN
# error This file includes non-ENIGMA STL headers and should not be included from SHELLmain.
#endif

#ifndef ENIGMA_GSTILESTRUCT_H
#define ENIGMA_GSTILESTRUCT_H

#include "Universal_System/roomsystem.h"

#include <map>
#include <vector>

namespace enigma
{
extern std::map<int,std::pair<int, int> > tile_layer_buffers;
extern std::map<int,std::vector<std::vector<int> > > tile_layer_metadata;

struct bkinxop
{
bool operator() (const tile a, const tile b) {return (a.bckid < b.bckid);}
} bkinxcomp;
};

extern bkinxop bkinxcomp;

void draw_tile();
void delete_tiles();
void load_tiles();
Expand Down
6 changes: 4 additions & 2 deletions ENIGMAsystem/SHELL/Graphics_Systems/OpenGL1/GLscreen.cpp
Expand Up @@ -20,7 +20,7 @@
#include "Graphics_Systems/General/GSsprite.h"
#include "Graphics_Systems/General/GSbackground.h"
#include "Graphics_Systems/General/GSscreen.h"
#include "Graphics_Systems/General/GStiles.h"
#include "Graphics_Systems/General/GStilestruct.h"
#include "Graphics_Systems/General/GSd3d.h"
#include "Graphics_Systems/General/GSvertex.h"
#include "Graphics_Systems/General/GSprimitives.h"
Expand Down Expand Up @@ -138,12 +138,14 @@ static inline void draw_insts()
*/
static inline int draw_tiles()
{
enigma::load_tiles();
for (enigma::diter dit = drawing_depths.rbegin(); dit != drawing_depths.rend(); dit++)
{
if (dit->second.tiles.size())
{
auto buffers = tile_layer_buffers[dit->second.tiles[0].depth];
for (auto &t : tile_layer_metadata[dit->second.tiles[0].depth]){
enigma_user::vertex_submit(tile_layer_buffers[dit->second.tiles[0].depth], enigma_user::pr_trianglelist, t[0], t[1], t[2]);
enigma_user::index_submit(buffers.second, buffers.first, enigma_user::pr_trianglelist, t[0], t[1], t[2]);
}
}
enigma::inst_iter* push_it = enigma::instance_event_iterator;
Expand Down
6 changes: 4 additions & 2 deletions ENIGMAsystem/SHELL/Graphics_Systems/OpenGL3/GL3screen.cpp
Expand Up @@ -18,7 +18,7 @@
#include "Graphics_Systems/graphics_mandatory.h"
#include "Graphics_Systems/General/OpenGLHeaders.h"
#include "Graphics_Systems/General/GStextures.h"
#include "Graphics_Systems/General/GStiles.h"
#include "Graphics_Systems/General/GStilestruct.h"
#include "Graphics_Systems/General/GSsprite.h"
#include "Graphics_Systems/General/GSbackground.h"
#include "Graphics_Systems/General/GSscreen.h"
Expand Down Expand Up @@ -144,12 +144,14 @@ static inline void draw_insts()
*/
static inline int draw_tiles()
{
enigma::load_tiles();
for (enigma::diter dit = drawing_depths.rbegin(); dit != drawing_depths.rend(); dit++)
{
if (dit->second.tiles.size())
{
auto buffers = tile_layer_buffers[dit->second.tiles[0].depth];
for (auto &t : tile_layer_metadata[dit->second.tiles[0].depth]){
enigma_user::vertex_submit(tile_layer_buffers[dit->second.tiles[0].depth], enigma_user::pr_trianglelist, t[0], t[1], t[2]);
enigma_user::index_submit(buffers.second, buffers.first, enigma_user::pr_trianglelist, t[0], t[1], t[2]);
}
}
enigma::inst_iter* push_it = enigma::instance_event_iterator;
Expand Down

0 comments on commit f1e4b09

Please sign in to comment.