Permalink
Browse files

Empty Primitives Fix & Better Graphical Debug Messages (#1365)

* Defaulted `vertex_colored` to true so we only add a color if you did specify a vertex but didn't specify a color (to prevent us adding a color if you didn't specify any vertex; safety for empty primitives basically)
* Added a debug message to `d3d_model_primitive_begin` to warn you if you didn't end the last primitive
* Added a debug message to `d3d_model_primitive_end` to warn you if you didn't even start a primitive
* Added a debug message to `d3d_model_primitive_end` to warn you if you didn't specify any vertex data and did not specify a valid vertex format, because one cannot be guessed based on the specification
* Added a debug message to `d3d_model_primitive_end` to warn you if you didn't specify any vertex data but you did specify a valid vertex format and the primitive is effectively empty
* Added a debug message to `vertex_format_begin` to warn you if you didn't end the last vertex format
* Added a debug message to `vertex_format_end` to warn you if you didn't even start a vertex format
* Moved `RESOURCE_EXISTS` macro inside anonymous namespace
  • Loading branch information...
RobertBColton committed Aug 24, 2018
1 parent 4e05f61 commit 21dce9bcc32963b788547db96c2215579970993a
@@ -26,6 +26,7 @@
#include "GSmatrix.h"
#include "GStextures.h"

#include "Widget_Systems/widgets_mandatory.h"
#include "Universal_System/fileio.h"

#include <math.h>
@@ -166,6 +167,7 @@ void d3d_model_clear(int id) {
model->primitives.clear();
model->current_primitive = 0;
model->vertex_started = false;
model->vertex_colored = true;
}

void d3d_model_draw(int id) {
@@ -212,11 +214,18 @@ void d3d_model_draw(int id, gs_scalar x, gs_scalar y, gs_scalar z, int texId) {

void d3d_model_primitive_begin(int id, int kind, int format) {
enigma::Model* model = enigma::models[id];
#ifdef DEBUG_MODE
if (model->current_primitive) {
show_error("d3d_model_primitive_begin called again without ending " \
"the previous primitive for model: " + std::to_string(id), false);
return;
}
#endif
if (!model->vertex_started) {
model->vertex_started = true;
vertex_begin(model->vertex_buffer);
}

model->vertex_colored = true;
model->current_primitive = new enigma::Primitive(
kind,
format,
@@ -227,27 +236,52 @@ void d3d_model_primitive_begin(int id, int kind, int format) {

void d3d_model_primitive_end(int id) {
enigma::Model* model = enigma::models[id];
#ifdef DEBUG_MODE
if (!model->current_primitive) {
show_error("d3d_model_primitive_end called for model " + std::to_string(id) + " and no current primitive exists! " \
"This can occur if you call end without actually calling begin.", false);
return;
}
#endif
// copy current primitive to the stack
enigma::Primitive primitive = *model->current_primitive;
// delete the current primitive from the heap
delete model->current_primitive;
model->current_primitive = 0;

if (model->use_draw_color && !model->vertex_colored) {
vertex_color(model->vertex_buffer, model->vertex_color, model->vertex_alpha);
}

// if we are guessing the format of the model, end the vertex format now
// if the primitive doesn't have a valid vertex format
// and one does exist that we were guessing, then end
// that vertex format now
if (!vertex_format_exists(primitive.format)) {
// we can't do anything if we can't figure out the format
if (!vertex_format_exists()) {
#ifdef DEBUG_MODE
show_error("d3d_model_primitive_end called for primitive of model " + std::to_string(id) + " that has " \
"non-existant vertex format and one could not be determined based on vertex specification", false);
#endif
return;
}
if (!primitive.format_defined && model->use_draw_color && !model->vertex_colored) {
vertex_format_add_color();
}
model->vertex_colored = false;
primitive.format = vertex_format_end();
primitive.format_defined = true;
}

// if the last vertex didn't specify a color then we have to do so now
if (model->use_draw_color && !model->vertex_colored) {
vertex_color(model->vertex_buffer, model->vertex_color, model->vertex_alpha);
model->vertex_colored = true;
}

size_t vertex_size = vertex_get_buffer_size(model->vertex_buffer) - primitive.vertex_offset;
#ifdef DEBUG_MODE
// there's ZERO reason to keep an empty primitive
if (!vertex_size) {
show_error("A primitive was ended that had 0 size on model: " + std::to_string(id), false);
return;
}
#endif
primitive.vertex_count = vertex_size / vertex_format_get_stride_size(primitive.format);

// combine adjacent primitives that are list types with logically the same format
@@ -67,7 +67,7 @@ struct Model {

Model(int type, bool use_draw_color):
type(type), vertex_buffer(-1), current_primitive(0), vertex_started(false), use_draw_color(use_draw_color),
vertex_colored(false), vertex_color(enigma_user::c_white), vertex_alpha(1.0) {}
vertex_colored(true), vertex_color(enigma_user::c_white), vertex_alpha(1.0) {}
};


@@ -33,8 +33,6 @@

#include <unordered_map>

#define RESOURCE_EXISTS(id, container) return (id >= 0 && (unsigned)id < enigma::container.size() && enigma::container[id] != nullptr);

namespace {

// cache of all vertex formats that are logically unique
@@ -45,6 +43,8 @@ std::unordered_map<size_t, int> vertexFormatCache;
// NOTE: this is NULl outside of vertex_format_begin and vertex_format_end
enigma::VertexFormat* currentVertexFormat = 0;

#define RESOURCE_EXISTS(id, container) return (id >= 0 && (unsigned)id < enigma::container.size() && enigma::container[id] != nullptr);

} // anonymous namespace

namespace enigma {
@@ -58,6 +58,12 @@ vector<IndexBuffer*> indexBuffers;
namespace enigma_user {

void vertex_format_begin() {
#ifdef DEBUG_MODE
if (currentVertexFormat) {
show_error("vertex_format_begin called again without ending the previous format", false);
vertex_format_end();
}
#endif
currentVertexFormat = new enigma::VertexFormat();
}

@@ -99,6 +105,13 @@ void vertex_format_add_custom(int type, int usage) {

int vertex_format_end() {
int id = -1;
#ifdef DEBUG_MODE
if (!currentVertexFormat) {
show_error("vertex_format_end called and no current vertex format exists! " \
"This can occur if you call end without actually calling begin.", false);
return id;
}
#endif
auto search = vertexFormatCache.find(currentVertexFormat->hash);
if (search != vertexFormatCache.end()) {
id = search->second;

0 comments on commit 21dce9b

Please sign in to comment.