Made a simple rendering system
This commit is contained in:
parent
6df51450ca
commit
04d6c0ed82
9
.vscode/settings.json
vendored
Normal file
9
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"*.pyx": "python",
|
||||
"*.js": "javascript",
|
||||
"*.c": "c",
|
||||
"*.scene": "yaml",
|
||||
"iostream": "cpp"
|
||||
}
|
||||
}
|
@ -1,56 +1,132 @@
|
||||
#include "../Engine/Engine.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_glfw.h"
|
||||
#include "imgui_impl_opengl3.h"
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
// Simple editor camera.
|
||||
struct EditorCamera {
|
||||
glm::vec3 position = glm::vec3(0.0f, 0.0f, 5.0f);
|
||||
float yaw = -90.0f;
|
||||
float pitch = 0.0f;
|
||||
float speed = 5.0f;
|
||||
float sensitivity = 0.1f;
|
||||
glm::mat4 view = glm::mat4(1.0f);
|
||||
glm::mat4 projection = glm::mat4(1.0f);
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// Initialize the engine (GLFW window + OpenGL)
|
||||
EditorCamera editorCamera;
|
||||
|
||||
void ProcessEditorCamera(GLFWwindow* window, float deltaTime) {
|
||||
glm::vec3 front;
|
||||
front.x = cos(glm::radians(editorCamera.yaw)) * cos(glm::radians(editorCamera.pitch));
|
||||
front.y = sin(glm::radians(editorCamera.pitch));
|
||||
front.z = sin(glm::radians(editorCamera.yaw)) * cos(glm::radians(editorCamera.pitch));
|
||||
front = glm::normalize(front);
|
||||
glm::vec3 right = glm::normalize(glm::cross(front, glm::vec3(0,1,0)));
|
||||
|
||||
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
||||
editorCamera.position += front * editorCamera.speed * deltaTime;
|
||||
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
|
||||
editorCamera.position -= front * editorCamera.speed * deltaTime;
|
||||
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
|
||||
editorCamera.position -= right * editorCamera.speed * deltaTime;
|
||||
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
||||
editorCamera.position += right * editorCamera.speed * deltaTime;
|
||||
|
||||
static double lastX = 0, lastY = 0;
|
||||
if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS) {
|
||||
double xpos, ypos;
|
||||
glfwGetCursorPos(window, &xpos, &ypos);
|
||||
if (lastX == 0 && lastY == 0) { lastX = xpos; lastY = ypos; }
|
||||
float offsetX = (float)(xpos - lastX);
|
||||
float offsetY = (float)(lastY - ypos);
|
||||
lastX = xpos;
|
||||
lastY = ypos;
|
||||
editorCamera.yaw += offsetX * editorCamera.sensitivity;
|
||||
editorCamera.pitch += offsetY * editorCamera.sensitivity;
|
||||
if (editorCamera.pitch > 89.0f) editorCamera.pitch = 89.0f;
|
||||
if (editorCamera.pitch < -89.0f) editorCamera.pitch = -89.0f;
|
||||
} else {
|
||||
lastX = lastY = 0;
|
||||
}
|
||||
editorCamera.view = glm::lookAt(editorCamera.position, editorCamera.position + front, glm::vec3(0,1,0));
|
||||
}
|
||||
|
||||
int main() {
|
||||
if (!Engine::Init())
|
||||
return 1;
|
||||
|
||||
//// Setup Dear ImGui context
|
||||
// Setup ImGui.
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable docking
|
||||
|
||||
// Set the style for ImGui
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
// Specify the GLSL version and initialize backends
|
||||
const char* glsl_version = "#version 330";
|
||||
ImGui_ImplGlfw_InitForOpenGL(Engine::GetWindow(), true);
|
||||
ImGui_ImplOpenGL3_Init(glsl_version);
|
||||
|
||||
// Main loop
|
||||
while (!glfwWindowShouldClose(Engine::GetWindow()))
|
||||
{
|
||||
Engine::BeginFrame();
|
||||
float lastFrameTime = (float)glfwGetTime();
|
||||
|
||||
//// Start a new ImGui frame
|
||||
while (!glfwWindowShouldClose(Engine::GetWindow())) {
|
||||
float currentFrameTime = (float)glfwGetTime();
|
||||
float deltaTime = currentFrameTime - lastFrameTime;
|
||||
lastFrameTime = currentFrameTime;
|
||||
|
||||
ProcessEditorCamera(Engine::GetWindow(), deltaTime);
|
||||
|
||||
// Update editor camera projection based on the window size.
|
||||
int winWidth, winHeight;
|
||||
glfwGetFramebufferSize(Engine::GetWindow(), &winWidth, &winHeight);
|
||||
editorCamera.projection = glm::perspective(glm::radians(45.0f), (float)winWidth / winHeight, 0.1f, 100.0f);
|
||||
|
||||
// Offscreen rendering: Resize framebuffer and render scene.
|
||||
Engine::ResizeFramebuffer(winWidth, winHeight);
|
||||
ImTextureID offscreenTexture = Engine::RenderScene(editorCamera.view, editorCamera.projection, editorCamera.position);
|
||||
|
||||
// Clear the default framebuffer background.
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glViewport(0, 0, winWidth, winHeight);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Clear with black (or choose any color).
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Start a single ImGui frame.
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
// Create a full-viewport docking space
|
||||
ImGui::DockSpaceOverViewport();
|
||||
// Create a full-viewport dock space.
|
||||
ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode);
|
||||
|
||||
// Create an editor window
|
||||
|
||||
// Create an "Editor Panel" window.
|
||||
ImGui::Begin("Editor Panel");
|
||||
ImGui::Text("Welcome to the Editor!");
|
||||
// Additional UI elements can be added here
|
||||
// (Additional UI elements can go here.)
|
||||
ImGui::End();
|
||||
|
||||
// Render ImGui data
|
||||
// Create a "Rendered Output" window.
|
||||
ImGui::Begin("Rendered Output");
|
||||
// Get available region size for the rendered output.
|
||||
ImVec2 viewportSize = ImGui::GetContentRegionAvail();
|
||||
// Display the offscreen texture. The UVs are flipped to correct the upside-down image.
|
||||
ImGui::Image(offscreenTexture, viewportSize, ImVec2(0,1), ImVec2(1,0));
|
||||
ImGui::End();
|
||||
|
||||
// Finalize and render the ImGui frame.
|
||||
ImGui::Render();
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
Engine::EndFrame();
|
||||
glfwSwapBuffers(Engine::GetWindow());
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
// Cleanup ImGui and terminate GLFW
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
glfwTerminate();
|
||||
Engine::Shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,33 +1,66 @@
|
||||
#pragma once
|
||||
#ifndef ENGINE_H
|
||||
#define ENGINE_H
|
||||
|
||||
#include <iostream>
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include "../vendor/imgui-docking/imgui.h"
|
||||
#include "../vendor/imgui-docking/imgui_impl_glfw.h"
|
||||
#include "../vendor/imgui-docking/imgui_impl_opengl3_loader.h"
|
||||
#include "../vendor/imgui-docking/imgui_impl_opengl3.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_opengl3.h"
|
||||
#include "imgui_impl_glfw.h"
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
class Engine {
|
||||
public:
|
||||
// Initializes GLFW, creates a window, and sets up the OpenGL context.
|
||||
// Main window.
|
||||
static GLFWwindow* window;
|
||||
|
||||
// Initializes GLFW, GLEW, and sets up the main window and offscreen framebuffer.
|
||||
static bool Init();
|
||||
|
||||
// Clears the screen.
|
||||
static void BeginFrame();
|
||||
|
||||
// Swaps buffers and polls for events.
|
||||
static void EndFrame();
|
||||
|
||||
// Returns the pointer to the GLFW window.
|
||||
// Returns the main GLFW window.
|
||||
static GLFWwindow* GetWindow();
|
||||
|
||||
// Clean up resources and shutdown GLFW.
|
||||
static void Shutdown();
|
||||
|
||||
// Offscreen render function that uses the provided camera parameters.
|
||||
// It renders the scene (e.g., a spinning cube with red lighting) offscreen
|
||||
// and returns its color attachment as an ImTextureID.
|
||||
static ImTextureID RenderScene(const glm::mat4 &view, const glm::mat4 &projection, const glm::vec3 &viewPos);
|
||||
|
||||
// Resizes the offscreen framebuffer to the given dimensions.
|
||||
static void ResizeFramebuffer(int width, int height);
|
||||
|
||||
// Retrieves the final rendered texture.
|
||||
static ImTextureID GetFinalRenderingTexture();
|
||||
|
||||
private:
|
||||
static GLFWwindow* window;
|
||||
// Offscreen framebuffer and its attachments.
|
||||
static GLuint framebuffer;
|
||||
static GLuint colorTexture;
|
||||
static GLuint depthRenderbuffer;
|
||||
|
||||
// Geometry for a simple cube.
|
||||
static GLuint cubeVAO;
|
||||
static GLuint cubeVBO;
|
||||
|
||||
// Shader program used for rendering the scene.
|
||||
static GLuint shaderProgram;
|
||||
|
||||
// Rotation angle for the spinning cube.
|
||||
static float rotationAngle;
|
||||
|
||||
// Current offscreen framebuffer dimensions.
|
||||
static int fbWidth;
|
||||
static int fbHeight;
|
||||
|
||||
// Helper function to compile and link shaders.
|
||||
static GLuint CompileShader(const char* vertexSrc, const char* fragmentSrc);
|
||||
|
||||
// Sets up cube geometry and shader (called during initialization).
|
||||
static bool SetupScene();
|
||||
};
|
||||
|
||||
#endif // ENGINE_H
|
||||
|
@ -1,51 +1,299 @@
|
||||
#include "Engine.h"
|
||||
#include <iostream>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
// Static member definitions.
|
||||
GLFWwindow* Engine::window = nullptr;
|
||||
GLuint Engine::framebuffer = 0;
|
||||
GLuint Engine::colorTexture = 0;
|
||||
GLuint Engine::depthRenderbuffer = 0;
|
||||
GLuint Engine::cubeVAO = 0;
|
||||
GLuint Engine::cubeVBO = 0;
|
||||
GLuint Engine::shaderProgram = 0;
|
||||
float Engine::rotationAngle = 0.0f;
|
||||
int Engine::fbWidth = 640;
|
||||
int Engine::fbHeight = 400;
|
||||
|
||||
bool Engine::Init() {
|
||||
if (!glfwInit()) {
|
||||
std::cout << "Failed to initialize GLFW\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Specify the OpenGL version (e.g., 3.3 Core Profile)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
// Create the GLFW window
|
||||
window = glfwCreateWindow(1280, 800, "Engine Window", nullptr, nullptr);
|
||||
if (!window) {
|
||||
std::cout << "Failed to create GLFW window\n";
|
||||
glfwTerminate();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make the OpenGL context current
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
glewExperimental = GL_TRUE;
|
||||
if (glewInit() != GLEW_OK) {
|
||||
std::cout << "Failed to initialize GLEW\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the viewport size to match the framebuffer dimensions
|
||||
int width, height;
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
// Create framebuffer.
|
||||
glGenFramebuffers(1, &framebuffer);
|
||||
ResizeFramebuffer(fbWidth, fbHeight);
|
||||
|
||||
// Setup cube geometry and shaders.
|
||||
if (!SetupScene()) {
|
||||
std::cout << "Failed to set up scene\n";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Engine::BeginFrame() {
|
||||
// Clear the screen with a chosen color
|
||||
glClearColor(0.0f, 0.2f, 0.4f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void Engine::EndFrame() {
|
||||
// Swap the front and back buffers and process events
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
GLFWwindow* Engine::GetWindow() {
|
||||
return window;
|
||||
}
|
||||
|
||||
void Engine::ResizeFramebuffer(int width, int height) {
|
||||
fbWidth = width;
|
||||
fbHeight = height;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
|
||||
// Delete old attachments if they exist.
|
||||
if (colorTexture) {
|
||||
glDeleteTextures(1, &colorTexture);
|
||||
}
|
||||
if (depthRenderbuffer) {
|
||||
glDeleteRenderbuffers(1, &depthRenderbuffer);
|
||||
}
|
||||
|
||||
// Create color texture using GL_RGBA.
|
||||
glGenTextures(1, &colorTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, colorTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fbWidth, fbHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
|
||||
|
||||
// Create depth renderbuffer.
|
||||
glGenRenderbuffers(1, &depthRenderbuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, fbWidth, fbHeight);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
std::cout << "Framebuffer is not complete! Status: " << status << std::endl;
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
GLuint Engine::CompileShader(const char* vertexSrc, const char* fragmentSrc) {
|
||||
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertexShader, 1, &vertexSrc, nullptr);
|
||||
glCompileShader(vertexShader);
|
||||
int success;
|
||||
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
|
||||
if (!success) {
|
||||
char infoLog[512];
|
||||
glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
|
||||
std::cout << "Vertex shader compilation failed: " << infoLog << std::endl;
|
||||
return 0;
|
||||
}
|
||||
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragmentShader, 1, &fragmentSrc, nullptr);
|
||||
glCompileShader(fragmentShader);
|
||||
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
|
||||
if (!success) {
|
||||
char infoLog[512];
|
||||
glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog);
|
||||
std::cout << "Fragment shader compilation failed: " << infoLog << std::endl;
|
||||
return 0;
|
||||
}
|
||||
GLuint program = glCreateProgram();
|
||||
glAttachShader(program, vertexShader);
|
||||
glAttachShader(program, fragmentShader);
|
||||
glLinkProgram(program);
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &success);
|
||||
if (!success) {
|
||||
char infoLog[512];
|
||||
glGetProgramInfoLog(program, 512, nullptr, infoLog);
|
||||
std::cout << "Shader program linking failed: " << infoLog << std::endl;
|
||||
return 0;
|
||||
}
|
||||
glDeleteShader(vertexShader);
|
||||
glDeleteShader(fragmentShader);
|
||||
return program;
|
||||
}
|
||||
|
||||
bool Engine::SetupScene() {
|
||||
// Cube vertices: positions and normals.
|
||||
float vertices[] = {
|
||||
// positions // normals
|
||||
// Front face
|
||||
-0.5f, -0.5f, 0.5f, 0, 0, 1,
|
||||
0.5f, -0.5f, 0.5f, 0, 0, 1,
|
||||
0.5f, 0.5f, 0.5f, 0, 0, 1,
|
||||
0.5f, 0.5f, 0.5f, 0, 0, 1,
|
||||
-0.5f, 0.5f, 0.5f, 0, 0, 1,
|
||||
-0.5f, -0.5f, 0.5f, 0, 0, 1,
|
||||
|
||||
// Back face
|
||||
-0.5f, -0.5f, -0.5f, 0, 0, -1,
|
||||
0.5f, -0.5f, -0.5f, 0, 0, -1,
|
||||
0.5f, 0.5f, -0.5f, 0, 0, -1,
|
||||
0.5f, 0.5f, -0.5f, 0, 0, -1,
|
||||
-0.5f, 0.5f, -0.5f, 0, 0, -1,
|
||||
-0.5f, -0.5f, -0.5f, 0, 0, -1,
|
||||
|
||||
// Left face
|
||||
-0.5f, 0.5f, 0.5f, -1, 0, 0,
|
||||
-0.5f, 0.5f, -0.5f, -1, 0, 0,
|
||||
-0.5f, -0.5f, -0.5f, -1, 0, 0,
|
||||
-0.5f, -0.5f, -0.5f, -1, 0, 0,
|
||||
-0.5f, -0.5f, 0.5f, -1, 0, 0,
|
||||
-0.5f, 0.5f, 0.5f, -1, 0, 0,
|
||||
|
||||
// Right face
|
||||
0.5f, 0.5f, 0.5f, 1, 0, 0,
|
||||
0.5f, 0.5f, -0.5f, 1, 0, 0,
|
||||
0.5f, -0.5f, -0.5f, 1, 0, 0,
|
||||
0.5f, -0.5f, -0.5f, 1, 0, 0,
|
||||
0.5f, -0.5f, 0.5f, 1, 0, 0,
|
||||
0.5f, 0.5f, 0.5f, 1, 0, 0,
|
||||
|
||||
// Top face
|
||||
-0.5f, 0.5f, -0.5f, 0, 1, 0,
|
||||
0.5f, 0.5f, -0.5f, 0, 1, 0,
|
||||
0.5f, 0.5f, 0.5f, 0, 1, 0,
|
||||
0.5f, 0.5f, 0.5f, 0, 1, 0,
|
||||
-0.5f, 0.5f, 0.5f, 0, 1, 0,
|
||||
-0.5f, 0.5f, -0.5f, 0, 1, 0,
|
||||
|
||||
// Bottom face
|
||||
-0.5f, -0.5f, -0.5f, 0, -1, 0,
|
||||
0.5f, -0.5f, -0.5f, 0, -1, 0,
|
||||
0.5f, -0.5f, 0.5f, 0, -1, 0,
|
||||
0.5f, -0.5f, 0.5f, 0, -1, 0,
|
||||
-0.5f, -0.5f, 0.5f, 0, -1, 0,
|
||||
-0.5f, -0.5f, -0.5f, 0, -1, 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, 6 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
// Normal attribute.
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
glBindVertexArray(0);
|
||||
|
||||
// Vertex shader source.
|
||||
const char* vertexShaderSrc = R"(
|
||||
#version 330 core
|
||||
layout(location = 0) in vec3 aPos;
|
||||
layout(location = 1) in vec3 aNormal;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
out vec3 FragPos;
|
||||
out vec3 Normal;
|
||||
|
||||
void main() {
|
||||
FragPos = vec3(model * vec4(aPos, 1.0));
|
||||
Normal = mat3(transpose(inverse(model))) * aNormal;
|
||||
gl_Position = projection * view * vec4(FragPos, 1.0);
|
||||
}
|
||||
)";
|
||||
|
||||
// Fragment shader source with red light.
|
||||
const char* fragmentShaderSrc = R"(
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec3 FragPos;
|
||||
in vec3 Normal;
|
||||
|
||||
uniform vec3 lightPos;
|
||||
uniform vec3 viewPos;
|
||||
|
||||
void main() {
|
||||
// Ambient.
|
||||
float ambientStrength = 0.2;
|
||||
vec3 ambient = ambientStrength * vec3(1.0, 0.0, 0.0);
|
||||
|
||||
// Diffuse.
|
||||
vec3 norm = normalize(Normal);
|
||||
vec3 lightDir = normalize(lightPos - FragPos);
|
||||
float diff = max(dot(norm, lightDir), 0.0);
|
||||
vec3 diffuse = diff * vec3(1.0, 0.0, 0.0);
|
||||
|
||||
// Specular.
|
||||
float specularStrength = 0.5;
|
||||
vec3 viewDir = normalize(viewPos - FragPos);
|
||||
vec3 reflectDir = reflect(-lightDir, norm);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
|
||||
vec3 specular = specularStrength * spec * vec3(1.0);
|
||||
|
||||
vec3 result = ambient + diffuse + specular;
|
||||
FragColor = vec4(result, 1.0);
|
||||
}
|
||||
)";
|
||||
|
||||
shaderProgram = CompileShader(vertexShaderSrc, fragmentShaderSrc);
|
||||
if (shaderProgram == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ImTextureID Engine::RenderScene(const glm::mat4 &view, const glm::mat4 &projection, const glm::vec3 &viewPos) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
glViewport(0, 0, fbWidth, fbHeight);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glUseProgram(shaderProgram);
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "view"), 1, GL_FALSE, glm::value_ptr(view));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
|
||||
glUniform3f(glGetUniformLocation(shaderProgram, "viewPos"), viewPos.x, viewPos.y, viewPos.z);
|
||||
|
||||
rotationAngle += 0.01f;
|
||||
glm::mat4 model = glm::rotate(glm::mat4(1.0f), rotationAngle, glm::vec3(1,1,1));
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(model));
|
||||
|
||||
glUniform3f(glGetUniformLocation(shaderProgram, "lightPos"), 0.0f, 20.0f, 0.0f);
|
||||
|
||||
glBindVertexArray(cubeVAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||
glBindVertexArray(0);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
return (ImTextureID)(intptr_t)colorTexture;
|
||||
}
|
||||
|
||||
ImTextureID Engine::GetFinalRenderingTexture() {
|
||||
return (ImTextureID)(intptr_t)colorTexture;
|
||||
}
|
||||
|
||||
void Engine::Shutdown() {
|
||||
glDeleteVertexArrays(1, &cubeVAO);
|
||||
glDeleteBuffers(1, &cubeVBO);
|
||||
glDeleteProgram(shaderProgram);
|
||||
glDeleteFramebuffers(1, &framebuffer);
|
||||
glDeleteTextures(1, &colorTexture);
|
||||
glDeleteRenderbuffers(1, &depthRenderbuffer);
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
}
|
||||
|
4
Makefile
4
Makefile
@ -1,12 +1,12 @@
|
||||
# Compiler and flags
|
||||
CXX := g++
|
||||
CXXFLAGS := -std=c++20 -Wall -Wextra -O2 -I/c/msys64/mingw64/include -Ivendor
|
||||
CXXFLAGS := -std=c++20 -Wall -Wextra -O2 -I/c/msys64/mingw64/include -Ivendor/imgui-docking
|
||||
|
||||
# Use this to link against the correct import lib
|
||||
LDFLAGS := -Llib -lglfw3 -lopengl32 -lglew32 -lglu32
|
||||
|
||||
# Source and build directories (including vendor folder)
|
||||
SRC_DIRS := . Editor Engine vendor
|
||||
SRC_DIRS := . Editor Engine vendor/imgui-docking
|
||||
BUILD_DIR := build
|
||||
|
||||
# Find all source files
|
||||
|
BIN
Three-Labs.exe
BIN
Three-Labs.exe
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/vendor/imgui-docking/imgui.o
vendored
Normal file
BIN
build/vendor/imgui-docking/imgui.o
vendored
Normal file
Binary file not shown.
BIN
build/vendor/imgui-docking/imgui_demo.o
vendored
Normal file
BIN
build/vendor/imgui-docking/imgui_demo.o
vendored
Normal file
Binary file not shown.
BIN
build/vendor/imgui-docking/imgui_draw.o
vendored
Normal file
BIN
build/vendor/imgui-docking/imgui_draw.o
vendored
Normal file
Binary file not shown.
BIN
build/vendor/imgui-docking/imgui_impl_glfw.o
vendored
Normal file
BIN
build/vendor/imgui-docking/imgui_impl_glfw.o
vendored
Normal file
Binary file not shown.
BIN
build/vendor/imgui-docking/imgui_impl_opengl3.o
vendored
Normal file
BIN
build/vendor/imgui-docking/imgui_impl_opengl3.o
vendored
Normal file
Binary file not shown.
BIN
build/vendor/imgui-docking/imgui_tables.o
vendored
Normal file
BIN
build/vendor/imgui-docking/imgui_tables.o
vendored
Normal file
Binary file not shown.
BIN
build/vendor/imgui-docking/imgui_widgets.o
vendored
Normal file
BIN
build/vendor/imgui-docking/imgui_widgets.o
vendored
Normal file
Binary file not shown.
31
imgui.ini
Normal file
31
imgui.ini
Normal file
@ -0,0 +1,31 @@
|
||||
[Window][WindowOverViewport_11111111]
|
||||
Pos=0,0
|
||||
Size=1280,800
|
||||
Collapsed=0
|
||||
|
||||
[Window][Debug##Default]
|
||||
Pos=60,60
|
||||
Size=400,400
|
||||
Collapsed=0
|
||||
|
||||
[Window][Editor Panel]
|
||||
Pos=0,0
|
||||
Size=334,800
|
||||
Collapsed=0
|
||||
DockId=0x00000001,0
|
||||
|
||||
[Window][Rendered Output]
|
||||
Pos=337,0
|
||||
Size=943,800
|
||||
Collapsed=0
|
||||
|
||||
[Window][Editor]
|
||||
Pos=176,231
|
||||
Size=680,444
|
||||
Collapsed=0
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,0 Size=1280,800 Split=X Selected=0x5098C5B2
|
||||
DockNode ID=0x00000001 Parent=0x08BD597D SizeRef=334,800 Selected=0x5098C5B2
|
||||
DockNode ID=0x00000002 Parent=0x08BD597D SizeRef=944,800 CentralNode=1
|
||||
|
54
vendor/imgui-docking/imgui_impl_win32.h
vendored
Normal file
54
vendor/imgui-docking/imgui_impl_win32.h
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
// dear imgui: Platform Backend for Windows (standard windows API for 32-bits AND 64-bits applications)
|
||||
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd);
|
||||
IMGUI_IMPL_API bool ImGui_ImplWin32_InitForOpenGL(void* hwnd);
|
||||
IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame();
|
||||
|
||||
// Win32 message handler your application need to call.
|
||||
// - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on <windows.h> from this helper.
|
||||
// - You should COPY the line below into your .cpp code to forward declare the function and then you can call it.
|
||||
// - Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
|
||||
|
||||
#if 0
|
||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
#endif
|
||||
|
||||
// DPI-related helpers (optional)
|
||||
// - Use to enable DPI awareness without having to create an application manifest.
|
||||
// - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps.
|
||||
// - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc.
|
||||
// but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime,
|
||||
// neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies.
|
||||
IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness();
|
||||
IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd
|
||||
IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor
|
||||
|
||||
// Transparency related helpers (optional) [experimental]
|
||||
// - Use to enable alpha compositing transparency with the desktop.
|
||||
// - Use together with e.g. clearing your framebuffer with zero-alpha.
|
||||
IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
Loading…
Reference in New Issue
Block a user