2024-12-25 23:35:38 +00:00
|
|
|
// RenderWindow.cpp
|
|
|
|
|
2024-12-25 21:44:33 +00:00
|
|
|
#include "RenderWindow.h"
|
2024-12-26 00:15:18 +00:00
|
|
|
#include <vector> // Add this line
|
|
|
|
|
2024-12-25 21:44:33 +00:00
|
|
|
#include <GL/glew.h>
|
2024-12-25 23:01:05 +00:00
|
|
|
#include <glm/gtc/matrix_transform.hpp>
|
|
|
|
#include <glm/gtc/type_ptr.hpp>
|
2024-12-25 21:44:33 +00:00
|
|
|
#include "imgui.h"
|
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
#include "gcml.h"
|
2024-12-26 00:15:18 +00:00
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
#include "Componenets/GameObject.h"
|
|
|
|
#include "Componenets/mesh.h"
|
|
|
|
#include "Componenets/transform.h"
|
2024-12-26 00:15:18 +00:00
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
extern std::vector<std::shared_ptr<GameObject>> g_GameObjects;
|
2024-12-26 00:53:17 +00:00
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
#define CAM_FOV 45.0f
|
|
|
|
#define CAM_NEAR_PLAIN 0.1f
|
|
|
|
#define CAM_FAR_PLAIN 1000.0f
|
2024-12-26 00:15:18 +00:00
|
|
|
|
2024-12-25 23:35:38 +00:00
|
|
|
// Include your AssetManager & Shader headers
|
|
|
|
#include "Engine/AssetManager.h"
|
|
|
|
#include "Rendering/Shader.h"
|
2024-12-25 21:44:33 +00:00
|
|
|
|
2024-12-25 23:35:38 +00:00
|
|
|
// Extern reference to our global (or extern) asset manager
|
2024-12-25 23:01:05 +00:00
|
|
|
extern AssetManager g_AssetManager;
|
2024-12-25 21:44:33 +00:00
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
|
2024-12-29 02:50:39 +00:00
|
|
|
extern int g_GPU_Triangles_drawn_to_screen;
|
2024-12-27 01:34:34 +00:00
|
|
|
|
2024-12-25 23:35:38 +00:00
|
|
|
// Example cube data (position + UVs)
|
2024-12-25 23:01:05 +00:00
|
|
|
static float g_CubeVertices[] =
|
2024-12-27 01:34:34 +00:00
|
|
|
{
|
|
|
|
// FRONT (z=+1)
|
|
|
|
-1.f,
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
0.f,
|
|
|
|
0.f,
|
|
|
|
1.f,
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
0.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
0.f,
|
|
|
|
1.f,
|
|
|
|
|
|
|
|
// BACK (z=-1)
|
|
|
|
-1.f,
|
|
|
|
-1.f,
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
0.f,
|
|
|
|
1.f,
|
|
|
|
-1.f,
|
|
|
|
-1.f,
|
|
|
|
0.f,
|
|
|
|
0.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
-1.f,
|
|
|
|
0.f,
|
|
|
|
1.f,
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
|
|
|
|
// LEFT (x=-1)
|
|
|
|
-1.f,
|
|
|
|
-1.f,
|
|
|
|
-1.f,
|
|
|
|
0.f,
|
|
|
|
0.f,
|
|
|
|
-1.f,
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
0.f,
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
-1.f,
|
|
|
|
0.f,
|
|
|
|
1.f,
|
|
|
|
|
|
|
|
// RIGHT (x=+1)
|
|
|
|
1.f,
|
|
|
|
-1.f,
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
0.f,
|
|
|
|
1.f,
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
0.f,
|
|
|
|
0.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
0.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
|
|
|
|
// TOP (y=+1)
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
-1.f,
|
|
|
|
0.f,
|
|
|
|
0.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
0.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
0.f,
|
|
|
|
1.f,
|
|
|
|
|
|
|
|
// BOTTOM (y=-1)
|
|
|
|
-1.f,
|
|
|
|
-1.f,
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
0.f,
|
|
|
|
1.f,
|
|
|
|
-1.f,
|
|
|
|
-1.f,
|
|
|
|
0.f,
|
|
|
|
0.f,
|
|
|
|
1.f,
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
0.f,
|
|
|
|
1.f,
|
|
|
|
-1.f,
|
|
|
|
-1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
|
|
|
1.f,
|
2024-12-25 23:01:05 +00:00
|
|
|
};
|
2024-12-25 21:44:33 +00:00
|
|
|
|
2024-12-25 23:01:05 +00:00
|
|
|
static unsigned int g_CubeIndices[] =
|
2024-12-27 01:34:34 +00:00
|
|
|
{
|
|
|
|
// Front
|
|
|
|
0, 1, 2, 2, 3, 0,
|
|
|
|
// Back
|
|
|
|
4, 5, 6, 6, 7, 4,
|
|
|
|
// Left
|
|
|
|
8, 9, 10, 10, 11, 8,
|
|
|
|
// Right
|
|
|
|
12, 13, 14, 14, 15, 12,
|
|
|
|
// Top
|
|
|
|
16, 17, 18, 18, 19, 16,
|
|
|
|
// Bottom
|
|
|
|
20, 21, 22, 22, 23, 20};
|
2024-12-25 21:44:33 +00:00
|
|
|
|
2024-12-29 02:50:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool PlayPauseButton(const char* label, bool* isPlaying)
|
2024-12-25 21:44:33 +00:00
|
|
|
{
|
2024-12-29 02:50:39 +00:00
|
|
|
// Define button size
|
|
|
|
ImVec2 buttonSize = ImVec2(50, 50); // Adjust size as needed
|
|
|
|
|
|
|
|
// Begin the button
|
|
|
|
if (ImGui::Button(label, buttonSize))
|
|
|
|
{
|
|
|
|
// Toggle the state
|
|
|
|
*isPlaying = !(*isPlaying);
|
|
|
|
return true; // Indicate that the state was toggled
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add tooltip
|
|
|
|
if (ImGui::IsItemHovered())
|
|
|
|
{
|
|
|
|
ImGui::SetTooltip(*isPlaying ? "Pause (Space)" : "Play (Space)");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the current window's draw list
|
|
|
|
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
|
|
|
|
|
|
|
// Get the position of the button
|
|
|
|
ImVec2 button_pos = ImGui::GetItemRectMin();
|
|
|
|
ImVec2 button_size = ImGui::GetItemRectSize();
|
|
|
|
ImVec2 center = ImVec2(button_pos.x + button_size.x * 0.5f, button_pos.y + button_size.y * 0.5f);
|
|
|
|
|
|
|
|
// Define icon size
|
|
|
|
float icon_size = 20.0f;
|
|
|
|
float half_icon_size = icon_size / 2.0f;
|
|
|
|
|
|
|
|
// Define colors
|
|
|
|
ImU32 icon_color = ImGui::GetColorU32(ImGuiCol_Text);
|
|
|
|
|
|
|
|
if (*isPlaying)
|
|
|
|
{
|
|
|
|
// Draw Pause Icon (two vertical bars)
|
|
|
|
float bar_width = 4.0f;
|
|
|
|
float spacing = 6.0f;
|
|
|
|
|
|
|
|
// Left bar
|
|
|
|
ImVec2 left_bar_p1 = ImVec2(center.x - spacing - bar_width, center.y - half_icon_size);
|
|
|
|
ImVec2 left_bar_p2 = ImVec2(center.x - spacing, center.y + half_icon_size);
|
|
|
|
draw_list->AddRectFilled(left_bar_p1, left_bar_p2, icon_color, 2.0f);
|
|
|
|
|
|
|
|
// Right bar
|
|
|
|
ImVec2 right_bar_p1 = ImVec2(center.x + spacing, center.y - half_icon_size);
|
|
|
|
ImVec2 right_bar_p2 = ImVec2(center.x + spacing + bar_width, center.y + half_icon_size);
|
|
|
|
draw_list->AddRectFilled(right_bar_p1, right_bar_p2, icon_color, 2.0f);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Draw Play Icon (triangle)
|
|
|
|
ImVec2 p1 = ImVec2(center.x - half_icon_size, center.y - half_icon_size);
|
|
|
|
ImVec2 p2 = ImVec2(center.x - half_icon_size, center.y + half_icon_size);
|
|
|
|
ImVec2 p3 = ImVec2(center.x + half_icon_size, center.y);
|
|
|
|
draw_list->AddTriangleFilled(p1, p2, p3, icon_color);
|
|
|
|
}
|
|
|
|
|
|
|
|
return false; // No toggle occurred
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void RenderWindow::Show(bool *GameRunning)
|
|
|
|
{
|
|
|
|
|
|
|
|
ImGui::Begin("Editor##EditorWindow");
|
2024-12-25 21:44:33 +00:00
|
|
|
|
|
|
|
ImVec2 size = ImGui::GetContentRegionAvail();
|
2024-12-25 23:01:05 +00:00
|
|
|
int w = static_cast<int>(size.x);
|
|
|
|
int h = static_cast<int>(size.y);
|
2024-12-25 21:44:33 +00:00
|
|
|
|
|
|
|
if (!m_Initialized)
|
|
|
|
{
|
|
|
|
InitGLResources();
|
|
|
|
m_Initialized = true;
|
|
|
|
}
|
|
|
|
|
2024-12-29 02:50:39 +00:00
|
|
|
// Center the button
|
|
|
|
ImGui::SetCursorPosX((ImGui::GetWindowWidth() - 60) * 0.5f);
|
|
|
|
|
|
|
|
// Render the Play/Pause button
|
|
|
|
// Render the Play/Pause button
|
|
|
|
PlayPauseButton("##PlayPauseButton", GameRunning);
|
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
|
|
|
|
|
2024-12-25 23:35:38 +00:00
|
|
|
// If there's space, render to the FBO, then show it as an ImGui image
|
2024-12-27 01:34:34 +00:00
|
|
|
|
2024-12-25 21:44:33 +00:00
|
|
|
if (w > 0 && h > 0)
|
|
|
|
{
|
|
|
|
if (w != m_LastWidth || h != m_LastHeight)
|
|
|
|
{
|
2024-12-29 02:50:39 +00:00
|
|
|
|
2024-12-25 21:44:33 +00:00
|
|
|
m_FBO.Create(w, h);
|
2024-12-27 01:34:34 +00:00
|
|
|
m_LastWidth = w;
|
2024-12-25 21:44:33 +00:00
|
|
|
m_LastHeight = h;
|
|
|
|
}
|
|
|
|
|
|
|
|
RenderSceneToFBO();
|
2024-12-27 01:34:34 +00:00
|
|
|
|
|
|
|
ImGui::Image(m_FBO.GetTextureID(), size, ImVec2(0, 0), ImVec2(1, 1));
|
2024-12-25 21:44:33 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ImGui::Text("No space to render.");
|
|
|
|
}
|
|
|
|
|
2024-12-29 02:50:39 +00:00
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
|
2024-12-29 02:50:39 +00:00
|
|
|
ImGui::End();
|
2024-12-25 21:44:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void RenderWindow::InitGLResources()
|
|
|
|
{
|
2024-12-25 23:35:38 +00:00
|
|
|
// ----------------------------------------------------
|
|
|
|
// 1) Load SHADER from the asset manager
|
|
|
|
// ----------------------------------------------------
|
2024-12-27 01:34:34 +00:00
|
|
|
|
2024-12-25 21:44:33 +00:00
|
|
|
{
|
2024-12-29 02:50:39 +00:00
|
|
|
Shader *shaderAsset = g_AssetManager.loadAsset<Shader *>(AssetType::SHADER, "assets/shaders/UnlitMaterial");
|
2024-12-25 23:35:38 +00:00
|
|
|
if (!shaderAsset)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "[RenderWindow] Failed to load shader via AssetManager.\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Cast back to your Shader class
|
2024-12-27 01:34:34 +00:00
|
|
|
m_ShaderPtr = static_cast<Shader *>(shaderAsset);
|
2024-12-25 21:44:33 +00:00
|
|
|
}
|
|
|
|
|
2024-12-25 23:35:38 +00:00
|
|
|
// ----------------------------------------------------
|
|
|
|
// 2) Create VAO/VBO/EBO for the cube
|
|
|
|
// ----------------------------------------------------
|
2024-12-25 21:44:33 +00:00
|
|
|
glGenVertexArrays(1, &m_VAO);
|
|
|
|
glBindVertexArray(m_VAO);
|
|
|
|
|
|
|
|
glGenBuffers(1, &m_VBO);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(g_CubeVertices), g_CubeVertices, GL_STATIC_DRAW);
|
|
|
|
|
|
|
|
glGenBuffers(1, &m_EBO);
|
|
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_EBO);
|
|
|
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(g_CubeIndices), g_CubeIndices, GL_STATIC_DRAW);
|
|
|
|
|
2024-12-25 23:35:38 +00:00
|
|
|
// Position = location 0, UV = location 1
|
|
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
|
2024-12-27 01:34:34 +00:00
|
|
|
5 * sizeof(float), (void *)0);
|
2024-12-25 21:44:33 +00:00
|
|
|
glEnableVertexAttribArray(0);
|
|
|
|
|
2024-12-25 23:01:05 +00:00
|
|
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,
|
2024-12-27 01:34:34 +00:00
|
|
|
5 * sizeof(float), (void *)(3 * sizeof(float)));
|
2024-12-25 21:44:33 +00:00
|
|
|
glEnableVertexAttribArray(1);
|
|
|
|
|
|
|
|
glBindVertexArray(0);
|
2024-12-25 23:01:05 +00:00
|
|
|
|
2024-12-25 23:35:38 +00:00
|
|
|
// ----------------------------------------------------
|
|
|
|
// 3) Load TEXTURE from the asset manager
|
|
|
|
// ----------------------------------------------------
|
2024-12-25 23:01:05 +00:00
|
|
|
{
|
2024-12-27 18:19:20 +00:00
|
|
|
GLuint texAsset = g_AssetManager.loadAsset<GLuint>(AssetType::TEXTURE, "assets/textures/wood.png");
|
2024-12-25 23:35:38 +00:00
|
|
|
if (!texAsset)
|
2024-12-25 23:01:05 +00:00
|
|
|
{
|
2024-12-25 23:35:38 +00:00
|
|
|
fprintf(stderr, "[RenderWindow] Failed to load texture.\n");
|
2024-12-25 23:01:05 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2024-12-25 23:35:38 +00:00
|
|
|
// Cast from void* to GLuint
|
2024-12-27 18:19:20 +00:00
|
|
|
m_TextureID = texAsset;
|
2024-12-25 23:01:05 +00:00
|
|
|
}
|
|
|
|
}
|
2024-12-26 00:15:18 +00:00
|
|
|
|
|
|
|
// ----------------------------------------------------
|
|
|
|
// 4) Initialize GameObjects
|
|
|
|
// ----------------------------------------------------
|
2024-12-27 01:34:34 +00:00
|
|
|
}
|
2024-12-26 00:15:18 +00:00
|
|
|
|
2024-12-25 21:44:33 +00:00
|
|
|
void RenderWindow::RenderSceneToFBO()
|
|
|
|
{
|
2024-12-27 01:34:34 +00:00
|
|
|
|
|
|
|
m_RotationAngle += 0.001f; // spin per frame
|
2024-12-25 21:44:33 +00:00
|
|
|
|
2024-12-26 00:15:18 +00:00
|
|
|
// Bind the FBO
|
2024-12-25 21:44:33 +00:00
|
|
|
m_FBO.Bind();
|
|
|
|
glViewport(0, 0, m_LastWidth, m_LastHeight);
|
|
|
|
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
2024-12-25 23:01:05 +00:00
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
glClearColor(0.f, 0.f, 0.f, 1.f);
|
2024-12-25 21:44:33 +00:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
|
2024-12-25 23:35:38 +00:00
|
|
|
// Use our loaded shader
|
2024-12-27 01:34:34 +00:00
|
|
|
|
2024-12-26 00:15:18 +00:00
|
|
|
if (!m_ShaderPtr)
|
|
|
|
return; // Can't render without a shader
|
2024-12-25 21:44:33 +00:00
|
|
|
|
2024-12-26 00:15:18 +00:00
|
|
|
m_ShaderPtr->Use();
|
2024-12-25 23:35:38 +00:00
|
|
|
GLuint programID = m_ShaderPtr->GetProgramID();
|
2024-12-25 21:44:33 +00:00
|
|
|
|
2024-12-26 00:15:18 +00:00
|
|
|
// Define view and projection matrices once
|
|
|
|
glm::mat4 view = glm::translate(glm::mat4(1.f), glm::vec3(0.f, 0.f, -5.f));
|
|
|
|
float aspect = (m_LastHeight != 0) ? (float)m_LastWidth / (float)m_LastHeight : 1.0f;
|
2024-12-26 00:53:17 +00:00
|
|
|
glm::mat4 proj = glm::perspective(glm::radians(CAM_FOV), aspect, CAM_NEAR_PLAIN, CAM_FAR_PLAIN);
|
2024-12-25 23:35:38 +00:00
|
|
|
|
2024-12-26 00:15:18 +00:00
|
|
|
// Iterate over each GameObject and render it
|
2024-12-27 01:34:34 +00:00
|
|
|
|
|
|
|
for (auto &obj : g_GameObjects)
|
2024-12-29 02:50:39 +00:00
|
|
|
{
|
2024-12-27 01:34:34 +00:00
|
|
|
|
2024-12-26 00:15:18 +00:00
|
|
|
// -----------------------------------
|
2024-12-27 01:34:34 +00:00
|
|
|
// 1) Build MVP from transform
|
2024-12-26 00:15:18 +00:00
|
|
|
// -----------------------------------
|
|
|
|
glm::mat4 model = glm::mat4(1.f);
|
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
std::shared_ptr<TransformComponent> transform = obj->GetComponent<TransformComponent>();
|
2024-12-26 00:15:18 +00:00
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
std::shared_ptr<MeshComponent> mesh = obj->GetComponent<MeshComponent>();
|
2024-12-26 00:15:18 +00:00
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
if (transform && mesh)
|
|
|
|
{
|
2024-12-29 02:50:39 +00:00
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
// Translate
|
|
|
|
|
2024-12-27 21:27:05 +00:00
|
|
|
g_GPU_Triangles_drawn_to_screen += static_cast<int>(mesh->indexCount);
|
2024-12-27 01:34:34 +00:00
|
|
|
|
|
|
|
model = glm::translate(model, transform->position);
|
2024-12-26 00:15:18 +00:00
|
|
|
|
2024-12-27 01:34:34 +00:00
|
|
|
// Rotate around X, Y, Z
|
|
|
|
|
2024-12-29 02:50:39 +00:00
|
|
|
// transform->rotation.x += m_RotationAngle;
|
2024-12-27 01:34:34 +00:00
|
|
|
model = glm::rotate(model, glm::radians(transform->rotation.x), glm::vec3(1.f, 0.f, 0.f));
|
|
|
|
model = glm::rotate(model, glm::radians(transform->rotation.y), glm::vec3(0.f, 1.f, 0.f));
|
|
|
|
model = glm::rotate(model, glm::radians(transform->rotation.z), glm::vec3(0.f, 0.f, 1.f));
|
|
|
|
|
|
|
|
// Scale
|
|
|
|
model = glm::scale(model, transform->scale);
|
|
|
|
|
|
|
|
// Compute MVP
|
|
|
|
glm::mat4 mvp = proj * view * model;
|
|
|
|
|
|
|
|
// Pass MVP to the shader
|
|
|
|
GLint mvpLoc = glGetUniformLocation(programID, "uMVP");
|
|
|
|
glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, glm::value_ptr(mvp));
|
|
|
|
|
|
|
|
// -----------------------------------
|
|
|
|
// 2) Bind the object's texture
|
|
|
|
// -----------------------------------
|
|
|
|
glActiveTexture(GL_TEXTURE0);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, mesh->textureID);
|
|
|
|
|
|
|
|
// Set the sampler uniform to texture unit 0
|
|
|
|
GLint texLoc = glGetUniformLocation(programID, "uTexture");
|
|
|
|
glUniform1i(texLoc, 0);
|
|
|
|
|
|
|
|
// -----------------------------------
|
|
|
|
// 3) Draw the object's mesh
|
|
|
|
// -----------------------------------
|
|
|
|
glBindVertexArray(mesh->vao);
|
|
|
|
glDrawElements(GL_TRIANGLES, mesh->indexCount, GL_UNSIGNED_INT, nullptr);
|
|
|
|
|
|
|
|
// Unbind for cleanliness
|
|
|
|
glBindVertexArray(0);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
}
|
2024-12-26 00:15:18 +00:00
|
|
|
}
|
2024-12-25 21:44:33 +00:00
|
|
|
|
2024-12-25 23:01:05 +00:00
|
|
|
// Cleanup
|
2024-12-26 00:15:18 +00:00
|
|
|
glUseProgram(0);
|
2024-12-25 23:35:38 +00:00
|
|
|
m_FBO.Unbind();
|
2024-12-25 21:44:33 +00:00
|
|
|
}
|