Added Textures
This commit is contained in:
parent
82d561c921
commit
1367bb0859
@ -1,10 +1,246 @@
|
|||||||
#include "ModelComponent.h"
|
#include "ModelComponent.h"
|
||||||
|
#include "stb_image.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
// Constructor: initialize material defaults, create default cube mesh, and load default textures.
|
||||||
ModelComponent::ModelComponent()
|
ModelComponent::ModelComponent()
|
||||||
: diffuseColor(1.0f, 1.0f, 1.0f),
|
: diffuseColor(1.0f, 1.0f, 1.0f),
|
||||||
specularColor(1.0f, 1.0f, 1.0f),
|
specularColor(1.0f, 1.0f, 1.0f),
|
||||||
shininess(32.0f) {
|
shininess(32.0f),
|
||||||
|
VAO(0), VBO(0), EBO(0),
|
||||||
|
diffuseTexture(0), normalTexture(0)
|
||||||
|
{
|
||||||
|
// Clear any previous data.
|
||||||
|
vertices.clear();
|
||||||
|
indices.clear();
|
||||||
|
|
||||||
|
// Create 24 vertices for a cube.
|
||||||
|
// Front face (z = 0.5)
|
||||||
|
Vertex v;
|
||||||
|
v.Normal = glm::vec3(0, 0, 1);
|
||||||
|
v.Tangent = glm::vec3(1, 0, 0);
|
||||||
|
// Top-left
|
||||||
|
v.Position = glm::vec3(-0.5f, 0.5f, 0.5f);
|
||||||
|
v.TexCoords = glm::vec2(0.0f, 1.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Bottom-left
|
||||||
|
v.Position = glm::vec3(-0.5f, -0.5f, 0.5f);
|
||||||
|
v.TexCoords = glm::vec2(0.0f, 0.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Bottom-right
|
||||||
|
v.Position = glm::vec3( 0.5f, -0.5f, 0.5f);
|
||||||
|
v.TexCoords = glm::vec2(1.0f, 0.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Top-right
|
||||||
|
v.Position = glm::vec3( 0.5f, 0.5f, 0.5f);
|
||||||
|
v.TexCoords = glm::vec2(1.0f, 1.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
|
||||||
|
// Right face (x = 0.5)
|
||||||
|
v.Normal = glm::vec3(1, 0, 0);
|
||||||
|
v.Tangent = glm::vec3(0, 0, -1);
|
||||||
|
// Top-left
|
||||||
|
v.Position = glm::vec3(0.5f, 0.5f, 0.5f);
|
||||||
|
v.TexCoords = glm::vec2(0.0f, 1.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Bottom-left
|
||||||
|
v.Position = glm::vec3(0.5f, -0.5f, 0.5f);
|
||||||
|
v.TexCoords = glm::vec2(0.0f, 0.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Bottom-right
|
||||||
|
v.Position = glm::vec3(0.5f, -0.5f, -0.5f);
|
||||||
|
v.TexCoords = glm::vec2(1.0f, 0.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Top-right
|
||||||
|
v.Position = glm::vec3(0.5f, 0.5f, -0.5f);
|
||||||
|
v.TexCoords = glm::vec2(1.0f, 1.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
|
||||||
|
// Back face (z = -0.5)
|
||||||
|
v.Normal = glm::vec3(0, 0, -1);
|
||||||
|
v.Tangent = glm::vec3(-1, 0, 0);
|
||||||
|
// Top-left
|
||||||
|
v.Position = glm::vec3( 0.5f, 0.5f, -0.5f);
|
||||||
|
v.TexCoords = glm::vec2(0.0f, 1.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Bottom-left
|
||||||
|
v.Position = glm::vec3( 0.5f, -0.5f, -0.5f);
|
||||||
|
v.TexCoords = glm::vec2(0.0f, 0.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Bottom-right
|
||||||
|
v.Position = glm::vec3(-0.5f, -0.5f, -0.5f);
|
||||||
|
v.TexCoords = glm::vec2(1.0f, 0.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Top-right
|
||||||
|
v.Position = glm::vec3(-0.5f, 0.5f, -0.5f);
|
||||||
|
v.TexCoords = glm::vec2(1.0f, 1.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
|
||||||
|
// Left face (x = -0.5)
|
||||||
|
v.Normal = glm::vec3(-1, 0, 0);
|
||||||
|
v.Tangent = glm::vec3(0, 0, 1);
|
||||||
|
// Top-left
|
||||||
|
v.Position = glm::vec3(-0.5f, 0.5f, -0.5f);
|
||||||
|
v.TexCoords = glm::vec2(0.0f, 1.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Bottom-left
|
||||||
|
v.Position = glm::vec3(-0.5f, -0.5f, -0.5f);
|
||||||
|
v.TexCoords = glm::vec2(0.0f, 0.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Bottom-right
|
||||||
|
v.Position = glm::vec3(-0.5f, -0.5f, 0.5f);
|
||||||
|
v.TexCoords = glm::vec2(1.0f, 0.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Top-right
|
||||||
|
v.Position = glm::vec3(-0.5f, 0.5f, 0.5f);
|
||||||
|
v.TexCoords = glm::vec2(1.0f, 1.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
|
||||||
|
// Top face (y = 0.5)
|
||||||
|
v.Normal = glm::vec3(0, 1, 0);
|
||||||
|
v.Tangent = glm::vec3(1, 0, 0);
|
||||||
|
// Top-left
|
||||||
|
v.Position = glm::vec3(-0.5f, 0.5f, -0.5f);
|
||||||
|
v.TexCoords = glm::vec2(0.0f, 1.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Bottom-left
|
||||||
|
v.Position = glm::vec3(-0.5f, 0.5f, 0.5f);
|
||||||
|
v.TexCoords = glm::vec2(0.0f, 0.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Bottom-right
|
||||||
|
v.Position = glm::vec3( 0.5f, 0.5f, 0.5f);
|
||||||
|
v.TexCoords = glm::vec2(1.0f, 0.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Top-right
|
||||||
|
v.Position = glm::vec3( 0.5f, 0.5f, -0.5f);
|
||||||
|
v.TexCoords = glm::vec2(1.0f, 1.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
|
||||||
|
// Bottom face (y = -0.5)
|
||||||
|
v.Normal = glm::vec3(0, -1, 0);
|
||||||
|
v.Tangent = glm::vec3(1, 0, 0);
|
||||||
|
// Top-left
|
||||||
|
v.Position = glm::vec3(-0.5f, -0.5f, 0.5f);
|
||||||
|
v.TexCoords = glm::vec2(0.0f, 1.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Bottom-left
|
||||||
|
v.Position = glm::vec3(-0.5f, -0.5f, -0.5f);
|
||||||
|
v.TexCoords = glm::vec2(0.0f, 0.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Bottom-right
|
||||||
|
v.Position = glm::vec3( 0.5f, -0.5f, -0.5f);
|
||||||
|
v.TexCoords = glm::vec2(1.0f, 0.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
// Top-right
|
||||||
|
v.Position = glm::vec3( 0.5f, -0.5f, 0.5f);
|
||||||
|
v.TexCoords = glm::vec2(1.0f, 1.0f);
|
||||||
|
vertices.push_back(v);
|
||||||
|
|
||||||
|
// Define indices: 6 faces, 2 triangles per face, 3 indices per triangle.
|
||||||
|
indices = {
|
||||||
|
0, 1, 2, 0, 2, 3, // Front face
|
||||||
|
4, 5, 6, 4, 6, 7, // Right face
|
||||||
|
8, 9, 10, 8, 10, 11, // Back face
|
||||||
|
12, 13, 14, 12, 14, 15, // Left face
|
||||||
|
16, 17, 18, 16, 18, 19, // Top face
|
||||||
|
20, 21, 22, 20, 22, 23 // Bottom face
|
||||||
|
};
|
||||||
|
|
||||||
|
// Setup mesh with the new vertex/index data.
|
||||||
|
SetupMesh();
|
||||||
|
|
||||||
|
// Load default textures.
|
||||||
|
if(!LoadDiffuseTexture("./assets/bricks.png")) {
|
||||||
|
std::cout << "Warning: Failed to load default diffuse texture 'bricks.png'\n";
|
||||||
|
}
|
||||||
|
if(!LoadNormalTexture("./assets/normal.png")) {
|
||||||
|
std::cout << "Warning: Failed to load default normal texture 'normal.png'\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelComponent::~ModelComponent() {
|
ModelComponent::~ModelComponent() {
|
||||||
|
if(VAO) glDeleteVertexArrays(1, &VAO);
|
||||||
|
if(VBO) glDeleteBuffers(1, &VBO);
|
||||||
|
if(EBO) glDeleteBuffers(1, &EBO);
|
||||||
|
if(diffuseTexture) glDeleteTextures(1, &diffuseTexture);
|
||||||
|
if(normalTexture) glDeleteTextures(1, &normalTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelComponent::SetupMesh() {
|
||||||
|
glGenVertexArrays(1, &VAO);
|
||||||
|
glGenBuffers(1, &VBO);
|
||||||
|
glGenBuffers(1, &EBO);
|
||||||
|
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// Vertex attributes:
|
||||||
|
// Positions.
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
// Normals.
|
||||||
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
// TexCoords.
|
||||||
|
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, TexCoords));
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
// Tangents.
|
||||||
|
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Tangent));
|
||||||
|
glEnableVertexAttribArray(3);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadDiffuseTexture loads a diffuse texture from file.
|
||||||
|
bool ModelComponent::LoadDiffuseTexture(const std::string &filepath) {
|
||||||
|
int w, h, channels;
|
||||||
|
unsigned char* data = stbi_load(filepath.c_str(), &w, &h, &channels, 0);
|
||||||
|
if (!data) {
|
||||||
|
std::cout << "Failed to load diffuse texture: " << filepath << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
glGenTextures(1, &diffuseTexture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, diffuseTexture);
|
||||||
|
GLenum format = (channels == 3) ? GL_RGB : GL_RGBA;
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, data);
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
stbi_image_free(data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadNormalTexture loads a normal map texture from file.
|
||||||
|
bool ModelComponent::LoadNormalTexture(const std::string &filepath) {
|
||||||
|
int w, h, channels;
|
||||||
|
unsigned char* data = stbi_load(filepath.c_str(), &w, &h, &channels, 0);
|
||||||
|
if (!data) {
|
||||||
|
std::cout << "Failed to load normal texture: " << filepath << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
glGenTextures(1, &normalTexture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, normalTexture);
|
||||||
|
GLenum format = (channels == 3) ? GL_RGB : GL_RGBA;
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, data);
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
stbi_image_free(data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the mesh using its VAO.
|
||||||
|
void ModelComponent::Draw() {
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(indices.size()), GL_UNSIGNED_INT, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,17 @@
|
|||||||
#define MODEL_COMPONENT_H
|
#define MODEL_COMPONENT_H
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
// Structure representing a single vertex.
|
||||||
|
struct Vertex {
|
||||||
|
glm::vec3 Position;
|
||||||
|
glm::vec3 Normal;
|
||||||
|
glm::vec2 TexCoords;
|
||||||
|
glm::vec3 Tangent;
|
||||||
|
};
|
||||||
|
|
||||||
class ModelComponent {
|
class ModelComponent {
|
||||||
public:
|
public:
|
||||||
@ -12,6 +23,27 @@ public:
|
|||||||
glm::vec3 diffuseColor;
|
glm::vec3 diffuseColor;
|
||||||
glm::vec3 specularColor;
|
glm::vec3 specularColor;
|
||||||
float shininess;
|
float shininess;
|
||||||
|
|
||||||
|
// Mesh data.
|
||||||
|
std::vector<Vertex> vertices;
|
||||||
|
std::vector<GLuint> indices;
|
||||||
|
|
||||||
|
// OpenGL buffers.
|
||||||
|
GLuint VAO, VBO, EBO;
|
||||||
|
|
||||||
|
// Texture handles.
|
||||||
|
GLuint diffuseTexture;
|
||||||
|
GLuint normalTexture;
|
||||||
|
|
||||||
|
// Set up the mesh by creating VAO, VBO, and EBO.
|
||||||
|
void SetupMesh();
|
||||||
|
|
||||||
|
// Load textures from file.
|
||||||
|
bool LoadDiffuseTexture(const std::string &filepath);
|
||||||
|
bool LoadNormalTexture(const std::string &filepath);
|
||||||
|
|
||||||
|
// Draw the mesh.
|
||||||
|
void Draw();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MODEL_COMPONENT_H
|
#endif // MODEL_COMPONENT_H
|
||||||
|
@ -31,7 +31,7 @@ public:
|
|||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
|
|
||||||
// Offscreen render function that uses the provided camera parameters and renders the scene
|
// Offscreen render function that uses the provided camera parameters and renders the scene
|
||||||
// (with entities) offscreen. Returns the color attachment as an ImTextureID.
|
// (with entities) offscreen. Returns its color attachment as an ImTextureID.
|
||||||
static ImTextureID RenderScene(const glm::mat4 &view, const glm::mat4 &projection, const glm::vec3 &viewPos, const std::vector<Entity*>& entities);
|
static ImTextureID RenderScene(const glm::mat4 &view, const glm::mat4 &projection, const glm::vec3 &viewPos, const std::vector<Entity*>& entities);
|
||||||
|
|
||||||
// Resizes the offscreen framebuffer to the given dimensions.
|
// Resizes the offscreen framebuffer to the given dimensions.
|
||||||
@ -40,28 +40,14 @@ public:
|
|||||||
// Retrieves the final rendered texture.
|
// Retrieves the final rendered texture.
|
||||||
static ImTextureID GetFinalRenderingTexture();
|
static ImTextureID GetFinalRenderingTexture();
|
||||||
|
|
||||||
// --- Billboard Rendering for 3D Icons ---
|
|
||||||
// Billboard shader and VAO for drawing icons (e.g., light icons) as billboards in 3D space.
|
|
||||||
static GLuint billboardShaderProgram;
|
|
||||||
static GLuint billboardVAO;
|
|
||||||
// Sets up billboard resources.
|
|
||||||
static bool SetupBillboard();
|
|
||||||
// Draws a billboarded icon at the given world position with a specified size.
|
|
||||||
static void DrawIconIn3DSpace(const glm::vec3 &worldPos, const glm::vec2 &size, ImTextureID texture, const glm::mat4 &view, const glm::mat4 &projection);
|
|
||||||
// Iterates over entities and draws icons for those of the appropriate type.
|
|
||||||
static void DrawIconsIn3DSpace(const std::vector<Entity*>& entities, const glm::mat4 &view, const glm::mat4 &projection, ImTextureID iconTexture);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Offscreen framebuffer and its attachments.
|
// Offscreen framebuffer and its attachments.
|
||||||
static GLuint framebuffer;
|
static GLuint framebuffer;
|
||||||
static GLuint colorTexture;
|
static GLuint colorTexture;
|
||||||
static GLuint depthRenderbuffer;
|
static GLuint depthRenderbuffer;
|
||||||
// Geometry for a simple cube.
|
|
||||||
static GLuint cubeVAO;
|
|
||||||
static GLuint cubeVBO;
|
|
||||||
// Shader program used for rendering the scene.
|
// Shader program used for rendering the scene.
|
||||||
static GLuint shaderProgram;
|
static GLuint shaderProgram;
|
||||||
// Rotation angle for the spinning cube (or animated models).
|
// Rotation angle (if needed for animated models).
|
||||||
static float rotationAngle;
|
static float rotationAngle;
|
||||||
// Current offscreen framebuffer dimensions.
|
// Current offscreen framebuffer dimensions.
|
||||||
static int fbWidth;
|
static int fbWidth;
|
||||||
@ -69,7 +55,7 @@ private:
|
|||||||
|
|
||||||
// Helper function to compile and link shaders.
|
// Helper function to compile and link shaders.
|
||||||
static GLuint CompileShader(const char* vertexSrc, const char* fragmentSrc);
|
static GLuint CompileShader(const char* vertexSrc, const char* fragmentSrc);
|
||||||
// Sets up cube geometry and shader (called during initialization).
|
// Sets up common scene resources (e.g. loading the scene shader).
|
||||||
static bool SetupScene();
|
static bool SetupScene();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,22 +4,22 @@
|
|||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include "stb_image.h"
|
#include "stb_image.h"
|
||||||
#include "Entity/Entity.h"
|
#include "Entity/Entity.h"
|
||||||
|
|
||||||
// Static member definitions.
|
// Static member definitions.
|
||||||
GLFWwindow* Engine::window = nullptr;
|
GLFWwindow* Engine::window = nullptr;
|
||||||
GLuint Engine::framebuffer = 0;
|
GLuint Engine::framebuffer = 0;
|
||||||
GLuint Engine::colorTexture = 0;
|
GLuint Engine::colorTexture = 0;
|
||||||
GLuint Engine::depthRenderbuffer = 0;
|
GLuint Engine::depthRenderbuffer = 0;
|
||||||
GLuint Engine::cubeVAO = 0;
|
|
||||||
GLuint Engine::cubeVBO = 0;
|
|
||||||
GLuint Engine::shaderProgram = 0;
|
GLuint Engine::shaderProgram = 0;
|
||||||
float Engine::rotationAngle = 0.0f;
|
float Engine::rotationAngle = 0.0f;
|
||||||
int Engine::fbWidth = 640;
|
int Engine::fbWidth = 640;
|
||||||
int Engine::fbHeight = 400;
|
int Engine::fbHeight = 400;
|
||||||
|
|
||||||
GLuint normalMapTexture = 0; // Global texture for the normal map
|
|
||||||
|
|
||||||
GLuint Engine::billboardShaderProgram = 0;
|
|
||||||
GLuint Engine::billboardVAO = 0;
|
|
||||||
|
// Global normal map texture (if needed for legacy models; otherwise each model handles its own)
|
||||||
|
GLuint normalMapTexture = 0;
|
||||||
|
|
||||||
bool Engine::Init() {
|
bool Engine::Init() {
|
||||||
if (!glfwInit()) {
|
if (!glfwInit()) {
|
||||||
@ -52,7 +52,7 @@ bool Engine::Init() {
|
|||||||
glGenFramebuffers(1, &framebuffer);
|
glGenFramebuffers(1, &framebuffer);
|
||||||
ResizeFramebuffer(fbWidth, fbHeight);
|
ResizeFramebuffer(fbWidth, fbHeight);
|
||||||
|
|
||||||
// Setup cube geometry, shaders, and load normal map.
|
// Setup scene-wide shader (this shader is now used to render all models)
|
||||||
if (!SetupScene()) {
|
if (!SetupScene()) {
|
||||||
std::cout << "Failed to set up scene\n";
|
std::cout << "Failed to set up scene\n";
|
||||||
return false;
|
return false;
|
||||||
@ -77,10 +77,8 @@ void Engine::ResizeFramebuffer(int width, int height) {
|
|||||||
int newWidth = width;
|
int newWidth = width;
|
||||||
int newHeight = height;
|
int newHeight = height;
|
||||||
if (currentAspect > targetAspect) {
|
if (currentAspect > targetAspect) {
|
||||||
// Too wide: adjust width.
|
|
||||||
newWidth = static_cast<int>(height * targetAspect);
|
newWidth = static_cast<int>(height * targetAspect);
|
||||||
} else if (currentAspect < targetAspect) {
|
} else if (currentAspect < targetAspect) {
|
||||||
// Too tall: adjust height.
|
|
||||||
newHeight = static_cast<int>(width / targetAspect);
|
newHeight = static_cast<int>(width / targetAspect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,184 +154,10 @@ GLuint Engine::CompileShader(const char* vertexSrc, const char* fragmentSrc) {
|
|||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetupScene now creates the shader program used for all models.
|
||||||
|
// It no longer creates cube-specific VAOs, since ModelComponent will store mesh data.
|
||||||
|
|
||||||
bool Engine::SetupBillboard() {
|
|
||||||
// Simple billboard vertex shader.
|
|
||||||
const char* billboardVertexSrc = R"(
|
|
||||||
#version 330 core
|
|
||||||
layout(location = 0) in vec3 aPos;
|
|
||||||
layout(location = 1) in vec2 aTexCoords;
|
|
||||||
|
|
||||||
uniform mat4 model;
|
|
||||||
uniform mat4 view;
|
|
||||||
uniform mat4 projection;
|
|
||||||
|
|
||||||
out vec2 TexCoords;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
TexCoords = aTexCoords;
|
|
||||||
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
// Simple billboard fragment shader.
|
|
||||||
const char* billboardFragmentSrc = R"(
|
|
||||||
#version 330 core
|
|
||||||
out vec4 FragColor;
|
|
||||||
in vec2 TexCoords;
|
|
||||||
uniform sampler2D billboardTexture;
|
|
||||||
void main() {
|
|
||||||
FragColor = texture(billboardTexture, TexCoords);
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
billboardShaderProgram = CompileShader(billboardVertexSrc, billboardFragmentSrc);
|
|
||||||
if (billboardShaderProgram == 0) return false;
|
|
||||||
|
|
||||||
// Define a quad (two triangles) for the billboard.
|
|
||||||
float quadVertices[] = {
|
|
||||||
// positions // texcoords
|
|
||||||
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
|
|
||||||
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
|
|
||||||
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
|
|
||||||
|
|
||||||
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
|
|
||||||
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
|
|
||||||
0.5f, 0.5f, 0.0f, 1.0f, 1.0f
|
|
||||||
};
|
|
||||||
|
|
||||||
GLuint VBO;
|
|
||||||
glGenVertexArrays(1, &billboardVAO);
|
|
||||||
glGenBuffers(1, &VBO);
|
|
||||||
glBindVertexArray(billboardVAO);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW);
|
|
||||||
// position attribute.
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
// texcoord attribute.
|
|
||||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
glDeleteBuffers(1, &VBO);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Engine::DrawIconIn3DSpace(const glm::vec3 &worldPos, const glm::vec2 &size, ImTextureID texture, const glm::mat4 &view, const glm::mat4 &projection) {
|
|
||||||
// Compute billboard matrix (extract inverse rotation from view).
|
|
||||||
glm::mat4 billboard = glm::mat4(1.0f);
|
|
||||||
billboard[0] = glm::vec4(view[0][0], view[1][0], view[2][0], 0.0f);
|
|
||||||
billboard[1] = glm::vec4(view[0][1], view[1][1], view[2][1], 0.0f);
|
|
||||||
billboard[2] = glm::vec4(view[0][2], view[1][2], view[2][2], 0.0f);
|
|
||||||
billboard = glm::transpose(billboard);
|
|
||||||
|
|
||||||
glm::mat4 model = glm::translate(glm::mat4(1.0f), worldPos);
|
|
||||||
model *= billboard;
|
|
||||||
model = glm::scale(model, glm::vec3(size, 1.0f));
|
|
||||||
|
|
||||||
glUseProgram(billboardShaderProgram);
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(billboardShaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(model));
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(billboardShaderProgram, "view"), 1, GL_FALSE, glm::value_ptr(view));
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(billboardShaderProgram, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
|
|
||||||
|
|
||||||
// Bind icon texture.
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)texture);
|
|
||||||
glUniform1i(glGetUniformLocation(billboardShaderProgram, "billboardTexture"), 0);
|
|
||||||
|
|
||||||
// Disable depth test so icon appears on top.
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
glBindVertexArray(billboardVAO);
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
glEnable(GL_DEPTH_TEST); // Re-enable depth testing.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Engine::DrawIconsIn3DSpace(const std::vector<Entity*>& entities, const glm::mat4 &view, const glm::mat4 &projection, ImTextureID iconTexture) {
|
|
||||||
for(auto e : entities) {
|
|
||||||
if(e->GetType() == EntityType::LIGHT) {
|
|
||||||
// Draw a billboard icon at the light's world position.
|
|
||||||
DrawIconIn3DSpace(e->transform.position, glm::vec2(1.0f, 1.0f), iconTexture, view, projection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Engine::SetupScene() {
|
bool Engine::SetupScene() {
|
||||||
// Updated cube vertices: each vertex has:
|
// Vertex shader: passes through vertex attributes.
|
||||||
// position (3), normal (3), texcoord (2), tangent (3) = 11 floats per vertex.
|
|
||||||
float vertices[] = {
|
|
||||||
// Front face (normal: 0,0,1), tangent: (1,0,0)
|
|
||||||
// positions normals texcoords tangent
|
|
||||||
-0.5f, -0.5f, 0.5f, 0,0,1, 0,0, 1,0,0,
|
|
||||||
0.5f, -0.5f, 0.5f, 0,0,1, 1,0, 1,0,0,
|
|
||||||
0.5f, 0.5f, 0.5f, 0,0,1, 1,1, 1,0,0,
|
|
||||||
0.5f, 0.5f, 0.5f, 0,0,1, 1,1, 1,0,0,
|
|
||||||
-0.5f, 0.5f, 0.5f, 0,0,1, 0,1, 1,0,0,
|
|
||||||
-0.5f, -0.5f, 0.5f, 0,0,1, 0,0, 1,0,0,
|
|
||||||
|
|
||||||
// Back face (normal: 0,0,-1), tangent: (-1,0,0)
|
|
||||||
0.5f, -0.5f, -0.5f, 0,0,-1, 0,0, -1,0,0,
|
|
||||||
-0.5f, -0.5f, -0.5f, 0,0,-1, 1,0, -1,0,0,
|
|
||||||
-0.5f, 0.5f, -0.5f, 0,0,-1, 1,1, -1,0,0,
|
|
||||||
-0.5f, 0.5f, -0.5f, 0,0,-1, 1,1, -1,0,0,
|
|
||||||
0.5f, 0.5f, -0.5f, 0,0,-1, 0,1, -1,0,0,
|
|
||||||
0.5f, -0.5f, -0.5f, 0,0,-1, 0,0, -1,0,0,
|
|
||||||
|
|
||||||
// Left face (normal: -1,0,0), tangent: (0,0,-1)
|
|
||||||
-0.5f, -0.5f, -0.5f, -1,0,0, 0,0, 0,0,-1,
|
|
||||||
-0.5f, -0.5f, 0.5f, -1,0,0, 1,0, 0,0,-1,
|
|
||||||
-0.5f, 0.5f, 0.5f, -1,0,0, 1,1, 0,0,-1,
|
|
||||||
-0.5f, 0.5f, 0.5f, -1,0,0, 1,1, 0,0,-1,
|
|
||||||
-0.5f, 0.5f, -0.5f, -1,0,0, 0,1, 0,0,-1,
|
|
||||||
-0.5f, -0.5f, -0.5f, -1,0,0, 0,0, 0,0,-1,
|
|
||||||
|
|
||||||
// Right face (normal: 1,0,0), tangent: (0,0,1)
|
|
||||||
0.5f, -0.5f, 0.5f, 1,0,0, 0,0, 0,0,1,
|
|
||||||
0.5f, -0.5f, -0.5f, 1,0,0, 1,0, 0,0,1,
|
|
||||||
0.5f, 0.5f, -0.5f, 1,0,0, 1,1, 0,0,1,
|
|
||||||
0.5f, 0.5f, -0.5f, 1,0,0, 1,1, 0,0,1,
|
|
||||||
0.5f, 0.5f, 0.5f, 1,0,0, 0,1, 0,0,1,
|
|
||||||
0.5f, -0.5f, 0.5f, 1,0,0, 0,0, 0,0,1,
|
|
||||||
|
|
||||||
// Top face (normal: 0,1,0), tangent: (1,0,0)
|
|
||||||
-0.5f, 0.5f, 0.5f, 0,1,0, 0,0, 1,0,0,
|
|
||||||
0.5f, 0.5f, 0.5f, 0,1,0, 1,0, 1,0,0,
|
|
||||||
0.5f, 0.5f, -0.5f, 0,1,0, 1,1, 1,0,0,
|
|
||||||
0.5f, 0.5f, -0.5f, 0,1,0, 1,1, 1,0,0,
|
|
||||||
-0.5f, 0.5f, -0.5f, 0,1,0, 0,1, 1,0,0,
|
|
||||||
-0.5f, 0.5f, 0.5f, 0,1,0, 0,0, 1,0,0,
|
|
||||||
|
|
||||||
// Bottom face (normal: 0,-1,0), tangent: (1,0,0)
|
|
||||||
-0.5f, -0.5f, -0.5f, 0,-1,0, 0,0, 1,0,0,
|
|
||||||
0.5f, -0.5f, -0.5f, 0,-1,0, 1,0, 1,0,0,
|
|
||||||
0.5f, -0.5f, 0.5f, 0,-1,0, 1,1, 1,0,0,
|
|
||||||
0.5f, -0.5f, 0.5f, 0,-1,0, 1,1, 1,0,0,
|
|
||||||
-0.5f, -0.5f, 0.5f, 0,-1,0, 0,1, 1,0,0,
|
|
||||||
-0.5f, -0.5f, -0.5f, 0,-1,0, 0,0, 1,0,0
|
|
||||||
};
|
|
||||||
|
|
||||||
glGenVertexArrays(1, &cubeVAO);
|
|
||||||
glGenBuffers(1, &cubeVBO);
|
|
||||||
glBindVertexArray(cubeVAO);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
|
||||||
// Position attribute.
|
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(float), (void*)0);
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
// Normal attribute.
|
|
||||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(float), (void*)(3 * sizeof(float)));
|
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
// Texcoord attribute.
|
|
||||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 11 * sizeof(float), (void*)(6 * sizeof(float)));
|
|
||||||
glEnableVertexAttribArray(2);
|
|
||||||
// Tangent attribute.
|
|
||||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 11 * sizeof(float), (void*)(8 * sizeof(float)));
|
|
||||||
glEnableVertexAttribArray(3);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
|
|
||||||
const char* vertexShaderSrc = R"(
|
const char* vertexShaderSrc = R"(
|
||||||
#version 330 core
|
#version 330 core
|
||||||
layout(location = 0) in vec3 aPos;
|
layout(location = 0) in vec3 aPos;
|
||||||
@ -359,6 +183,7 @@ bool Engine::SetupScene() {
|
|||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
// Fragment shader: uses a normal map and material properties.
|
||||||
const char* fragmentShaderSrc = R"(
|
const char* fragmentShaderSrc = R"(
|
||||||
#version 330 core
|
#version 330 core
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
@ -372,6 +197,7 @@ bool Engine::SetupScene() {
|
|||||||
uniform vec3 lightColors[2];
|
uniform vec3 lightColors[2];
|
||||||
uniform int numLights;
|
uniform int numLights;
|
||||||
uniform vec3 viewPos;
|
uniform vec3 viewPos;
|
||||||
|
uniform sampler2D diffuseTexture;
|
||||||
uniform sampler2D normalMap;
|
uniform sampler2D normalMap;
|
||||||
|
|
||||||
// Material properties.
|
// Material properties.
|
||||||
@ -380,6 +206,7 @@ bool Engine::SetupScene() {
|
|||||||
uniform float materialShininess;
|
uniform float materialShininess;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
// Sample normal map.
|
||||||
vec3 normMap = texture(normalMap, TexCoords).rgb;
|
vec3 normMap = texture(normalMap, TexCoords).rgb;
|
||||||
normMap = normalize(normMap * 2.0 - 1.0);
|
normMap = normalize(normMap * 2.0 - 1.0);
|
||||||
normMap.z = -normMap.z;
|
normMap.z = -normMap.z;
|
||||||
@ -389,12 +216,14 @@ bool Engine::SetupScene() {
|
|||||||
mat3 TBN = mat3(T, B, N);
|
mat3 TBN = mat3(T, B, N);
|
||||||
vec3 perturbedNormal = normalize(TBN * normMap);
|
vec3 perturbedNormal = normalize(TBN * normMap);
|
||||||
|
|
||||||
vec3 ambient = 0.1 * materialDiffuse;
|
vec3 diffuseTex = texture(diffuseTexture, TexCoords).rgb;
|
||||||
|
|
||||||
|
vec3 ambient = 0.1 * materialDiffuse * diffuseTex;
|
||||||
vec3 lighting = ambient;
|
vec3 lighting = ambient;
|
||||||
for(int i = 0; i < numLights; i++) {
|
for(int i = 0; i < numLights; i++) {
|
||||||
vec3 lightDir = normalize(lightPositions[i] - FragPos);
|
vec3 lightDir = normalize(lightPositions[i] - FragPos);
|
||||||
float diff = max(dot(perturbedNormal, lightDir), 0.0);
|
float diff = max(dot(perturbedNormal, lightDir), 0.0);
|
||||||
vec3 diffuse = diff * materialDiffuse * lightColors[i];
|
vec3 diffuse = diff * materialDiffuse * diffuseTex * lightColors[i];
|
||||||
|
|
||||||
vec3 viewDir = normalize(viewPos - FragPos);
|
vec3 viewDir = normalize(viewPos - FragPos);
|
||||||
vec3 reflectDir = reflect(-lightDir, perturbedNormal);
|
vec3 reflectDir = reflect(-lightDir, perturbedNormal);
|
||||||
@ -407,44 +236,18 @@ bool Engine::SetupScene() {
|
|||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
|
||||||
shaderProgram = CompileShader(vertexShaderSrc, fragmentShaderSrc);
|
shaderProgram = CompileShader(vertexShaderSrc, fragmentShaderSrc);
|
||||||
if (shaderProgram == 0) {
|
if (shaderProgram == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SetupBillboard()) {
|
// Optionally, if you want a global normal map fallback you can load it here.
|
||||||
std::cout << "Failed to set up billboard resources." << std::endl;
|
// Otherwise, each ModelComponent should load its own textures.
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Load normal map from "./normal.png"
|
|
||||||
int texWidth, texHeight, texChannels;
|
|
||||||
unsigned char* data = stbi_load("./normal.jpg", &texWidth, &texHeight, &texChannels, 0);
|
|
||||||
if (!data) {
|
|
||||||
std::cout << "Failed to load normal map." << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
glGenTextures(1, &normalMapTexture);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, normalMapTexture);
|
|
||||||
GLenum format = (texChannels == 3) ? GL_RGB : GL_RGBA;
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, format, texWidth, texHeight, 0, format, GL_UNSIGNED_BYTE, data);
|
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
|
||||||
// Set texture parameters.
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
stbi_image_free(data);
|
|
||||||
|
|
||||||
// Bind the normal map to texture unit 1.
|
|
||||||
glUseProgram(shaderProgram);
|
|
||||||
glUniform1i(glGetUniformLocation(shaderProgram, "normalMap"), 1);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RenderScene now uses the new model system.
|
||||||
|
// For each entity of type CUBE with a valid ModelComponent, update uniforms and call Draw() on the model.
|
||||||
ImTextureID Engine::RenderScene(const glm::mat4 &view, const glm::mat4 &projection, const glm::vec3 &viewPos, const std::vector<Entity*>& entities) {
|
ImTextureID Engine::RenderScene(const glm::mat4 &view, const glm::mat4 &projection, const glm::vec3 &viewPos, const std::vector<Entity*>& entities) {
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||||
glViewport(0, 0, fbWidth, fbHeight);
|
glViewport(0, 0, fbWidth, fbHeight);
|
||||||
@ -476,12 +279,7 @@ ImTextureID Engine::RenderScene(const glm::mat4 &view, const glm::mat4 &projecti
|
|||||||
glUniform3fv(glGetUniformLocation(shaderProgram, "lightColors"), lightCount, glm::value_ptr(lightColors[0]));
|
glUniform3fv(glGetUniformLocation(shaderProgram, "lightColors"), lightCount, glm::value_ptr(lightColors[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bind the normal map on texture unit 1.
|
// Render each cube entity using its ModelComponent.
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, normalMapTexture);
|
|
||||||
// (Assumes that the uniform "normalMap" is already set to 1.)
|
|
||||||
|
|
||||||
// Render cube entities.
|
|
||||||
for (auto e : entities) {
|
for (auto e : entities) {
|
||||||
if (e->GetType() == EntityType::CUBE && e->modelComponent) {
|
if (e->GetType() == EntityType::CUBE && e->modelComponent) {
|
||||||
glm::mat4 modelMatrix = e->transform.GetMatrix();
|
glm::mat4 modelMatrix = e->transform.GetMatrix();
|
||||||
@ -489,25 +287,29 @@ ImTextureID Engine::RenderScene(const glm::mat4 &view, const glm::mat4 &projecti
|
|||||||
glUniform3fv(glGetUniformLocation(shaderProgram, "materialDiffuse"), 1, glm::value_ptr(e->modelComponent->diffuseColor));
|
glUniform3fv(glGetUniformLocation(shaderProgram, "materialDiffuse"), 1, glm::value_ptr(e->modelComponent->diffuseColor));
|
||||||
glUniform3fv(glGetUniformLocation(shaderProgram, "materialSpecular"), 1, glm::value_ptr(e->modelComponent->specularColor));
|
glUniform3fv(glGetUniformLocation(shaderProgram, "materialSpecular"), 1, glm::value_ptr(e->modelComponent->specularColor));
|
||||||
glUniform1f(glGetUniformLocation(shaderProgram, "materialShininess"), e->modelComponent->shininess);
|
glUniform1f(glGetUniformLocation(shaderProgram, "materialShininess"), e->modelComponent->shininess);
|
||||||
glBindVertexArray(cubeVAO);
|
// Bind the diffuse texture to texture unit 0.
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, e->modelComponent->diffuseTexture);
|
||||||
|
glUniform1i(glGetUniformLocation(shaderProgram, "diffuseTexture"), 0);
|
||||||
|
// Bind the normal texture to texture unit 1.
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, e->modelComponent->normalTexture);
|
||||||
|
glUniform1i(glGetUniformLocation(shaderProgram, "normalMap"), 1);
|
||||||
|
|
||||||
|
// Draw the model.
|
||||||
|
e->modelComponent->Draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glBindVertexArray(0);
|
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
return (ImTextureID)(intptr_t)colorTexture;
|
return (ImTextureID)(intptr_t)colorTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ImTextureID Engine::GetFinalRenderingTexture() {
|
ImTextureID Engine::GetFinalRenderingTexture() {
|
||||||
return (ImTextureID)(intptr_t)colorTexture;
|
return (ImTextureID)(intptr_t)colorTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::Shutdown() {
|
void Engine::Shutdown() {
|
||||||
glDeleteVertexArrays(1, &cubeVAO);
|
|
||||||
glDeleteBuffers(1, &cubeVBO);
|
|
||||||
glDeleteProgram(shaderProgram);
|
glDeleteProgram(shaderProgram);
|
||||||
glDeleteFramebuffers(1, &framebuffer);
|
glDeleteFramebuffers(1, &framebuffer);
|
||||||
glDeleteTextures(1, &colorTexture);
|
glDeleteTextures(1, &colorTexture);
|
||||||
|
BIN
Three-Labs.exe
BIN
Three-Labs.exe
Binary file not shown.
BIN
assets/bricks.png
Normal file
BIN
assets/bricks.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.2 MiB |
BIN
assets/normal.png
Normal file
BIN
assets/normal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 MiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user