I just realized that I didn't post anything in this website for more than one year. Anyway, this is not actually the mirror of my activity so far. As always, I was very busy with my actual job but I found anyway some time to continue my private projects, in particular the TextureMind Framework. I really need to write some post here in the future for updating the situation. I perfected the serialization and the graphics context, making an implementation with the cairo library and the first example test.
Now the context is able to draw complex structure of primitive 2D shapes along materials and textures. I'm writing also an Engine that will be part of the framework and it will have great features. I implemented most of the architecture for 2D and 3D scenes, like textures, materials, shaders, assets, scripts, animations. I refactored my old material format for covering modern features, I got inspired by Unreal Engine 4, with some improvements.
Textures can be created starting from images, but also with fixed shaders and program shaders. A fixed shader texture depends on the context implementation and it's not programmable, but it should produce consistently the same output between different implementations, while a program shader texture can be programmed in GLSL or HLSL languages.
As you can see in the picture, the rounded box with holes is drawn with cairo libraries using a linear pattern, that in my framework is considered a 2D texture with a fixed shader. The same texture can be drawn also with OpenGL, DirectX or Vulkan implementation of the context. In this case, the fixed shader is translated into GLSL or HLSL code and executed by the graphics library.
This abstraction has been introduced to support basic functionality when advanced graphics libraries are not available. With Cairo we don't have program shaders and linear or radial shader textures can be translated into linear and radial patterns to make the rendering possible. On the contrary, program shader textures cannot be rendered because Cairo don't have program shader functionality at all. This abstraction is useful if you want to reuse the same context API for basic functionality, like software rendering of the GUI for the application.
Materials are more complex but they use similar concepts for being extremely scalable. First of all, I decided to abandon the old format similar to 3D Studio Max or Maxon Cinema 4D to adopt another format more similar to UE4 that is based on Visual Expression Nodes, where one node in this case is called "material component". A material is composed by different stages: displacement, fragment, blend and radiance. Every stage has parameters and a single component in input, that can be a texture with texture coords, diffusion with lights and normals or the combination of more components with "add" or "multiply" nodes.
If program shaders are supported by the context implementation, the material is translated into a program shader, otherwise it will be rendered as best as possible, with the component types supported by the graphics library. In the case of cairo, program shaders are not available and only texture components are supported. In this case, a single texture component is passed to fragment stage as input, like in the following diagram:
To draw a simple image with Cairo like the background in the example test, a material can be created with just a texture image attached to the fragment stage. If a feature is not available in the context implementation, the rendering won't be produced but no error will be generated. You can try to render a 3D scene with Cairo (and not OpenGL): in this case only 2D shapes will be rendered and not meshes with polygons, complex materials and program shaders, that are not supported. On the contrary, advanced graphics libraries like OpenGL are always able to render scenes with lower features. An OpenGL context should be always able to render a simple 2D scene, like the one showed in the example. In the same way, the GUI can be rendered via software with Cairo libraries or via GPU with OpenGL libraries. However, advanced functionality are not mandatory for the graphics engine to work. In this way, the engine can be scaled from the pac-man clone to the latest 3D games with ray tracing functionality.
Now I'm proceeding with the implementation of the graphics engine and I'm pretty excited. The next step is to write an implementation of the graphics context with OpenGL, Direct3D and Vulkan, improving the 3D engine. Most of the 2D engine will be used to implement the GUI. I will implement a converter for importing assets with assimp library. I want to write also a series of posts about the missing progresses that I made during development of the framework in the last year.