CalcMySky
v0.3.1
|
ShowMySky uses Qt for its rendering and data processing, so the API reflects this: it relies on QOpenGLFunctions_3_3_Core
, QOpenGLShaderProgram
, QString
etc.
To use ShowMySky from your C++ application, you need to do the following.
<ShowMySky/AtmosphereRenderer.hpp>
to get access to the relevant classes.dlopen
/LoadLibrary[Ex]
/QLibrary::load
etc. The name of the library to load is in the SHOWMYSKY_LIB_NAME macro. Use ShowMySky_ABI_version as the soversion (the second parameter of QLibrary
constructor).ShowMySky_ABI_version
of type uint32_t
in the loaded library (via dlsym
/GetProcAddress
/QLibrary::resolve
etc.), compare its value with ShowMySky_ABI_version macro defined in the header included in step 1. If it doesn't match, the library is incompatible with the header, use of such a library has undefined behavior.decltype(ShowMySky_AtmosphereRenderer_create)
.AtmosphereRenderer
. This is done by calling ShowMySky_AtmosphereRenderer_create, the function resolved in step 4, passing path to the atmosphere model directory, as well as a pointer to QOpenGLFunctions_3_3_Core
for the OpenGL context in which the renderer will work.In OpenGL there are many ways to draw a surface to be displayed on the screen or saved into a texture. One of the simplest ways is to draw a single GL_QUADS
item, having set up current vertex array and supplied the necessary uniforms to the current shader program. Here's an example of such a surface rendering function:
Aside from the many ways to draw a surface, there's a lot of different projections to choose from, as well as different connections of the their parameters to the surface drawing process. Thus, we need some way to find out what direction in the physical 3D space a given pixel on the surface corresponds to. ShowMySky API makes it possible for the app to provide its own shaders (vertex and fragment) that implement the function that takes no arguments and yields the direction in 3D space.
The coordinate system is such that north is along the \(x\) axis, west is along the \(y\) axis, and zenith is along the \(z\) axis.
Here's an example of the vertex and fragment shaders that implement this function to work in tandem with the drawSurface
example above:
Data loading is a bit involved. Because loading can potentially take dozens of seconds (for heavy models), it's done in steps, making it possible for application to indicate progress in the UI instead of freezing for the duration of loading. The procedure is as follows:
calcViewDir
function (see Surface rendering and view direction shader section for details).Readiness of the renderer to rendering can be queried by a call to ShowMySky::AtmosphereRenderer::isReadyToRender. Once true
is returned, basic rendering can be done by calling ShowMySky::AtmosphereRenderer::draw. If textures need to be reloaded (see below), reloading is done synchronously, which may throw ShowMySky::Error if it fails.
In some cases the draw
call may take much longer than it normally would. This is because, to avoid loading the whole textures into VRAM, only a slice of texture data corresponding to current camera altitude (determined by ShowMySky::Settings::altitude) is loaded. When camera altitude changes, there may be a need to reload another slice. If the application simply calls ShowMySky::AtmosphereRenderer::draw, the reloading may take some time, making the application appear to freeze.
To avoid freezes, the application can drive the reloading step by step. To implement this, the following steps are needed.