From e14550ce6314a9a5aed3eefcfb8e3b663879ab18 Mon Sep 17 00:00:00 2001 From: PreacherDHM Date: Thu, 2 Jul 2026 21:59:55 -0700 Subject: [PATCH] first --- .gitignore | 21 +++++ CMakeLists.txt | 20 +++++ README.md | 2 + external/CMakeLists.txt | 3 + external/glad | 1 + external/glfw | 1 + source/CMakeLists.txt | 17 ++++ source/engin/shaders.c | 0 source/engin/shaders.h | 16 ++++ source/engin/window.c | 75 ++++++++++++++++++ source/engin/window.h | 44 +++++++++++ source/main.cpp | 170 ++++++++++++++++++++++++++++++++++++++++ 12 files changed, 370 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 README.md create mode 100644 external/CMakeLists.txt create mode 160000 external/glad create mode 160000 external/glfw create mode 100644 source/CMakeLists.txt create mode 100644 source/engin/shaders.c create mode 100644 source/engin/shaders.h create mode 100644 source/engin/window.c create mode 100644 source/engin/window.h create mode 100644 source/main.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4e0a981 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps +CMakeUserPresets.json + +build/ + +# CLion +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#cmake-build-* diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..cace62c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.30.0) + +project(openglProject VERSION 0.1) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_COLOR_MAKEFILE ON) +set(CMAKE_COLOR_DIAGNOSTICS ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +set(RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin") +set(LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib") +set(ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib") + +find_package(GLEW REQUIRED) +find_package(OpenGL REQUIRED) + +add_subdirectory(source) +add_subdirectory(external) diff --git a/README.md b/README.md new file mode 100644 index 0000000..77e8b12 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# openglProject +This is a test for opengl diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt new file mode 100644 index 0000000..2a5ee8d --- /dev/null +++ b/external/CMakeLists.txt @@ -0,0 +1,3 @@ +# ADD Externals HERE +add_subdirectory(glfw) + diff --git a/external/glad b/external/glad new file mode 160000 index 0000000..e3c14f9 --- /dev/null +++ b/external/glad @@ -0,0 +1 @@ +Subproject commit e3c14f906127dea49ead20ff4d5878294d08b7ab diff --git a/external/glfw b/external/glfw new file mode 160000 index 0000000..567b1ec --- /dev/null +++ b/external/glfw @@ -0,0 +1 @@ +Subproject commit 567b1ec2442d59525e24c19e8d413df6baf02496 diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt new file mode 100644 index 0000000..6f710e9 --- /dev/null +++ b/source/CMakeLists.txt @@ -0,0 +1,17 @@ +# ADD SOURCES HERE +set(SOURCE_FILES + main.cpp +) + +add_executable(${PROJECT_NAME} ${SOURCE_FILES}) + +target_link_libraries( + ${PROJECT_NAME} + PRIVATE + OpenGL::GL + GLEW::GLEW + glfw) +target_sources( + ${PROJECT_NAME} + main.cpp +) diff --git a/source/engin/shaders.c b/source/engin/shaders.c new file mode 100644 index 0000000..e69de29 diff --git a/source/engin/shaders.h b/source/engin/shaders.h new file mode 100644 index 0000000..22416cb --- /dev/null +++ b/source/engin/shaders.h @@ -0,0 +1,16 @@ +#ifndef SHADERS_H +#define SHADERS_H + + +typedef struct { + char* vertex; + int vertexSize; + char* fragment; + int fragmentSize; +} shader; + +int ReadFragmentShader(const char* path, shader* shader); +int ReadVertexShader(const char* path, shader* shader); + + +#endif diff --git a/source/engin/window.c b/source/engin/window.c new file mode 100644 index 0000000..4448e5a --- /dev/null +++ b/source/engin/window.c @@ -0,0 +1,75 @@ +#include "window.h" +#include "GLFW/glfw3.h" +#include + +int keyState[GLFW_KEY_LAST] = {0}; + +// Key name lookup table (optional, you can hardcode or load from a config) +const char* keyNames[GLFW_KEY_LAST] = { + "Escape", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", + "Backspace", "Tab", "Return", "Space", "Delete", "Insert", "Home", "End", "PageUp", "PageDown", + "Left", "Up", "Right", "Down", "PrintScreen", "Pause", "ScrollLock", "NumLock", "CapsLock", + "Shift", "Control", "Alt", "Super", "Enter", "Backspace", "Tab", "Space", + // Add more key names as needed + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", + // Add more if needed +}; +void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); + +int WindowCreate(window* w, window_config *config) { + glfwInit(); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_PROFILE); + glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); + + w->ctx = glfwCreateWindow(config->width, config->height, config->Name, 0, 0); + + glfwMakeContextCurrent(w->ctx); + + glfwSetKeyCallback(w->ctx, keyCallback); + + glewExperimental = GL_TRUE; + glewInit(); + glfwGetFramebufferSize(w->ctx, &w->width, &w->height); + + return 0; +} + +int WindowHandleInput(window* w) { + return 0; +} +int WindowEventHandler(window* w) { + return 0; +} + +static int keyNameToCode(const char* name) { + for (int i = 0; i < GLFW_KEY_LAST; ++i) { + if (strcmp(name, keyNames[i]) == 0) { + return i; + } + } + return -1; // invalid key +} + +// GetKey wrapper +int GetKey(const char* keyName) { + int keyCode = keyNameToCode(keyName); + if (keyCode == -1) { + return 0; // or you can handle error differently + } + return keyState[keyCode]; +} + +// GLFW key callback +void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) { + if (key >= 0 && key < GLFW_KEY_LAST) { + if (action == GLFW_PRESS) { + keyState[key] = 1; + } else if (action == GLFW_RELEASE) { + keyState[key] = 0; + } + } +} + diff --git a/source/engin/window.h b/source/engin/window.h new file mode 100644 index 0000000..f23d085 --- /dev/null +++ b/source/engin/window.h @@ -0,0 +1,44 @@ +#ifndef WINDOW_H +#define WINDOW_H + +typedef int(*window_evnet_cb)(int argc, void* argv); + +typedef struct { + const char* Log; + window_evnet_cb callback; + + +}window_event; + +#ifdef _GLFW_WAYLAND +#define GLEW_STATIC +#include +#include + typedef GLFWwindow context; +#else +// If not using GLFW +#endif + +typedef struct { + const char* Name; + const char* Description; + int width; + int height; + window_event windowClosedEvent; + window_event windowOpenEvent; + window_event windowKeyEvent; +}window_config; + +typedef struct { + const char* Name; + const char* Description; + int width; + int height; + context* ctx; +}window; + +int WindowCreate(window* w,window_config* config); +int WindowHandleInput(window* w); +int WindowEventHandler(window* w); +int GetKeyDown(const char* keyName); +#endif diff --git a/source/main.cpp b/source/main.cpp new file mode 100644 index 0000000..a02fffc --- /dev/null +++ b/source/main.cpp @@ -0,0 +1,170 @@ +/* ############################################################################# + * # openglProject + * This is a test for opengl + * + * AUTHER: Preacherdhm + * DATE: 22/06/26 + * ############################################################################# + */ +#include + +// GLEW +#define GLEW_STATIC +#include + +// GLFW +#include + + +// Function prototypes +void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode); + +// Window dimensions +const GLuint WIDTH = 800, HEIGHT = 600; + +// Shaders +const GLchar* vertexShaderSource = "#version 330 core\n" + "layout (location = 0) in vec3 position;\n" + "void main()\n" + "{\n" + "gl_Position = vec4(position.x, position.y, position.z, 1.0);\n" + "}\0"; +const GLchar* fragmentShaderSource = "#version 330 core\n" + "out vec4 color;\n" + "void main()\n" + "{\n" + "color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n" + "}\n\0"; + +// The MAIN function, from here we start the application and run the game loop +int main() +{ + // Init GLFW + glfwInit(); + // Set all the required options for GLFW + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); + + // Create a GLFWwindow object that we can use for GLFW's functions + GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); + glfwMakeContextCurrent(window); + + // Set the required callback functions + glfwSetKeyCallback(window, key_callback); + + // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions + glewExperimental = GL_TRUE; + // Initialize GLEW to setup the OpenGL Function pointers + glewInit(); + + // Define the viewport dimensions + int width, height; + glfwGetFramebufferSize(window, &width, &height); + glViewport(0, 0, width, height); + + + // Build and compile our shader program + // Vertex shader + GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); + glCompileShader(vertexShader); + // Check for compile time errors + GLint success; + GLchar infoLog[512]; + glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; + } + // Fragment shader + GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); + glCompileShader(fragmentShader); + // Check for compile time errors + glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); + if (!success) + { + glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; + } + // Link shaders + GLuint shaderProgram = glCreateProgram(); + glAttachShader(shaderProgram, vertexShader); + glAttachShader(shaderProgram, fragmentShader); + glLinkProgram(shaderProgram); + // Check for linking errors + glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); + if (!success) { + glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); + std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; + } + glDeleteShader(vertexShader); + glDeleteShader(fragmentShader); + + + // Set up vertex data (and buffer(s)) and attribute pointers + // We add a new set of vertices to form a second triangle (a total of 6 vertices); the vertex attribute configuration remains the same (still one 3-float position vector per vertex) + GLfloat vertices[] = { + // First triangle + 0.9f, 0.5f, 0.0f, // Left + 0.0f, 0.5f, 0.0f, // Right + 0.9f, -0.5f, 0.0f, // Top + // Second triangle + 0.0f, -0.5f, 0.0f, // Left + 0.9f, -0.5f, 0.0f, // Right + 0.00f, 0.5f, 0.0f // Top + }; + GLuint VBO, VAO; + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &VBO); + // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s). + glBindVertexArray(VAO); + + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0); + glEnableVertexAttribArray(0); + + glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind + + glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs) + + // Game loop + while (!glfwWindowShouldClose(window)) + { + // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions + glfwPollEvents(); + + // Render + // Clear the colorbuffer + glClearColor(0.2f, 0.3f, 0.3f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + // Draw our first triangle + glUseProgram(shaderProgram); + glBindVertexArray(VAO); + glDrawArrays(GL_TRIANGLES, 0, 6); // We set the count to 6 since we're drawing 6 vertices now (2 triangles); not 3! + glBindVertexArray(0); + + // Swap the screen buffers + glfwSwapBuffers(window); + } + // Properly de-allocate all resources once they've outlived their purpose + glDeleteVertexArrays(1, &VAO); + glDeleteBuffers(1, &VBO); + // Terminate GLFW, clearing any resources allocated by GLFW. + glfwTerminate(); + return 0; +} + +// Is called whenever a key is pressed/released via GLFW +void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) +{ + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + glfwSetWindowShouldClose(window, GL_TRUE); +} +