diff --git a/src/FluidRenderer.cpp b/src/FluidRenderer.cpp
index c3fa0bbf085a5e1b16ab9555a331e71bf6ba1784..685393cd3fb1d4a58b868124d01a699afced736e 100644
--- a/src/FluidRenderer.cpp
+++ b/src/FluidRenderer.cpp
@@ -142,88 +142,85 @@ void FluidRenderer::initShaders() {
     std::cout << "Visualization Shaders initialized successfully." << std::endl;
 }
 
-// Initialize Shader Uniforms
-void FluidRenderer::initShaderUniforms() {
-    // Normal Render Shader Uniforms
-    glUseProgram(m_normalRenderProgram.programID);
-
-    m_normalRenderProgram.positionAttribLoc = glGetAttribLocation(m_normalRenderProgram.programID, "aPosition");
-    if (m_normalRenderProgram.positionAttribLoc == -1) {
-        fprintf(stderr, "Normal Render Shader: Could not find attribute 'aPosition'\n");
+void FluidRenderer::setupShaderProgram(ShaderProgram& shaderProgram)
+{
+    glUseProgram(shaderProgram.programID);
+
+    // 1. Try fetching the attribute for position
+    //    Note: Some shaders use "aPosition", some use "aPos".
+    shaderProgram.positionAttribLoc = glGetAttribLocation(shaderProgram.programID, "aPosition");
+    if (shaderProgram.positionAttribLoc == -1) {
+        // If "aPosition" is not found, try "aPos" (used by visualization)
+        shaderProgram.positionAttribLoc = glGetAttribLocation(shaderProgram.programID, "aPos");
+        if (shaderProgram.positionAttribLoc == -1) {
+            fprintf(stderr, "Shader (ID %d): Could not find attribute 'aPosition' or 'aPos'\n",
+                    shaderProgram.programID);
+        } else {
+            printf("Shader (ID %d): Found attribute 'aPos' at location %d\n",
+                   shaderProgram.programID, shaderProgram.positionAttribLoc);
+        }
     } else {
-        printf("Normal Render Shader: Attribute 'aPosition' location: %d\n", m_normalRenderProgram.positionAttribLoc);
+        printf("Shader (ID %d): Found attribute 'aPosition' at location %d\n",
+               shaderProgram.programID, shaderProgram.positionAttribLoc);
     }
 
-    m_normalRenderProgram.modelMatrixLoc = glGetUniformLocation(m_normalRenderProgram.programID, "modelMatrix");
-    m_normalRenderProgram.viewMatrixLoc = glGetUniformLocation(m_normalRenderProgram.programID, "viewMatrix");
-    m_normalRenderProgram.projectionMatrixLoc = glGetUniformLocation(m_normalRenderProgram.programID, "projectionMatrix");
-    m_normalRenderProgram.pointRadiusLoc = glGetUniformLocation(m_normalRenderProgram.programID, "pointRadius");
-    m_normalRenderProgram.pointScaleLoc = glGetUniformLocation(m_normalRenderProgram.programID, "pointScale");
-    m_normalRenderProgram.uColorLoc = glGetUniformLocation(m_normalRenderProgram.programID, "uColor");
-
-    if (m_normalRenderProgram.pointRadiusLoc != -1)
-        glUniform1f(m_normalRenderProgram.pointRadiusLoc, 20.0f);
-    if (m_normalRenderProgram.pointScaleLoc != -1)
-        glUniform1f(m_normalRenderProgram.pointScaleLoc, 10.0f);
-
-    mat4 modelMatrix = IdentityMatrix();
-    glUniformMatrix4fv(m_normalRenderProgram.modelMatrixLoc, 1, GL_TRUE, modelMatrix.m);
+    //  Fetch uniforms that may or may not exist in this shader.
+    //  If the location is -1, that uniform is absent; just skip it.
+    shaderProgram.modelMatrixLoc      = glGetUniformLocation(shaderProgram.programID, "modelMatrix");
+    shaderProgram.viewMatrixLoc       = glGetUniformLocation(shaderProgram.programID, "viewMatrix");
+    shaderProgram.projectionMatrixLoc = glGetUniformLocation(shaderProgram.programID, "projectionMatrix");
+    shaderProgram.pointRadiusLoc      = glGetUniformLocation(shaderProgram.programID, "pointRadius");
+    shaderProgram.pointScaleLoc       = glGetUniformLocation(shaderProgram.programID, "pointScale");
+    shaderProgram.uColorLoc           = glGetUniformLocation(shaderProgram.programID, "uColor");
+    shaderProgram.sphereRadiusLoc     = glGetUniformLocation(shaderProgram.programID, "sphereRadius");
+    shaderProgram.nearPlaneLoc        = glGetUniformLocation(shaderProgram.programID, "zNear");
+    shaderProgram.farPlaneLoc         = glGetUniformLocation(shaderProgram.programID, "zFar");
 
-    std::cout << "Normal Render Shader uniforms initialized." << std::endl;
-
-    // Depth Render Shader Uniforms
-    glUseProgram(m_depthRenderProgram.programID);
-
-    m_depthRenderProgram.positionAttribLoc = glGetAttribLocation(m_depthRenderProgram.programID, "aPosition");
-    if (m_depthRenderProgram.positionAttribLoc == -1) {
-        fprintf(stderr, "Depth Render Shader: Could not find attribute 'aPosition'\n");
-    } else {
-        printf("Depth Render Shader: Attribute 'aPosition' location: %d\n", m_depthRenderProgram.positionAttribLoc);
+    
+    // Set default values if the uniform is present
+    
+    // For point rendering (as in particle shaders):
+    if (shaderProgram.pointRadiusLoc != -1) {
+        glUniform1f(shaderProgram.pointRadiusLoc, 20.0f);
     }
-
-    m_depthRenderProgram.modelMatrixLoc = glGetUniformLocation(m_depthRenderProgram.programID, "modelMatrix");
-    m_depthRenderProgram.viewMatrixLoc = glGetUniformLocation(m_depthRenderProgram.programID, "viewMatrix");
-    m_depthRenderProgram.projectionMatrixLoc = glGetUniformLocation(m_depthRenderProgram.programID, "projectionMatrix");
-    m_depthRenderProgram.pointRadiusLoc = glGetUniformLocation(m_depthRenderProgram.programID, "pointRadius");
-    m_depthRenderProgram.pointScaleLoc = glGetUniformLocation(m_depthRenderProgram.programID, "pointScale");
-    m_depthRenderProgram.uColorLoc = glGetUniformLocation(m_depthRenderProgram.programID, "uColor");
-    m_depthRenderProgram.sphereRadiusLoc = glGetUniformLocation(m_depthRenderProgram.programID, "sphereRadius"); // For depth shader
-    m_depthRenderProgram.nearPlaneLoc = glGetUniformLocation(m_depthRenderProgram.programID, "zNear");       // Corrected uniform name
-    m_depthRenderProgram.farPlaneLoc = glGetUniformLocation(m_depthRenderProgram.programID, "zFar");         // Corrected uniform name
-
-    if (m_depthRenderProgram.pointRadiusLoc != -1)
-        glUniform1f(m_depthRenderProgram.pointRadiusLoc, 20.0f);
-    if (m_depthRenderProgram.pointScaleLoc != -1)
-        glUniform1f(m_depthRenderProgram.pointScaleLoc, 10.0f);
-    if (m_depthRenderProgram.sphereRadiusLoc != -1)
-        glUniform1f(m_depthRenderProgram.sphereRadiusLoc, 1.0f); // Set to desired sphere radius
-
-    // Set near and far planes
-    float cameraNearPlane = m_camera->getNearPlane(); // Replace with actual method
-    float cameraFarPlane = m_camera->getFarPlane();   // Replace with actual method
-
-    if (m_depthRenderProgram.nearPlaneLoc != -1) {
-        glUniform1f(m_depthRenderProgram.nearPlaneLoc, cameraNearPlane);
+    if (shaderProgram.pointScaleLoc != -1) {
+        glUniform1f(shaderProgram.pointScaleLoc, 10.0f);
     }
-    if (m_depthRenderProgram.farPlaneLoc != -1) {
-        glUniform1f(m_depthRenderProgram.farPlaneLoc, cameraFarPlane);
+    // For model matrix, set to Identity by default
+    if (shaderProgram.modelMatrixLoc != -1) {
+        mat4 modelMatrix = IdentityMatrix();
+        glUniformMatrix4fv(shaderProgram.modelMatrixLoc, 1, GL_TRUE, modelMatrix.m);
+    }
+    // For near/far planes, if present
+    if (shaderProgram.nearPlaneLoc != -1 || shaderProgram.farPlaneLoc != -1) {
+        float cameraNearPlane = m_camera->getNearPlane(); 
+        float cameraFarPlane  = m_camera->getFarPlane();
+
+        if (shaderProgram.nearPlaneLoc != -1) {
+            glUniform1f(shaderProgram.nearPlaneLoc, cameraNearPlane);
+        }
+        if (shaderProgram.farPlaneLoc != -1) {
+            glUniform1f(shaderProgram.farPlaneLoc, cameraFarPlane);
+        }
     }
 
-    glUniformMatrix4fv(m_depthRenderProgram.modelMatrixLoc, 1, GL_TRUE, modelMatrix.m);
+    std::cout << "Shader (ID " << shaderProgram.programID
+              << ") uniform/attribute locations have been fetched and set where applicable.\n";
+}
 
-    std::cout << "Depth Render Shader uniforms initialized." << std::endl;
+// Initialize Shader Uniforms
+void FluidRenderer::initShaderUniforms()
+{
+    // Normal render program:
+    setupShaderProgram(m_normalRenderProgram);
 
-    // Visualization Shader Uniforms
-    glUseProgram(m_visualizationProgram.programID);
+    // Depth render program:
+    setupShaderProgram(m_depthRenderProgram);
 
-    m_visualizationProgram.positionAttribLoc = glGetAttribLocation(m_visualizationProgram.programID, "aPos");
-    if (m_visualizationProgram.positionAttribLoc == -1) {
-        fprintf(stderr, "Visualization Shader: Could not find attribute 'aPos'\n");
-    } else {
-        printf("Visualization Shader: Attribute 'aPos' location: %d\n", m_visualizationProgram.positionAttribLoc);
-    }
+    // Visualization program:
+    setupShaderProgram(m_visualizationProgram);
 
-    std::cout << "Visualization Shader uniforms initialized." << std::endl;
+    std::cout << "All shader programs' uniforms initialized via setupShaderProgram()." << std::endl;
 }
 
 void FluidRenderer::initializeFramebuffer(ShaderProgram& shaderProgram, GLenum textureInternalFormat, GLenum textureFormat, GLenum textureType) {
@@ -304,6 +301,38 @@ void FluidRenderer::initFullscreenQuad() {
     std::cout << "Fullscreen quad initialized." << std::endl;
 }
 
+void FluidRenderer::resizeFramebuffer(
+    ShaderProgram& shaderProgram,
+    GLenum textureInternalFormat,
+    GLenum textureFormat,
+    GLenum textureType,
+    int newWidth,
+    int newHeight)
+{
+    // Bind the FBO
+    glBindFramebuffer(GL_FRAMEBUFFER, shaderProgram.fbo);
+
+    // Resize the texture
+    glBindTexture(GL_TEXTURE_2D, shaderProgram.fboTexture);
+    glTexImage2D(GL_TEXTURE_2D, 0, textureInternalFormat,
+                 newWidth, newHeight, 0,
+                 textureFormat, textureType, nullptr);
+
+    // Resize the renderbuffer
+    glBindRenderbuffer(GL_RENDERBUFFER, shaderProgram.depthRBO);
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, newWidth, newHeight);
+
+    // Check completeness
+    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+        fprintf(stderr, "FBO (ID %d) not complete after resize: 0x%X\n",
+                shaderProgram.programID, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+    }
+
+    // Unbind
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+
 // Resize Framebuffers
 void FluidRenderer::resizeFBO(int newWidth, int newHeight) {
     if (newWidth <= 0 || newHeight <= 0) return;
@@ -312,33 +341,19 @@ void FluidRenderer::resizeFBO(int newWidth, int newHeight) {
     m_fbHeight = newHeight;
 
     // Resize Normal Render Shader FBO
-    glBindFramebuffer(GL_FRAMEBUFFER, m_normalRenderProgram.fbo);
-
-    glBindTexture(GL_TEXTURE_2D, m_normalRenderProgram.fboTexture);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_fbWidth, m_fbHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-
-    glBindRenderbuffer(GL_RENDERBUFFER, m_normalRenderProgram.depthRBO);
-    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, m_fbWidth, m_fbHeight);
-
-    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
-        fprintf(stderr, "Normal Render Shader FBO not complete after resize: 0x%X\n", glCheckFramebufferStatus(GL_FRAMEBUFFER));
-    }
+    resizeFramebuffer(m_normalRenderProgram,
+                      GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE,
+                      newWidth, newHeight);
 
     // Resize Depth Render Shader FBO
-    glBindFramebuffer(GL_FRAMEBUFFER, m_depthRenderProgram.fbo);
+    resizeFramebuffer(m_depthRenderProgram,
+                      GL_R32F, GL_RED, GL_FLOAT,
+                      newWidth, newHeight);
 
-    glBindTexture(GL_TEXTURE_2D, m_depthRenderProgram.fboTexture);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, m_fbWidth, m_fbHeight, 0, GL_RED, GL_FLOAT, NULL); // Use GL_R32F for depth storage
-
-    glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderProgram.depthRBO);
-    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, m_fbWidth, m_fbHeight);
-
-    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
-        fprintf(stderr, "Depth Render Shader FBO not complete after resize: 0x%X\n", glCheckFramebufferStatus(GL_FRAMEBUFFER));
-    }
-
-    // Unbind framebuffer
-    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    // Resize Visualization Render Shader FBO
+    resizeFramebuffer(m_visualizationProgram,
+                      GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE,
+                      newWidth, newHeight);
 
     std::cout << "Framebuffers resized to " << newWidth << "x" << newHeight << "." << std::endl;
 }
@@ -349,62 +364,48 @@ void FluidRenderer::setVBOs(GLuint particleVBO, GLuint boundaryVBO) {
     m_boundaryVBO = boundaryVBO;
 }
 
-// Render Particles
-void FluidRenderer::renderParticles(size_t particleCount, const ShaderProgram& shader) {
-    // Set particle color
-    glUseProgram(shader.programID);
-    glUniform3f(shader.uColorLoc, 0.29f, 0.573f, 1.0f);
-    
-    // Bind the particle VBO
-    glBindBuffer(GL_ARRAY_BUFFER, m_particleVBO);
-    
-    // Enable the 'aPosition' attribute
-    glEnableVertexAttribArray(shader.positionAttribLoc);
-    
-    // Define the layout of the 'aPosition' attribute
+void FluidRenderer::renderPoints(GLuint vbo,
+                                 size_t count,
+                                 const ShaderProgram& shaderProgram,
+                                 const vec3& color)
+{
+    glUseProgram(shaderProgram.programID);
+    glUniform3f(shaderProgram.uColorLoc, color.x, color.y, color.z);
+
+    // Bind the VBO
+    glBindBuffer(GL_ARRAY_BUFFER, vbo);
+
+    // Enable position attribute
+    glEnableVertexAttribArray(shaderProgram.positionAttribLoc);
     glVertexAttribPointer(
-        shader.positionAttribLoc, // Attribute location
-        3,                        // Number of components (x, y, z)
-        GL_FLOAT,                 // Data type
-        GL_FALSE,                 // Normalized
-        sizeof(float3),           // Stride
-        (void*)0                  // Offset
+        shaderProgram.positionAttribLoc, // location
+        3,                               // number of components
+        GL_FLOAT,                        // type
+        GL_FALSE,                        // normalized?
+        sizeof(float3),                  // stride
+        (void*)0                         // offset
     );
-    
-    // Draw the particles as points
-    glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(particleCount));
-    
-    // Disable the 'aPosition' attribute
-    glDisableVertexAttribArray(shader.positionAttribLoc);
+
+    // Draw
+    glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(count));
+
+    // Disable
+    glDisableVertexAttribArray(shaderProgram.positionAttribLoc);
+}
+
+
+// Render Particles
+void FluidRenderer::renderParticles(size_t particleCount,
+                                    const ShaderProgram& shaderProgram)
+{
+    renderPoints(m_particleVBO, particleCount, shaderProgram, vec3(0.29f, 0.573f, 1.0f));
 }
 
 // Render Boundaries
-void FluidRenderer::renderBoundaries(size_t boundaryCount, const ShaderProgram& shader) {
-    // Set boundary color
-    glUseProgram(shader.programID);
-    glUniform3f(shader.uColorLoc, 0.29f, 1.0f, 0.57f);
-    
-    // Bind the boundary VBO
-    glBindBuffer(GL_ARRAY_BUFFER, m_boundaryVBO);
-    
-    // Enable the 'aPosition' attribute
-    glEnableVertexAttribArray(shader.positionAttribLoc);
-    
-    // Define the layout of the 'aPosition' attribute
-    glVertexAttribPointer(
-        shader.positionAttribLoc, // Attribute location
-        3,                        // Number of components (x, y, z)
-        GL_FLOAT,                 // Data type
-        GL_FALSE,                 // Normalized
-        sizeof(float3),           // Stride
-        (void*)0                  // Offset
-    );
-    
-    // Draw the boundary particles as points
-    glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(boundaryCount));
-    
-    // Disable the 'aPosition' attribute
-    glDisableVertexAttribArray(shader.positionAttribLoc);
+void FluidRenderer::renderBoundaries(size_t boundaryCount,
+                                     const ShaderProgram& shaderProgram)
+{
+    renderPoints(m_boundaryVBO, boundaryCount, shaderProgram, vec3(0.29f, 1.0f, 0.57f));
 }
 
 // Render Normal Frame
@@ -416,29 +417,23 @@ void FluidRenderer::renderNormalFrame(size_t particleCount, size_t boundaryCount
     // Set the viewport to match the framebuffer size
     glViewport(0, 0, m_fbWidth, m_fbHeight);
     
-    // Set clear color (background)
     glClearColor(0.9f, 0.9f, 0.9f, 1.0f);
     
     // Clear color and depth buffers
-    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
     
-    // Enable depth writing
     glDepthMask(GL_TRUE);
 
-    // Use the Normal Render Shader program
     glUseProgram(m_normalRenderProgram.programID);
     glBindVertexArray(particles_vao);
 
 
-    // Update shader with camera projection matrix
     mat4 projectionMatrix = m_camera->getProjectionMatrix();
     glUniformMatrix4fv(m_normalRenderProgram.projectionMatrixLoc, 1, GL_TRUE, projectionMatrix.m);
 
-    // Update shader with camera view matrix
     mat4 viewMatrix = m_camera->getViewMatrix();
     glUniformMatrix4fv(m_normalRenderProgram.viewMatrixLoc, 1, GL_TRUE, viewMatrix.m);
 
-    // Render particles
     renderParticles(particleCount, m_normalRenderProgram);
 
     // Render boundaries if enabled
@@ -459,35 +454,28 @@ void FluidRenderer::renderDepthFrame(size_t particleCount, size_t boundaryCount)
     // Set the viewport to match the framebuffer size
     glViewport(0, 0, m_fbWidth, m_fbHeight);
     
-    // Set clear color (background)
-    glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Typically black for depth
+    glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Typically black for depth?
 
     // Clear color and depth buffers
-    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
     
-    // Enable depth writing
     glDepthMask(GL_TRUE);
 
-    // Use the Depth Render Shader program
     glUseProgram(m_depthRenderProgram.programID);
     glBindVertexArray(particles_vao);
 
-    // Update shader with camera projection matrix
     mat4 projectionMatrix = m_camera->getProjectionMatrix();
     glUniformMatrix4fv(m_depthRenderProgram.projectionMatrixLoc, 1, GL_TRUE, projectionMatrix.m);
 
-    // Update shader with camera view matrix
     mat4 viewMatrix = m_camera->getViewMatrix();
     glUniformMatrix4fv(m_depthRenderProgram.viewMatrixLoc, 1, GL_TRUE, viewMatrix.m);
 
-    // Set sphereRadius uniform
     if (m_depthRenderProgram.sphereRadiusLoc != -1) {
-        glUniform1f(m_depthRenderProgram.sphereRadiusLoc, 1.0f); // Adjust based on your simulation
+        glUniform1f(m_depthRenderProgram.sphereRadiusLoc, 1.0f);
     }
 
-    // Set near and far planes
-    float cameraNearPlane = m_camera->getNearPlane(); // Replace with actual method
-    float cameraFarPlane = m_camera->getFarPlane();   // Replace with actual method
+    float cameraNearPlane = m_camera->getNearPlane();
+    float cameraFarPlane = m_camera->getFarPlane();
 
     if (m_depthRenderProgram.nearPlaneLoc != -1) {
         glUniform1f(m_depthRenderProgram.nearPlaneLoc, cameraNearPlane);
@@ -496,14 +484,8 @@ void FluidRenderer::renderDepthFrame(size_t particleCount, size_t boundaryCount)
         glUniform1f(m_depthRenderProgram.farPlaneLoc, cameraFarPlane);
     }
 
-    // Render particles
     renderParticles(particleCount, m_depthRenderProgram);
 
-    // Render boundaries if enabled
-    if (m_camera->shouldDisplayBorder()) {
-        renderBoundaries(boundaryCount, m_depthRenderProgram);
-    }
-
     // Unbind the framebuffer to return to default framebuffer
     glBindFramebuffer(GL_FRAMEBUFFER, 0);
 }
@@ -517,10 +499,8 @@ void FluidRenderer::visualizeBuffer(RenderStage stage)
     glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // White background for visualization
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
-    // Disable depth testing for visualization
     glDisable(GL_DEPTH_TEST);
 
-    // Use the Visualization Shader Program
     glUseProgram(m_visualizationProgram.programID);
 
     // Retrieve the appropriate texture based on RenderStage
@@ -549,20 +529,17 @@ void FluidRenderer::visualizeBuffer(RenderStage stage)
     glBindFramebuffer(GL_FRAMEBUFFER, 0);
 }
 
-// Retrieve Texture Based on RenderStage
 GLuint FluidRenderer::getTexture(RenderStage stage) const {
     switch (stage) {
         case RenderStage::FinalOutput:
             return m_normalRenderProgram.fboTexture;
         case RenderStage::DepthBuffer:
             return m_depthRenderProgram.fboTexture;
-        // Add more cases here if additional RenderStages are implemented
         default:
             return 0; // Return 0 if no valid stage was selected
     }
 }
 
-// Getter for Visualization Texture
 GLuint FluidRenderer::getVisualizationTexture() const {
     return m_visualizationProgram.fboTexture;
 }
diff --git a/src/include/FluidRenderer.h b/src/include/FluidRenderer.h
index 40d20c2646aa855c51701e8042642d7d777656cf..bebb5c8efd79254f08f6f0f09b7f82939b69e8ad 100644
--- a/src/include/FluidRenderer.h
+++ b/src/include/FluidRenderer.h
@@ -92,9 +92,22 @@ private:
     void initializeFramebuffer(ShaderProgram& shaderProgram, GLenum textureInternalFormat, GLenum textureFormat, GLenum textureType);
     void initFBOs();                    // Set up framebuffers for each shader program
     void initFullscreenQuad();          // Set up fullscreen quad for visualization
+    void setupShaderProgram(ShaderProgram& shaderProgram);
 
     void deleteFramebufferResources(ShaderProgram& shaderProgram);
-
+    void resizeFramebuffer(
+        ShaderProgram& shaderProgram,
+        GLenum textureInternalFormat,
+        GLenum textureFormat,
+        GLenum textureType,
+        int newWidth,
+        int newHeight);
+
+    void renderPoints(
+        GLuint vbo,
+        size_t count,
+        const ShaderProgram& shaderProgram,
+        const vec3& color);
     // Rendering helper methods
     void renderParticles(size_t particleCount, const ShaderProgram& shader);
     void renderBoundaries(size_t boundaryCount, const ShaderProgram& shader);