TinyWindow 0.4

Since the beginning of February TinyWindow has gone through a massive number of changes with a new focus on implementing more C++ features. for features implemented between February 14th to 25th see here. Again special thanks to James Mitchell for the feedback that drives these updates

  • Mar 2nd –
    • Added typedefs and extra functions to fit the new typedefs
    • implemented std::unique_ptr
    • fixed warnings on windows and Linux platforms
  • Mar 4th-
    • implemented new error handling system using std::error/std::error_category. Error enums are now private and are no longer publicly accessible to users
    • learned a little bit about exception specification for pure virtual functions
    • fixed a few warnings as well as potentially fixing shutdown bug during shutdown on Linux
    • fixed Issue with PrintErrorMessage being accidentally called on shutdown. Also swapped out noexcept with throw() as noexcept is not supported by older versions of Visual Studio
    • fixed Long forgotten shutdown issue on Linux platform
  • Mar 6th –
    • updated documentation to now include detailed graphs as well as include the doxyfile

Big changes to TinyWindow

Starting from the 14th of February, I have made a large number of changes to TinyWindow which includes adding CMake, and making TinyWindow use more c++ features.

starting from the 14th of february, here are the changes to TinyWindow up to this point:

  • Feb 14th –
    • moved example code to seperate folder and added CMakeLists to example folder.
    • compressed documentation to a single zip file
  • Feb 17th –
    • Updated TinyWindow based on feedback. Special thanks to James Mitchell
    • renamed FOUNDATION_ERROR and FOUNDATION_OK to TINYWINDOW_””
    • removed magic numbers in WNDPROC
    • changed windows storage from std::list to std::vector
    • removed GetWindowInList functions
    • fixed in-code documentation relating to X11 Atoms being mistakenly referred to Atomics
    • swapped out #define for const declarations
    • replaced for each loops with C++11 range based for loops
  • Feb 22nd –
    • removed useless windowproc function declaration
    • swapped out const int variables definitions with enums.
    • added error for invalid icon path
    • added forward declaration for window_t to allow its use in public functions
    • window_t now uses default values for it’s consturctor
    • changed GCC flags to strictest warning settings
    • added keypress event to Example for debugging purposes
    • replaced C style function pointers with std::function
  • Feb 23rd –
    • added Platform_ private functions to better organize code
  • Feb 24th –
    • replaced most enums with class enums to prevent name clashes as well as type safety

The next upcoming changes to TinyWindow include:

  • using std::error/std::error_category for error management
  • implement std::unique_ptr
  • update documentation

With these updates, TinyWindow will move from 0.3 to 0.4

 

More information on future updates and features can be found here

 

 

 

tinyShaders now with pre-compiled shaders support

my most recent addition to tinyShaders is the ability to save and load shader program binaries which is a great technique for greatly reducing loading times by allowing an application to completely bypass the shader compilation stage of initialization.

please note that pre-compiled shader binaries would be best used for caching purposes not distribution as every GPU vendor as well as driver version for that GPU would have a different implementation for saving shader binaries.

example 1. (a shader binary compiled on an AMD HD5800 GPU)
example 2. (a shader binary compiled on a Nvidia GTX550M GPU)

as you can see there is a very clear difference in shader binaries so your best bet would be to ship your product with the shader source code, compile the shader code to a binary and save it to the user’s filesystem.

the process of saving the binary is actually very straightforward and can be done whilst the shader source code is being loaded

//after specifying input and output shader attributes

GLchar errorLog[ TINYSHADERS_ERROR_LOG_SIZE ];
GLint successful = GL_FALSE;
//tell OpenGL to hang onto the shader binary
glProgramParameteri( programHandle, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE );

//if the shader program links correctly
glLinkProgram( programHandle );
glGetProgramiv( programHandle, GL_LINK_STATUS, &successful );
glGetProgramInfoLog( programHandle, sizeof( errorLog ), 0, errorLog );

GLint binarySize = 0;

//retrieve the size and format of the binary from OpenGL
glGetProgramiv( programHandle, GL_PROGRAM_BINARY_LENGTH, &binarySize );

void* buffer = nullptr;
buffer = ( void* )malloc( binarySize );
GLenum binaryFormat = GL_NONE; //the next function will set binary format as a reference parameter
glGetProgramBinary( programHandle, binarySize, NULL, &binaryFormat, buffer );

//now you have a buffer object that you can save to a file at a later time

TinyShaders-embedded is now complete

I am happy to announce that TinyShaders-embedded has been completed as well as adding documentation for both TinyShaders and TinyShaders-Embedded. The new version of TinyShaders can be found here .

The ext update for TinyShaders will have the ability to load and save pre-compiled shader programs to greatly increase shader loading times for graphical applications.

TinyShaders Dilemma

I am happy to announce that the latest version of TinyShaders has been updated to reflect my new coding style however whilst working on the API I’ve found that creating an embedded version of TinyShaders would not in fact be compatible with TinyExtender-embedded. This is due to the fact that necessary OpenGL functions required by TinyShaders-embedded are stored as member functions in the embedded version of TinyExtender. It IS possible to implement a version of TinyShaders-Embedded that uses TinyExtender-Embedded but that would go directly against the modular design of my APIs.

However, developing an embedded version of TinyShaders that retains a modular design is possible as long as the OpenGL functions required are on a global scope(not accessible via class, struct or namespace).

So in conclusion, an embedded version of TinyShaders is on the way but it will not be compatible with TinyExtender-Embedded unless you want to edit the source code to directly use TinyExtender-embedded.

New coding standard for all current and future projects

Today I would like to announce a new coding style I will be implementing for all of my projects. This style is heavily inspired by DOOM 3 source code style with some of my own tweaks. The style is broken down as follows:

Comments:
the commenting style allows for programs like Doxygen to work more effectively

    For Functions:
/**
 * This is the new commenting style for functions
 */
void Example( int parameter );
    For Variables
int example = 0; /**< This is the new commenting style for variables */

Brackets
For brackets I do NOT like to use trailing braces and I use 4 spaces for indentation

bool isValid = false;
if( isValid )
{
    return true;
}
//else, else if, etc. statements should be on the same line as the if statement
else
{
    return false;
}

Padding
Pad parenthesized expressions with a single space

//function declarations
void Example( int parameter, int parameter2);

//function calling. (trail commas with a single space)
Example( 5, 10 );

//arithmetic
x = ( 1 + 5 );

Variable and Function names

//names start with a lowercase letter
int example = 0;

//names with more than one word follow the preceding rule and use camel notation
bool secondExample = false;

//function names start with an Upper case letter
bool Example();

//function names start with an Upper case letter and use camel notation
bool SecondExample(): 

Classes and member layout

//class names with multiple words begin with a lower case letter and use Camel notation
class exampleClass
{
    //the order of protection levels are: public, protected, then private
public:

    //class and struct member variables have the same naming conventions as variables

    //indent the names of class variables and class methods to make neat columns
    float    x;    /**< indent variable comments as well to maintain a column */
    float    y;    /**< */
    float    z;    /**< */
    //also use constant member functions where applicable
    float    Example( void ) const;

    //class and struct member functions have the same naming conventions as functions
    bool ExampleFunction( void ) const;
};

/*
the ordering of class members and functions should be:
- list of friend classes
- public variables
- public methods
- protected variables
- protected methods
- private variables
- private methods
*/

Typedefs and structs

//typedef and struct names always end with _t
typedef void( *exampleFunctionPointer_t )( void ); 

struct exampleStruct_t
{

};

Macros

//macro names use all upper case letters. multiple words are separated with an underscore
#define EXAMPLE_MACRO 0

refer to the DOOM 3 coding standards for more information.

Embedded versions of APIs

Starting yesterday I have begun work on new versions of my APIs that are made specifically to be embedded into existing frameworks and engines. This has been achieved by removing the use of static methods to instead use member functions and force users to create instances of managers themselves (a necessary sacrifice).

Currently TinyWindow and TinyExtender have embedded versions

e.g. TinyWindow-Embedded


#include "TinyWindow.h"

int main()
{
	windowManager* manager = new windowManager();
	manager->AddWindow("Example");
	
	while (!manager->GetWindowShouldCloseByIndex(0))
	{
			manager->PollForEvents();// or WaitForEvents
			manager->MakeWindowCurrentContextByIndex(0);
			glClearColor(0.25f, 0.25f, 0.25f, 1.0f);
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
			manager->WindowSwapBuffersByIndex(iter);
	}
	manager->ShutDown();
	return 0;
}

versus TinyWindow

#include "TinyWindow.h"

int main()
{
	windowManager::Initialize();
	windowManager::AddWindow("Example");
	
	while (!windowManager::GetWindowShouldCloseByIndex(0))
	{
		windowManager::PollForEvents();// or WaitForEvents
		windowManager::MakeWindowCurrentContextByIndex(0);
		glClearColor(0.25f, 0.25f, 0.25f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		windowManager::WindowSwapBuffersByIndex(0);
	}
	windowManager::ShutDown();
	return 0;
}

The main advantage of this change is to make it as easy as possible to insert APIs like TinyWindow and TinyExtender into existing frameworks or engines. As well as hopefully be able to allow people to create multiple instances of OpenGL windows that can run on separate CPU threads.