CS6610 Interactive Computer Graphics HW repository. Stands for CompUter Renders Lot of Images. It is inteded as a toy renderer/course-project.
Note to TAs: If you are viewing this as a PDF it is the same document as the ReadMe.md so you may use that if it is more convinient.
Building CuRLI for windows requires Cmake 3.0
Most of these dependencies are included as submodules and compiles with CMake. Only dependency that does not exist as submodule is glad which can be downloaded from generated link obtained glad web page.
- MSVCv143 - VS2022 C++ or above
- Cmake 3.0
- GLM
- ImGui
- GLFW
FreeGlut - Glad
- cyCodeBase(only for .obj importer ATM)
- EnTT
- Clone or download the files(unzip the downloaded files).
- Create a folder to build binaries.
- Run CmakeGui or Cmake select source as the project root directory and where to build binaries as build folder.
- Select Visual Studio 17 2022 as the generator.
- Configure and Generate
- Navigate to build folder and open curli.sln file with Visual Studio
- Select Under Build>Build solution(F7)
- Run the executable i.e. ./curli.exe [params] from console
- Creating Window context
- Keyboard listeners where ‘esc’ is used to call
glutLeaveMainLoop();
- Setting window size, position, name and clear color during initialization.
- Idle function where animation between two colors are generated using linear interpolation of sine value of time(ms).
Some Screenshots:
- Integrated
cyTriMesh
class to load .obj files from console arguments. Now path to a .obj mesh needs to be given to executable as the first argument as follows:./curli.exe path/to/mesh
- Implemented very simple shaders (/assets/shaders/simple/...) to transform and render vertex points in a constant single color as
GL_POINTS
. - Implemented tarball controlled lookAt camera where
left mouse button + drag
adjusts two angles of the camera andright mouse button + drag
adjusts the distance of the camera to center. - Programmed a Imgui window and keyboard shortcuts that allows reloading(
F5
) and recompiling(F6
) of the shader files. This means that one can edit shader files after curli launches, pressing F5 and F6 will use the edited shaders if compilation is successful. - Imgui window also includes a button that recenters camera(
F1
) to the mesh center point. - Pressing
P
also lets user switch between orthographic and perspective projection types.
- Curiously recurring template pattern has been utulized to have staged renderers and application.
- Application stages are:
Initialize()
,Render()
,DrawGui()
,Terminate()
.Render and DrawGui are called in a render loop. - Each renderer
A
that implements base classRenderer<A>
will need to overrideStart()
PreUpdate()
Update()
andEnd()
. These functions are called on various stages of the application allowing custimizable renderers to be written.
- Application stages are:
- Also programmed a simple event dispatcher system which gets the input&windowing events by
glfw
to be queued. The queued event is resolved in render loop.- Each renderer has the option to override certain event calls dispatched by the system if the fuctions are overriden they are called by the
dispatchEvent()
- Each renderer has the option to override certain event calls dispatched by the system if the fuctions are overriden they are called by the
- Inside
PreUpdate()
function of this projects renderer (TeapotRenderer
) I set the model matrix of the teapot to a rotation matrix that updates the angle over time. This causes teapot to revolve around itself.
Some Screenshots:
- Displayed triangles instead of points
- Uploaded and transforming vertex normals using inverse transpose of model view matrix
- Imlemented Blinn-Phong shading in view space using half angles.
- Added orbital controls to the first point light source inserted into the scene.
- Integrated EnTT --- an entity-component system.
- Using EnTT several components have been developed:
CLight
: Illuminates the scene currently only as point light but soon other types will be implemented.CTransform
: A transform component that is traditionally used to generate model matrices for shadersCTriMesh
: Wrapper for cyTriMesh allows entities to have geometryCVertexArrayObject
: Allows geometry to be drawn using bound VBOs and EBO(optional). Automaticly handles and selects which draw calls to make.
- Using EnTT several components have been developed:
- Implemented
OpenGLProgram
abstraction which alows convenience binding shaders and uploading uniforms. - Using the ECS I let shaders render multiple light sources over multiple objects.
Some Screenshots:
- Rendering and shading 3D sphere as a particle.
-
LShift + Mouse drag
can interactively apply force. - 3D arrow as force vector indicator.
- Programmable VelocityField2D component with respective UI to add/remove from the scene.
- Programmable ForceField2D component with respective UI to add/remove from the scene.
- Euler integrator (explicit or implicit) and its selection UI.
- BoundingBox class with VertexArrayObject component so it can be drawn as GL_LINES.
Some Screenshots:
- Load and parse .mtl files associated with .obj files.
- Load and decode .png files as textures.
- Use cmdline to read .obj files
- Usage
-model --path ../path/to/your.obj
- Appending
--rb
after-model
tag attachesCRigidBody
component to the model which includes this object in WIP physics events.
- Usage
- Display textures properly on the object.
- Include the specular texture, specified in the mtl file, for adjusting the specular color of the object.
- Improved UI using ImGUI and EnTT.
- Now scene objects are displayed in a list.
- Selecting an object from a list allows user to see different components attached to the object.
- Using the Top menu bar user can load .obj files.
File>import .obj file
- Again using the top menu bar user can add components to the selected scene object.
- Under
Edit > Attach component
- Under
- User can also create empty entities to attach objects to it using
Edit>Create Entity
Some Screenshots:
- Loads and parses
.obj
files as command-line arguments.- Usage
-model --path ../path/to/your.obj
- For this specific example to work call the program with a plane.obj file provided inside assets. I have set up a scene for easy grading
- Usage
- The objects are rendered with the textures coupled with their
.obj
and.mtl
files. - The provided scene can be rendered without the teapot on the actual viewport (but on the texture) by adjusting visibilty settings on Mesh component using the GUI.
- Display the rendered texture by mapping it on a square-shaped plane.
- Camera controls work the same as with the previous assignments.
- If the ALT key is pressed, the left and right mouse buttons (and drag) controls the same view parameters for rendering texture on the plane.
- Background of the image plane is set to phong diffuse color of the plane to separate it from the background color.
- The rendered texture uses bilinear filtering for magnification and mip-mapping with anisotropic filtering for minification.
- Seperated OpenGL concepts like
VertexArrayObject
andTextures
are seperated from scene/entity component system.- This seperation allows better and cleaner implementation.
- For textures I have implemented a
CImageMaps
component which maintains astd::vector
ofImageMap
.ImageMap
data and properties are converted toOpenGLProgram
Textures and bound acordingly. - For Rendered textures I maintain a wrapper struct for
Texture2D
struct which creates frame and depth buffers on request. This struct comes with aRender(...)
function. This function takes anotherstd::function
as parameter and calls it after binding the relevant buffers and the viewport. CallingRenderedTexture2D
's Render function at Renderer'sPreupdate
function I can pass theUpdate
function pointer as a parameter and render the scene as it would to that texture. - The component
CImageMaps
handles rendered textures by creating aCamera
object along them instead of decoding a image file and storing it.
- Implemented a GUI for textures where bound textures and their respective slots are displayed.
- For rendered textures this view is live and can be used to adjust camera pressing
alt
.
- For rendered textures this view is live and can be used to adjust camera pressing
- Reimplemented
TriMesh
class not to rely oncy::TriMesh
. Now cy::TriMesh is only used for importing.obj
files.- For better shading I implemented re-indexing and duplicating certain vertex attributes as OBJ format uses multiple faced indexing.
Some Screenshots:
- Display the background(named as
CSkybox
). - Reflections on a sphere and other objects using on-the-flye generated cubemaps
- to attach this component: Select a scene object, go to edit->attach/detach components, select ImageMaps from the attach menu. Then go to newly attached ImageMaps components tab on the right, select Environment Map from the menu and press "from rendered image".
- Flat objects like plane can also be attached with environment map components however, its better to use a
RenderedTexture2D
with it's camera positioned at reflected camera position.
- Instead of drawing all cube faces in one frame CuRLI draws one side in every six frames.
Some Screenshots:
- Program takes the name of the .obj file as its first command-line argument.
- Same as the las assignments a obj can be imported into the scene by
-model --path ../path/to/your.obj
- Same as the las assignments a obj can be imported into the scene by
- Computes shadows from a light onto the plane and the object.
- Currently CuRLI supports both spot directional light shadow mapping.
- The object casts shadows onto itself.
- The light position can be controlled with the UI on the right panel.
- The point&spot lights can be displayed by checking the
show
on the UI panel (See image 1&3 below).
- Shadow depth textures can be displayed on the UI.
- Multiple directional light sources can be added and they can cast multiple shadows
- Shadows are calculated with poisson samplingto reduce aliasing.
- As an argument one can also give paths to skybox textures.
- ex:
-skybox ../assets/images/cubemap/cubemap_posx.png ../assets/images/cubemap/cubemap_negx.png ../assets/images/cubemap/cubemap_posy.png ../assets/images/cubemap/cubemap_negy.png ../assets/images/cubemap/cubemap_posz.png ../assets/images/cubemap/cubemap_negz.png
- ex:
Some Screenshots:
- Implemented normal mapping.
- Now image map components(textures) can be loaded along side with a model object
-model --path ../path/to/your.obj --im [amb/diff/spec/norm/disp] ../path/to/your.png
- One can use the GUI for this as well(see fifth bullet point).
- Quad-shaped plane can be loaded from assets plane.obj.
- Normal shading(Blinn) operations are supported with this mode.
- Using geometry shaders CuRLI can generate wireframes for the scene. To activate this one can either press spacebar or click on
view/Wireframe
on top menu. - Using tessellation shaders CuRLI can utilize displacement mapping to enable this one can use the GUI menu.
- Select object, add an image map component using
edit/Attach Detach Components/Image Map
then select the newly created image map tab on the selected object and load displacement map from images. - Same can be achieved with console arguments described in second bullet point.
- Tesselation level can be controlled by selecting the object from the right menu and pressing up or down arrows.
- Same can be achieved by going to mesh tab and adjusting the tessellation parameter there.
- Select object, add an image map component using
- Normal and displacement map terxtures can be viewed using the left menu tab.
Some Screenshots: