Skip to content

Commit

Permalink
Merge pull request #53 from Ghoster738/mac_fix
Browse files Browse the repository at this point in the history
Made Finalize Workaround Configurable.
  • Loading branch information
Ghoster738 committed May 24, 2024
2 parents f202d9e + 9ce1bb6 commit f60c27b
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 20 deletions.
9 changes: 8 additions & 1 deletion src/Graphics/Environment.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,17 @@ class Environment {
/**
* This sets up bounding box rendering.
* @note This feature is optional, it is only there for debugging purposes.
* @param draw If true then bounding boes
* @param draw If true then bounding boxes
*/
virtual void setBoundingBoxDraw(bool draw) = 0;

/**
* This is to fix synchronization issues with certain graphics cards/drivers.
* @note This feature is TEMPORARY. I will add something far more elegant.
* @param finalize_bitfield If true then bounding boxes
*/
virtual void setDynamicTriangleFinalizeBitfield(unsigned finalize_bitfield) = 0;

/**
* Setup the draw graph for the renderer.
*/
Expand Down
7 changes: 6 additions & 1 deletion src/Graphics/SDL2/GLES2/Environment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Environment::Environment() {
this->display_world = false;
this->has_initialized_routines = false;
this->draw_bounding_boxes = false;
this->temporary_finalize_dynamic_triangle_draw = 0;
}

Environment::~Environment() {
Expand Down Expand Up @@ -324,6 +325,10 @@ void Environment::setBoundingBoxDraw(bool draw) {
this->draw_bounding_boxes = draw;
}

void Environment::setDynamicTriangleFinalizeBitfield(unsigned finalize_bitfield) {
this->temporary_finalize_dynamic_triangle_draw = finalize_bitfield;
}

void Environment::setupFrame() {
for( unsigned int i = 0; i < window_p->getCameras()->size(); i++ )
{
Expand Down Expand Up @@ -384,7 +389,7 @@ void Environment::drawFrame() {
glEnable( GL_BLEND );
glDepthMask(GL_FALSE);

this->dynamic_triangle_draw_routine.draw( *current_camera_r, textures );
this->dynamic_triangle_draw_routine.draw( *current_camera_r, textures, this->temporary_finalize_dynamic_triangle_draw );
current_camera_r->transparent_triangles.reset();
glDepthMask(GL_TRUE);

Expand Down
2 changes: 2 additions & 0 deletions src/Graphics/SDL2/GLES2/Environment.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class Environment : public Graphics::Environment {
Graphics::SDL2::GLES2::Internal::DynamicTriangleDraw dynamic_triangle_draw_routine;

bool draw_bounding_boxes;
unsigned temporary_finalize_dynamic_triangle_draw;

public:
Environment();
Expand All @@ -50,6 +51,7 @@ class Environment : public Graphics::Environment {
virtual int setTilPolygonBlink( unsigned polygon_type, float rate = 1.0f);
virtual bool getBoundingBoxDraw() const;
virtual void setBoundingBoxDraw(bool draw);
virtual void setDynamicTriangleFinalizeBitfield(unsigned finalize_bitfield);
virtual void setupFrame();
virtual void drawFrame();
virtual bool screenshot( Utilities::Image2D &image ) const;
Expand Down
67 changes: 54 additions & 13 deletions src/Graphics/SDL2/GLES2/Internal/DynamicTriangleDraw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,22 @@ struct BlendModeCommand {
GLenum fs_dstRGB;
GLenum fs_srcAlpha;
GLenum fs_dstAlpha;

bool isEqual(const BlendModeCommand &last) const {
if(es_modeRGB != last.es_modeRGB)
return false;
if(es_modeAlpha != last.es_modeAlpha)
return false;
if(fs_srcRGB != last.fs_srcRGB)
return false;
if(fs_dstRGB != last.fs_dstRGB)
return false;
if(fs_srcAlpha != last.fs_srcAlpha)
return false;
if(fs_dstAlpha != last.fs_dstAlpha)
return false;
return true;
}
};

struct DrawTriangleCommand {
Expand Down Expand Up @@ -161,7 +177,9 @@ bool getDrawCommand(const Graphics::SDL2::GLES2::Internal::DynamicTriangleDraw::
}
}

void Graphics::SDL2::GLES2::Internal::DynamicTriangleDraw::DrawCommand::draw( const VertexAttributeArray &vertex_array, const std::map<uint32_t, Graphics::SDL2::GLES2::Internal::Texture2D*> &textures, GLuint diffusive_texture_uniform_id ) const {
void Graphics::SDL2::GLES2::Internal::DynamicTriangleDraw::DrawCommand::draw( const VertexAttributeArray &vertex_array, const std::map<uint32_t, Graphics::SDL2::GLES2::Internal::Texture2D*> &textures, GLuint diffusive_texture_uniform_id, unsigned finalize_bitfield ) const {
bool should_call_finalize = false;

// Do not bother rendering triangles if there are none.
if( triangles_amount == 0 )
return;
Expand All @@ -175,7 +193,10 @@ void Graphics::SDL2::GLES2::Internal::DynamicTriangleDraw::DrawCommand::draw( co
// Bind the vertex array for the triangles.
vertex_array.bind();

DrawTriangleCommand draw_command;
if((finalize_bitfield & 0b001) != 0) // Check for before routine bit.
glFinish();

DrawTriangleCommand draw_command, last_draw_command;

draw_command.triangle_index = 0;

Expand All @@ -185,22 +206,42 @@ void Graphics::SDL2::GLES2::Internal::DynamicTriangleDraw::DrawCommand::draw( co
// Blend mode can affect the rendering.
const BlendModeCommand &blend_mode = draw_command.blend_mode;

// Set the blend method.
glBlendEquationSeparate(blend_mode.es_modeRGB, blend_mode.es_modeAlpha);
glBlendFuncSeparate(blend_mode.fs_srcRGB, blend_mode.fs_dstRGB, blend_mode.fs_srcAlpha, blend_mode.fs_dstAlpha);
// Set the blend method if the draw command is first or if blend method has changed.
if(draw_command.triangle_index == 0 || !last_draw_command.blend_mode.isEqual(blend_mode)) {
glBlendEquationSeparate(blend_mode.es_modeRGB, blend_mode.es_modeAlpha);
glBlendFuncSeparate(blend_mode.fs_srcRGB, blend_mode.fs_dstRGB, blend_mode.fs_srcAlpha, blend_mode.fs_dstAlpha);

// Set the texture.
auto current_texture_r = textures.find( draw_command.texture_id );
if( current_texture_r != textures.end() ) {
current_texture_r->second->bind( 0, diffusive_texture_uniform_id );
// If finalize bit has been set then glFinish should be called.
if((finalize_bitfield & 0b010) != 0)
should_call_finalize = true;
}

// Tell OpenGL to be finished with all the rendering commands before rendering semi-transparent triangles.
glFinish();
if(draw_command.triangle_index == 0 || draw_command.texture_id != last_draw_command.texture_id) {
// Set the texture if it exists.
auto current_texture_r = textures.find( draw_command.texture_id );
if( current_texture_r != textures.end() ) {
current_texture_r->second->bind( 0, diffusive_texture_uniform_id );

if((finalize_bitfield & 0b100) != 0)
should_call_finalize = true;
}
}

if((finalize_bitfield & 0b110) != 0 && draw_command.triangle_index == 0)
should_call_finalize = true;

if(should_call_finalize) {
// Tell OpenGL to be finished with all the rendering commands before rendering semi-transparent triangles.
glFinish();

should_call_finalize = false;
}

// Draw the triangles.
glDrawArrays( GL_TRIANGLES, 3 * draw_command.triangle_index, 3 * draw_command.triangle_count );

last_draw_command = draw_command;

// Increment the triangle index of the draw command. Unless you like infinite cycles.
draw_command.triangle_index += draw_command.triangle_count;
}
Expand Down Expand Up @@ -402,7 +443,7 @@ void Graphics::SDL2::GLES2::Internal::DynamicTriangleDraw::setEnvironmentTexture
this->env_texture_r = env_texture_ref;
}

void Graphics::SDL2::GLES2::Internal::DynamicTriangleDraw::draw( Graphics::SDL2::GLES2::Camera &camera, const std::map<uint32_t, Graphics::SDL2::GLES2::Internal::Texture2D*> &textures ) {
void Graphics::SDL2::GLES2::Internal::DynamicTriangleDraw::draw( Graphics::SDL2::GLES2::Camera &camera, const std::map<uint32_t, Graphics::SDL2::GLES2::Internal::Texture2D*> &textures, unsigned finalize_bitfield ) {
if( camera.transparent_triangles.triangles_amount == 0 )
return; // There is no semi-transparent triangle to draw.

Expand All @@ -428,5 +469,5 @@ void Graphics::SDL2::GLES2::Internal::DynamicTriangleDraw::draw( Graphics::SDL2:
glUniformMatrix4fv( matrix_uniform_id, 1, GL_FALSE, reinterpret_cast<const GLfloat*>( &camera_3D_projection_view[0][0] ) );

camera.transparent_triangles.sortTriangles();
camera.transparent_triangles.draw( vertex_array, textures, diffusive_texture_uniform_id );
camera.transparent_triangles.draw( vertex_array, textures, diffusive_texture_uniform_id, finalize_bitfield );
}
4 changes: 2 additions & 2 deletions src/Graphics/SDL2/GLES2/Internal/DynamicTriangleDraw.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class DynamicTriangleDraw {

// The following methods are for internal use only.
void sortTriangles();
void draw( const VertexAttributeArray &vertex_array, const std::map<uint32_t, Graphics::SDL2::GLES2::Internal::Texture2D*> &textures, GLuint diffusive_texture_uniform_id ) const;
void draw( const VertexAttributeArray &vertex_array, const std::map<uint32_t, Graphics::SDL2::GLES2::Internal::Texture2D*> &textures, GLuint diffusive_texture_uniform_id, unsigned finalize_bitfield ) const;
};
protected:

Expand Down Expand Up @@ -172,7 +172,7 @@ class DynamicTriangleDraw {
* @param camera This is the camera data to be passed into this routine.
* @param textures This is the camera data to be passed into this routine.
*/
void draw( Graphics::SDL2::GLES2::Camera &camera, const std::map<uint32_t, Graphics::SDL2::GLES2::Internal::Texture2D*> &textures );
void draw( Graphics::SDL2::GLES2::Camera &camera, const std::map<uint32_t, Graphics::SDL2::GLES2::Internal::Texture2D*> &textures, unsigned finalize_bitfield );

/**
* @return the program that this World uses.
Expand Down
2 changes: 2 additions & 0 deletions src/MainProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ void MainProgram::setupGraphics() {
if( this->environment_p == nullptr )
throwException( "Sorry, but OpenGL 2/OpenGL ES 2 are the minimum requirements for this engine. Identifier: " + this->graphics_identifier );

this->environment_p->setDynamicTriangleFinalizeBitfield(options.getTemporaryBitfield());

// Declare a pointer
Graphics::Window *window_r = Graphics::Window::alloc( *this->environment_p );

Expand Down
15 changes: 12 additions & 3 deletions src/Utilities/Options/Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const std::string VIDEO = "video";
const std::string VIDEO_WIDTH = "width";
const std::string VIDEO_HEIGHT = "height";
const std::string VIDEO_FULLSCREEN = "fullscreen";
const std::string VIDEO_TEMPORARY_FINALIZE_DYNAMIC_TRIANGLES = "temporary_finalize_dynamic_triangles";

const std::string DATA = "data";
const std::string DATA_LOAD_ALL_MAPS = "load_all_maps";
Expand All @@ -28,9 +29,10 @@ Options::Options (Paths& paths, Parameters& parameters) : paths(paths), paramete
ini_file_p->read(ini_data);

// Default values
init( VIDEO, VIDEO_WIDTH, "800");
init( VIDEO, VIDEO_HEIGHT, "600");
init( VIDEO, VIDEO_FULLSCREEN, "false");
init( VIDEO, VIDEO_WIDTH, "800" );
init( VIDEO, VIDEO_HEIGHT, "600" );
init( VIDEO, VIDEO_FULLSCREEN, "false" );
init( VIDEO, VIDEO_TEMPORARY_FINALIZE_DYNAMIC_TRIANGLES, "0" );

init( DIRECTORIES, DIRECTORIES_SAVES, paths.getUserDirPath( Paths::SAVED_GAMES ));
init( DIRECTORIES, DIRECTORIES_SCREENSHOTS, paths.getUserDirPath( Paths::SCREENSHOTS ));
Expand Down Expand Up @@ -98,6 +100,13 @@ bool Options::getVideoFullscreen() {
}
void Options::setVideoFullscreen(bool value) { setBool(VIDEO, VIDEO_FULLSCREEN, value); this->modified.insert( VIDEO + VIDEO_FULLSCREEN ); }

int Options::getTemporaryBitfield() {
return getInt(VIDEO, VIDEO_TEMPORARY_FINALIZE_DYNAMIC_TRIANGLES);
}
void Options::setTemporaryBitfield(int value) {
setInt( VIDEO, VIDEO_TEMPORARY_FINALIZE_DYNAMIC_TRIANGLES, value);
}

std::string Options::getSaveDirectory() {
return getString( DIRECTORIES, DIRECTORIES_SAVES);
}
Expand Down
3 changes: 3 additions & 0 deletions src/Utilities/Options/Options.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ class Options {
bool getVideoFullscreen();
void setVideoFullscreen(bool value);

int getTemporaryBitfield();
void setTemporaryBitfield(int value);

std::string getSaveDirectory();
void setSaveDirectory( std::string value );

Expand Down

0 comments on commit f60c27b

Please sign in to comment.