Table of Contents Link to heading
Code Architecture Overview Link to heading
This project simulates a 3D solar system using OpenGL. Below is a breakdown of the key parts and their roles.
Shaders Link to heading
- Color.shader: Renders objects with a solid color. Uses
u_Color
uniform for coloring. - Texture.shader:
- Supports texture mapping and Phong lighting (ambient, diffuse, specular).
- Vertex shader computes normals and positions for lighting.
- Fragment shader blends textures with dynamic light calculations.
Materials Link to heading
- Material (Base Class):
- Manages transformations (translation, scaling, rotation) and shader uniforms (
u_ModelMat
,u_ViewMat
,u_ProjectionMat
). - Abstract class with
setColorTexture()
as a pure virtual method.
- Manages transformations (translation, scaling, rotation) and shader uniforms (
- ColorMaterial:
- Inherits from
Material
. Sets a uniform color viau_Color
.
- Inherits from
- TextureMaterial:
- Inherits from
Material
. Binds textures and sets opacity viau_TexOpacity
.
- Inherits from
Buffers & Layouts Link to heading
- VertexBuffer: Stores vertex data (positions, UVs, normals).
- ElementBuffer: Stores indices for indexed rendering.
- VertexArray: Manages vertex attributes and buffer bindings.
- VertexBufferLayout: Defines vertex attribute formats (e.g.,
position: vec3
,UV: vec2
,normal: vec3
).
Textures Link to heading
- Loads images (e.g., planet textures) using
stb_image
, binds to OpenGL texture slots. - Textures are applied to
TextureMaterial
objects (e.g., sun, planets).
Shapes Link to heading
getCube()
: Generates vertices and indices for a cube (used for the skybox).getSphere()
: Generates a UV-sphere mesh with normals (used for planets).
Renderer Link to heading
draw()
: Binds VAO/EBO/shader and issuesglDrawElements
.clear()
: Clears color and depth buffers.
Camera Link to heading
- Manages view/projection matrices and FOV.
- Processes keyboard (WASD) and mouse input for movement/orbiting.
- Supports zoom via scroll.
Debugger Link to heading
- Macros:
glCall
,ASSERT
wrap OpenGL calls to catch and log errors. - Functions:
glClearError()
,glLogCall()
for error checking.
OOP Concepts in Rendering Loop Link to heading
Inheritance & Polymorphism Link to heading
- Base Class
Material
: Defines common interfaces (updateModelMat()
,setColorTexture()
). - Derived Classes:
ColorMaterial
andTextureMaterial
overridesetColorTexture()
to handle color/texture-specific logic. - Polymorphic Array: All materials are stored as
Material*
pointers, enabling unified rendering:Material* materials[] = { sunLight, sun, mercury, ... }; for (Material* material : materials) { material->setColorTexture(); // Calls overridden method material->updateModelMat(deltaTime); renderer.draw(...); }
Encapsulation Link to heading
- Classes encapsulate OpenGL resources (e.g.,
VertexBuffer
,Texture
) with RAII:- Resources are initialized in constructors and released in destructors.
- Camera state (position, rotation) is managed internally, exposed via matrices.
Separation of Concerns Link to heading
- Shaders handle lighting/texturing logic.
- Materials manage object-specific properties (transformations, colors/textures).
- Renderer/Camera abstract low-level OpenGL details.
How the Rendering Loop Works Link to heading
- Initialization:
- Load shaders, textures, and create VAOs/VBOs for shapes.
- Instantiate materials (e.g.,
sun
,earth
) with unique transforms and properties.
- Per-Frame Updates:
- Process input to update camera.
- Compute view/projection matrices.
- Drawing:
- Render the skybox (
space
object) first. - Iterate over all
Material
objects, updating their transforms and binding resources. - Use
Renderer::draw()
to render each object with its VAO/EBO and shader.
- Render the skybox (
This architecture ensures flexibility (e.g., adding new materials) and efficiency (shared rendering logic). The use of OOP principles keeps the code modular and maintainable.