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_Coloruniform 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
TextureMaterialobjects (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,ASSERTwrap 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:
ColorMaterialandTextureMaterialoverridesetColorTexture()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 (
spaceobject) first. - Iterate over all
Materialobjects, 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.