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 "../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()
|
EditorCamera editorCamera;
|
||||||
{
|
|
||||||
// Initialize the engine (GLFW window + OpenGL)
|
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())
|
if (!Engine::Init())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
//// Setup Dear ImGui context
|
// Setup ImGui.
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable docking
|
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||||
|
|
||||||
// Set the style for ImGui
|
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
|
|
||||||
// Specify the GLSL version and initialize backends
|
|
||||||
const char* glsl_version = "#version 330";
|
const char* glsl_version = "#version 330";
|
||||||
ImGui_ImplGlfw_InitForOpenGL(Engine::GetWindow(), true);
|
ImGui_ImplGlfw_InitForOpenGL(Engine::GetWindow(), true);
|
||||||
ImGui_ImplOpenGL3_Init(glsl_version);
|
ImGui_ImplOpenGL3_Init(glsl_version);
|
||||||
|
|
||||||
// Main loop
|
float lastFrameTime = (float)glfwGetTime();
|
||||||
while (!glfwWindowShouldClose(Engine::GetWindow()))
|
|
||||||
{
|
|
||||||
Engine::BeginFrame();
|
|
||||||
|
|
||||||
//// 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_ImplOpenGL3_NewFrame();
|
||||||
ImGui_ImplGlfw_NewFrame();
|
ImGui_ImplGlfw_NewFrame();
|
||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
|
|
||||||
// Create a full-viewport docking space
|
// Create a full-viewport dock space.
|
||||||
ImGui::DockSpaceOverViewport();
|
ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode);
|
||||||
|
|
||||||
// Create an editor window
|
|
||||||
|
// Create an "Editor Panel" window.
|
||||||
ImGui::Begin("Editor Panel");
|
ImGui::Begin("Editor Panel");
|
||||||
ImGui::Text("Welcome to the Editor!");
|
ImGui::Text("Welcome to the Editor!");
|
||||||
// Additional UI elements can be added here
|
// (Additional UI elements can go here.)
|
||||||
ImGui::End();
|
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::Render();
|
||||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||||
|
|
||||||
Engine::EndFrame();
|
glfwSwapBuffers(Engine::GetWindow());
|
||||||
|
glfwPollEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup ImGui and terminate GLFW
|
|
||||||
ImGui_ImplOpenGL3_Shutdown();
|
ImGui_ImplOpenGL3_Shutdown();
|
||||||
ImGui_ImplGlfw_Shutdown();
|
ImGui_ImplGlfw_Shutdown();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
glfwTerminate();
|
Engine::Shutdown();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,33 +1,66 @@
|
|||||||
#pragma once
|
#ifndef ENGINE_H
|
||||||
|
#define ENGINE_H
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <GL/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
#include "imgui.h"
|
||||||
#include <GL/gl.h>
|
#include "imgui_impl_opengl3.h"
|
||||||
#include "../vendor/imgui-docking/imgui.h"
|
#include "imgui_impl_glfw.h"
|
||||||
#include "../vendor/imgui-docking/imgui_impl_glfw.h"
|
#include <glm/glm.hpp>
|
||||||
#include "../vendor/imgui-docking/imgui_impl_opengl3_loader.h"
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
#include "../vendor/imgui-docking/imgui_impl_opengl3.h"
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Engine {
|
class Engine {
|
||||||
public:
|
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();
|
static bool Init();
|
||||||
|
|
||||||
// Clears the screen.
|
// Returns the main GLFW window.
|
||||||
static void BeginFrame();
|
|
||||||
|
|
||||||
// Swaps buffers and polls for events.
|
|
||||||
static void EndFrame();
|
|
||||||
|
|
||||||
// Returns the pointer to the GLFW window.
|
|
||||||
static GLFWwindow* GetWindow();
|
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:
|
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 "Engine.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
// Static member definitions.
|
||||||
GLFWwindow* Engine::window = nullptr;
|
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() {
|
bool Engine::Init() {
|
||||||
if (!glfwInit()) {
|
if (!glfwInit()) {
|
||||||
std::cout << "Failed to initialize GLFW\n";
|
std::cout << "Failed to initialize GLFW\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specify the OpenGL version (e.g., 3.3 Core Profile)
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
|
||||||
// Create the GLFW window
|
|
||||||
window = glfwCreateWindow(1280, 800, "Engine Window", nullptr, nullptr);
|
window = glfwCreateWindow(1280, 800, "Engine Window", nullptr, nullptr);
|
||||||
if (!window) {
|
if (!window) {
|
||||||
std::cout << "Failed to create GLFW window\n";
|
std::cout << "Failed to create GLFW window\n";
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make the OpenGL context current
|
|
||||||
glfwMakeContextCurrent(window);
|
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;
|
int width, height;
|
||||||
glfwGetFramebufferSize(window, &width, &height);
|
glfwGetFramebufferSize(window, &width, &height);
|
||||||
glViewport(0, 0, 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;
|
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() {
|
GLFWwindow* Engine::GetWindow() {
|
||||||
return window;
|
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
|
# Compiler and flags
|
||||||
CXX := g++
|
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
|
# Use this to link against the correct import lib
|
||||||
LDFLAGS := -Llib -lglfw3 -lopengl32 -lglew32 -lglu32
|
LDFLAGS := -Llib -lglfw3 -lopengl32 -lglew32 -lglu32
|
||||||
|
|
||||||
# Source and build directories (including vendor folder)
|
# Source and build directories (including vendor folder)
|
||||||
SRC_DIRS := . Editor Engine vendor
|
SRC_DIRS := . Editor Engine vendor/imgui-docking
|
||||||
BUILD_DIR := build
|
BUILD_DIR := build
|
||||||
|
|
||||||
# Find all source files
|
# 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