|
|
## Functional Overview
|
|
|
|
|
|
Within ACGL you will find the following folders:
|
|
|
|
|
|
* Animations - a simple animation framework.
|
|
|
* Base - some basic functionality, mainly internal.
|
|
|
* HardwareSupport - wrappers for additional hardware to easily connect it with the rest of ACGL, currently it hols support for the SpaceNavigator 3D mouse to directly control the ACGL camera class (GenericCamera)
|
|
|
* Math - include Math.hh from here to get access to GLM and additional small helper functions.
|
|
|
* OpenGL - Wrapper classes for OpenGL objects and loaders for meshes, textures and shaders.
|
|
|
* Resource - Resource handling, mostly interesting for the ShaderProgrammManagers that can reload shaders at runtime.
|
|
|
* Scene - Helper classes for scene data, the MatrixStack and the GenericCamera might be the most interesting classes to start with.
|
|
|
* Utils - Utility classes like timers and logging.
|
|
|
|
|
|
## Shared Pointer
|
|
|
|
|
|
ACGL uses shared pointers instead of real C pointers most of the time. For most classes there exists a typedef to make the naming simpler to type: for a class Foo a SharedFoo is a shared pointer to foo. As soon as all SharedPointers got destroyed, the object within gets deleted. Shared pointers are objects so they destroy them self automatically. This is a simple kind of reference counting.
|
|
|
|
|
|
## OpenGL
|
|
|
|
|
|
When using OpenGL with ACGL, always include the GL.hh from ACGL instead of platform specific headers. GL.hh will detect the system at compile time and include the correct headers on its own or use the self provided alternatives.
|
|
|
The simplest way to start is to use the classes found in the OpenGL/Objects folder. Those are thin wrappers around OpenGL objects so a basic understanding of OpenGL is needed. All other classes are only present to simplify tasks but not necessarily needed. One good example of this is ShaderProgramCreator which can simplify the loading of multiple GLSL files and the creation of a shader program from it to one line of code (see ShaderProgramCreator.hh for examples and details).
|
|
|
|
|
|
Don't use global objects of basic OpenGL classes as those will get created before the OpenGL context is ready. Only create OpenGL objects at run-time.
|
|
|
|
|
|
## The Matrix Stack
|
|
|
|
|
|
As modern OpenGL does not support an internal matrix stack anymore (glPushMatrix, glPopMatrix, glMatrixMode etc.), ACGL provides an own matrix stack which also mimics some of the old GL operations like glTranslate, glRotate etc. See MatrixStack.hh for more information. This can be used to create/handle the model matices in your application.
|
|
|
|
|
|
|
|
|
## The virtual camera GenericCamera
|
|
|
|
|
|
To create/handle the view matrix and the projection matrix, the class GenericCamera can be used. This class provides simple functions to set all camera parameters and move the camera around in the virtual environment. It can also be controlled by a SpaceNavigator.
|
|
|
|
|
|
|
|
|
## Loading Shaders, Textures and Meshes
|
|
|
|
|
|
ACGL provides some basic functionality to load simple resources. Look at the GLFWExamples template to see examples of how this is done.
|
|
|
|
|
|
|
|
|
### Shaders
|
|
|
|
|
|
A shader is some code that runs on the GPU in one of the following stages: vertex shader, tessellation control shader, tessellation evaluation shader, geometry shader, fragment shader, compute shader. A complete pipeline to render something with is called a shader program (in the simplest case a vertex and a fragment shader). To create a shader program 'by hand' you would have to:
|
|
|
|
|
|
* load the vertex shader code from a text file
|
|
|
* create a vertex shader
|
|
|
* add the code as a string to the shader
|
|
|
* compile it
|
|
|
* check for compile errors
|
|
|
* load the fragment shader code from a text file
|
|
|
* create a fragment shader
|
|
|
* add the code as a string to the shader
|
|
|
* compile it
|
|
|
* check for compile errors
|
|
|
* create a shader program
|
|
|
* attach both shaders to the shader program
|
|
|
* link the shader program
|
|
|
* check for linker errors
|
|
|
|
|
|
As this is a quite repetitive task, it can be done by ShaderProgramCreator:
|
|
|
|
|
|
SharedShaderProgram prog = ShaderProgramCreator("vertexshader.vsh").andFile("fragmentshader.fsh").create();
|
|
|
|
|
|
This will do all of the above tasks.
|
|
|
|
|
|
### Textures
|
|
|
|
|
|
Textures/images can not be loaded from disk directly into graphics memory, they have to pass the main memory. In this state they are stored as a TextureData object which is a thin wrapper around an array of image data (a GLubyte*). You can load a file to a TextureData object with the functions found in TextureDataLoadStore.hh. You can also create the data in memory on your own (e.g. for procedural textures or if you add your own loader). These TextureData objects can then be set as Images into a Texture. Textures can hold multiple Images, depending on the Texture kind (2D, array, cubemap, etc) and whether MipMaps are used.
|
|
|
A simple way to just load an image file and create a new Texture from it is by calling:
|
|
|
|
|
|
SharedTexture2D myTexture = loadTexture2D( "filename.png" );
|
|
|
|
|
|
from TextureLoadStore.hh. Note that only PNG, RGBE and PPM files are supported everywhere. When using QT, more formats are supported and on Linux EXR might be supported as well.
|
|
|
|
|
|
The formats can also be written (look for the saveScreenshot functions).
|
|
|
|
|
|
There is also a creator for simple 2D textures:
|
|
|
|
|
|
SharedTexture2D myTexture = Texture2DCreator( "filename.png" ).create();
|
|
|
|
|
|
which does the same as the function call above. It is useful in combination with the Texture2DFileManager:
|
|
|
|
|
|
SharedTexture2D myTexture = Texture2DFileManager::the()->get( Texture2DCreator("filename.png"));
|
|
|
|
|
|
as this now has aslo a reference stored to the texture and all the information needed to reload the file if it has changed. To do so, just call:
|
|
|
|
|
|
Texture2DFileManager::the()->updateAll();
|
|
|
|
|
|
|
|
|
### Meshes
|
|
|
|
|
|
OBJ files can be loaded into VBOs with a connecting VertexArrayObject via
|
|
|
|
|
|
SharedVertexArrayObject myMesh = VertexArrayObjectControlFile("mesh.obj").create();
|
|
|
|
|
|
This will setup up to three generic vertex attributes: aPosition, aNormal and aTexCoord.
|
|
|
|
|
|
|
|
|
## Logging to the console
|
|
|
|
|
|
Internally ACGL writes all loggings using an own stream class functionally similar to cout named ACGL::Utils::debug(), ACGL::Utils::error(), ACGL::Utils::message() and ACGL::Utils::warning(). The advantage of using those streams instead of cout is, that an app can add additional streams and mute/unmute any of those at runtime. The streams can also be mirrored to a file for logging or specific platform APIs if needed (e.g. to __android_log_print on Android). |
|
|
\ No newline at end of file |