-
Notifications
You must be signed in to change notification settings - Fork 1
Core Graphics
This page provides a lot of use-cases and examples of accessing low-level OpenGL operations, such as changing staet, creating textures, loading vertex/fragment shaders, and uploading vertex data to the GPU.
Note: A lot of the content on this page relies on thourough knowledge of computer graphics, OpenGL specifically.
Note: All code references assume using namespace zen; using namespace gfxcore; All other namespaces are explicitly prefixed.
If you've read the section on regular subsystems, you'll be quite familiar with the content of this section. OpenGL subsystems are those that need to be explicitly initialized and destroyed. Naturally, this could be done in the constructor/destructor, but then there would be no error checking available, and it isn't always desireable to initialize immediately. Thus I opted for explicit initialization much like the zSubsystem route.
In the Zenderer framework, OpenGL subsystems are built into the following:
- zVertexArray (covered below)
- gfx::zRenderTarget (see the "Graphics" page)
- gfx::zEffect (see the "Graphics" page)
The process for implementing custom OpenGL subsystems is identical to that of regular subsystems; see the relevant page. There are several additional requirements that are OpenGL specific.
- It must bind the OpenGL object handle via
zGLSubsystem::Bind(). - It must unbind the OpenGL object handle via
zGLSubsystem::Unbind(). - It must give raw access to an OpenGL object handle via
zGLSubsystem::GetObjectHandle().
Naturally, the user can perform raw OpenGL state commands via calls such as glEnable. I aimed to provide a way to access common state changes through an abstracted interface that could potentially expand support DirectX.
The way Zenderer provides this is via the gfxcore::zRenderer API. This provides commonly used state-change wrappers allowing for the user to toggle blending and material states, and provides access to default objects necessary for rendering, such as a simple shader and the current projection matrix.
Over time, this wrapper will be expanded to provide more abstracted functionality such as depth or stencil states.
There are a couple of blending operations available in Zenderer, without delving into direct calls to glBlendFunc(). All are contained within the BlendFunc enumeration, and are passed to the zRenderer::BlendOperation(BlendFunc) method.
-
DISABLE_BLEND— As the name implies, this disables all blending operations and enables depth testing. -
A call to
zRenderer::DisableBlending()is identical to callingzRenderer(BlendFunc::DISABLE_BLEND). -
ENABLE_BLEND— This enables blending and disables depth testing, using the same blending operation as was being used prior to this call. This means that if you've never passed an actual blending equation to this method or calledglBlendFunc()explicitly, the behavior is unknown. -
STANDARD_BLEND— This will perform anENABLE_BLENDoperation, and will then set the standard blending operation that most people typically use when trying to achieve alpha transparency effects. This equation can be described as Co = 1 - As, where Co is the output color, and As is the source alpha. -
ADDITIVE_BLEND— This will also initially perform anENABLE_BLENDoperation, but will then set an additive blending operation. This equation can be described as Co = 1Cs + 1Cd, where Co is the output color, Cs is the source color, and Cd is the destination color.
Here's a handy blending guide if you'd like to perform direct calls to glBlendFunc():
You can disable all existing material state (materials are described in detail in the "Graphics" section) by calling zRenderer::ResetMaterialState(). This can be handy at the end of a drawing sequence if you are unsure of what explicitly needs to be disabled, or are simply too lazy to reference each part of the material separately.
All rendering to a certain framebuffer should reference the same projection matrix. You can achieve an immutable reference to this matrix via zRenderer::GetProjectionMatrix(). It will always point to the projection matrix being used by the current framebuffer.
Instead of it being necessary to create an effect with the default shaders (see the section on effects), you can access it directly via zRenderer::GetDefaultEffect() (or zRenderer::GetDefaultMaterial().GetEffect()). It is immutable, but actually allows for calls modifying the matrices bound to the effect ("mv" for the model-view matrix and "proj" for the projection matrix). There is no way of knowing what the existing matrix state is of the effect is, so it is always recommended that you set these parameters explicitly, or at least the model-view matrix if you aren't using alternate render targets.
Furthermore, there is access to a default texture, achieved with a call to zRenderer::GetDefaultTexture(). This is simply a 1x1 white pixel, and is used throughout the framework in order to properly display color info when rendering untextured primitives.
Finally, there is access to a special fullscreen vertex buffer object, accessible through zRenderer::GetFullscreenVBO(). It's primarily used internally for additive blending of lights and post-processing effects achieved through the gfx::zScene wrapper, but is also publicly accessible if the user wishes to draw full-screen quads directly.

