A simple template implementation using SDL for quickly applying the modern OpenGL pipeline to projects.
The easiest way to utilise this library appears to be:
- Clone the contents of the
includedirectory into your own include directory's root. - Clone the contents of the platform relevant
lib\<architecture>directory into your relevant lib directories. - Clone the platform relevant runtime libraries (.dll) from
<configuration>\<architecture>into your relevant build directories. - Update the linker to link against:
SDL2.libSDL2_image.libglew32.libOpenGL32.libglu32.libfreetype263.lib
- Delete the sample
main.cpp, to remove the duplicate entry point. - Copy the
sdl_exp/visualisationdirectory into your own source directory. - Create a new class which extends
Sceneand overrides all of its virtual methodsEntityScene.h&EntityScene.cppare provided as an example of how to configure your ownScene.- Make sure to call the constructor of Scene, as this will automatically manage your Projection and ModelView matrices!
- Within your main method you can now create the Visualisation:
Visualisation v = Visualisation("Visulisation Example", 1280, 720);
EntityScene *scene = new EntityScene(v);
v.run();The Shaders and Entity objects attempt to automatically manage uniforms and attributes, you can assist their functioning by using the below naming schemes for your uniforms and vertex attributes. You can also configure your own static and dynamic uniform floats and ints by calling addStaticUniform() and addDynamicUniform() on the relevant Shaders object.
- Uniforms:
_modelViewMat- ModelView Matrix[Mat4]_projectionMat- Projection Matrix[Mat4]_modelViewProjectionMat- ModelViewProjection Matrix[Mat4]_texture- Texture Sampler[sampler2D/samplerCube]_color- gl_Color equivalent[Vec3/Vec4]
- Atributes:
_vertex- Vertex Position[Vec3/Vec4]_normal- Vertex Normal[Vec3/Vec4]_color- Vertex Color[Vec3/Vec4]_texCoords- Texture Coordinates[Vec2/Vec3]
The header visualisation/util/cuda.cuh provides functionality for allocating and freeing OpenGL texture buffers that can be accessed by CUDA.
If you wish to write to these textures asynchronously of their accesses by shaders it is recommended you use some form of locking.
The header was initially written for use with the CUDA 7.5 API.
In order to enable CUDA compilation/support in the project you must follow these steps:
- Enable the CUDA build customisation
- Rename all the
.cu.cppfiles to.cu. (Without this the.cu.cppfiles will not CUDA compiled correctly.) - Configure all
.cufiles to build with the CUDA compiler - Add
cuda.libandcudart.libdependencies to the linker settings
Usage:
- Create a
CUDATextureBufferusingmallocGLInteropTextureBuffer<float>()- Alternatively
floatcan be replaced withintorunsigned int
- Alternatively
- For convenience you can store this inside a
TextureBufferobject, which can be treated like otherTexturesubclasses. - You can now access the texture buffer using CUDA:
- You can use the
d_mappedPointermember variable to read/write from the buffer as you would with any normal device pointer. - Within CUDA kernels you can read the texture buffers using the texture object API texture fetch functions (e.g.
tex1Dfetch<float4>()) passing thecuTextureObjmember variable as the first argument.- You can pass the
cuTextureObjmember variable as a kernel parameter or copy it to a device constant
- You can pass the
- Write a vertex shader:
- The existing shader file
instanced.vertprovides an example. iandurespectively should be prepended tosamplerBuffer,texelFetch()andvec4in the following steps if you are usingintorunsigned intdata instead of the defaultfloat.- Declare a
uniform samplerBuffersampler inside your shader. - To access an element of the texture buffer use
texelFetch(), passing the identifer of yoursamplerBufferas the first argument, and the desired index as the second argument.- This returns a
vec4, if your element has less than 4 components ignore those you do not require. - If you are performing instanced rendering, the second argument is likely
gl_InstanceID.
- This returns a
- If you are writing a vertex shader using a version earlier than 140 you must follow some additional steps:
- Add
#extension GL_EXT_gpu_shader4 : requireto the shader on the line directly after#version.- This enables the extension for reading data from the texture buffer.
- Replace all call calls to
texelFetch(),itexelFetch()andutexelFetch()with calls totexelFetchBuffer(). This function returns the right type ofvec4, based on thesamplerBuffertype.
- Add
- The existing shader file
- Create a
Shadersobject from your vertex shader source:- Call
addTextureUniform()on yourShadersobject:- The first argument should be the
glTexNamemember variable. - The second argument should be the identifier of the
uniform sampleBufferwithin your vertex shader source. - The third argument should be
GL_TEXTURE_BUFFER.
- The first argument should be the
- Call
- Pass your
Shadersobject to anEntityand render! - After you have finished using the texture buffer with both OpenGL and CUDA, pass the
CUDATextureBuffertofreeGLInteropTextureBuffer(CUDATextureBuffer *texBuf). This will deallocate the texture buffer and delete theCUDATextureBufferstruct.
- You can use the
Additional Usage:
- To access the texture buffer using OpenGL:
- Before doing anything with the texture buffer in OpenGL you should bind the buffer using
glBindBuffer()passing theglTBOmember variable as the argument.- The
glTBOmember variable is the buffers 'name', you can use this with various OpenGL buffer methods.
- The
- To copy data to the texture buffer using OpenGL you can use
glBufferData()passingGL_TEXTURE_BUFFERas the first argument. - You can copy data back from the buffer using
glGetBufferSubData()passingGL_TEXTURE_BUFFERas the first argument. - You can clear the active buffer by calling
glBindBuffer(0).
- Before doing anything with the texture buffer in OpenGL you should bind the buffer using
- To use the texture buffer when manually rendering with OpenGL:
- After you have linked the shader program:
- You must set the value of the
uniform samplerBufferwithin the shader, to the texture unit into which you will load the desired texture buffer.- This should be any value from 0 to that of
glGet(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS)-1(remember this value, it must be reused at render). In most cases you can simply increment this value from 0 for each unique texture, texture units can be reused across seperate render calls per frame. - You can use
glUniform1i()to then set this value within the shader, where the second parameter can be gained usingglGetUniformLocation()if not stated within the vertex shader source.
- This should be any value from 0 to that of
- You must set the value of the
- Within your render loop:
- Activate the texture unit using
glActiveTexture()- The argument passed to this should be
GL_TEXTURE0+ the value you earlier stored in the shadersuniform samplerBuffer
- The argument passed to this should be
- Bind the texture buffer to the texture unit using
glBindTexture()passingGL_TEXTURE_BUFFERas the first argument, and theglTexNamemember variable as the second argument. - After the render call use
glActiveTexture()again, followed byglBindBuffer(0)to clear the texture unit.
- Activate the texture unit using
- After you have linked the shader program:
All dependent libraries are included within the repo, licenses are available on their respective websites.