diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e41428..9688a55 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,37 +5,67 @@ project(fred) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # For my Clangd LSP # endif() -set(GLFW_BUILD_WAYLAND OFF) # This should be detected and not forced +set(GLFW_BUILD_WAYLAND OFF) # This should be detected and not forced +set(BUILD_SHARED_LIBS OFF) # Keep the project as one binary (glew, glm) +set(GLM__BUILD_TESTS OFF) # Don't build GLM tests +set(GLFW_BUILD_EXAMPLES OFF) # Don't build GLFW Examples +set(GLFW_BUILD_TESTS OFF) # Don't build GLFW Tests +set(GLFW_INSTALL OFF) # We're not building a standalone +# set(GLEW_BUILD_DOCS $) # Build docs if debug +set(SOIL2_BUILD_TESTS OFF) # Don't build SOIL2 Tests + find_package(OpenGL REQUIRED) if(CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR) - message(FATAL_ERROR "You fucking smell fr") + message(FATAL_ERROR "You fucking smell fr\n") endif() if(CMAKE_SOURCE_DIR MATCHES " ") - message("Spaces in the source dir can cause errors, thou art been warned") + message(WARNING "Spaces in the source dir can cause errors, thou art been warned\n") endif() -if(CMAKE_BIANRY_DIR MATCHES " ") - message("Spaces in the build dir can cause errors, thou art been warned") +if(CMAKE_BINARY_DIR MATCHES " ") + message(WARNING "Spaces in the build dir can cause errors, thou art been warned\n") endif() -if(LINUX) +if(UNIX) + message(STATUS "Configuring GLEW for *nix (Non-cmake)\n") add_custom_command( OUTPUT ${PROJECT_SOURCE_DIR}/include/glew/src/glew.c ${PROJECT_SOURCE_DIR}/include/glewinfo.c WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/include/glew/auto COMMAND ${CMAKE_MAKE_PROGRAM}) + + add_subdirectory(include/glew/build/cmake) + + if(NOT (EXISTS "${PROJECT_SOURCE_DIR}/include/glew/src/glew.c" AND EXISTS "${PROJECT_SOURCE_DIR}/include/glewinfo.c")) + message(FATAL_ERROR "GLEW failed to configure!") + endif() endif() if(WIN32) - add_custom_command( - OUTPUT ${PROJECT_SOURCE_DIR}/include (glew) /src/glew.c - ${PROJECT_SOURCE_DIR}/include/glewinfo.c - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/include/glew/build/vc15 - COMMAND ${CMAKE_VS_MSBUILD_COMMAND}) + message(STATUS "Download GLEW for Windows (Non-cmake)\n") # I wanted to make this work from source, but the auto config is make only, and requiring and/or shipping msys2 would be unreasonable so this is the best compromise + file(DOWNLOAD https://github.com/nigels-com/glew/releases/download/glew-2.2.0/glew-2.2.0-win32.zip ${CMAKE_BINARY_DIR}/glew-2.2.0.zip) + execute_process(COMMAND tar -xf ${CMAKE_BINARY_DIR}/glew-2.2.0.zip # bdstar + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + + if(NOT EXISTS ${CMAKE_BINARY_DIR}/glew-2.2.0/include/GL/glew.h) + message(FATAL_ERROR "GLEW Failed to download/decompress") + endif() + + include_directories(${CMAKE_BINARY_DIR}/glew-2.2.0/include) + add_library(glew STATIC # There aren't actually any binaries in here, so no lib is to be built + ${CMAKE_BINARY_DIR}/glew-2.2.0/include/GL/eglew.h + ${CMAKE_BINARY_DIR}/glew-2.2.0/include/GL/glew.h + ${CMAKE_BINARY_DIR}/glew-2.2.0/include/GL/glxew.h + ${CMAKE_BINARY_DIR}/glew-2.2.0/include/GL/wglew.h) + set_target_properties(glew PROPERTIES LINKER_LANGUAGE C) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit + target_link_libraries(glew ${CMAKE_BINARY_DIR}/glew-2.2.0/lib/Release/x64/glew32.lib ${CMAKE_BINARY_DIR}/glew-2.2.0/lib/Release/x64/glew32s.lib) + elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) # 32-bit, if it's not either of these you're in trouble + target_link_libraries(glew ${CMAKE_BINARY_DIR}/glew-2.2.0/lib/Release/Win32/glew32.lib ${CMAKE_BINARY_DIR}/glew-2.2.0/lib/Release/Win32/glew32s.lib) + endif() endif() add_subdirectory(include/glm) -add_subdirectory(include/glew/build/cmake) add_subdirectory(include/glfw) add_subdirectory(include/SOIL2) add_subdirectory(include/assimp) @@ -43,7 +73,7 @@ add_subdirectory(include/CLog) include_directories(include/imgui) add_library( - imgui + imgui STATIC include/imgui/imgui.cpp include/imgui/imgui_demo.cpp include/imgui/imgui_draw.cpp @@ -54,13 +84,26 @@ add_library( target_link_libraries(imgui glfw) add_executable(fred engine.cpp shader.c) +if (UNIX) target_link_libraries( fred -lm - glm glew + glm glfw soil2 assimp imgui clog) + endif() + if (WIN32) + target_link_libraries( + fred + glew + glm + glfw + soil2 + assimp + imgui + clog) + endif() \ No newline at end of file diff --git a/engine.cpp b/engine.cpp index 12d2bf7..e7b82b3 100644 --- a/engine.cpp +++ b/engine.cpp @@ -21,18 +21,16 @@ #include #include -extern "C" { #include "shader.h" -} -#define WIDTH 1024 -#define HEIGHT 768 +constexpr int WIDTH = 1024; +constexpr int HEIGHT = 768; static void glfwErrorCallback(int e, const char *description) { clog_log(CLOG_LEVEL_ERROR, "GLFW Error %d: %s", e, description); } -bool loadModel(const char *path, std::vector &indices, +static bool loadModel(const char *path, std::vector &indices, std::vector &vertices, std::vector &uvs, std::vector &normals) { Assimp::Importer importer; @@ -68,7 +66,7 @@ bool loadModel(const char *path, std::vector &indices, return true; } -int initWindow() { +static int initWindow() { glfwSetErrorCallback(glfwErrorCallback); glewExperimental = true; @@ -317,7 +315,7 @@ int initWindow() { // Index buffer glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer); - glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, (void *)0); + glDrawElements(GL_TRIANGLES, (GLsizei)indices.size(), GL_UNSIGNED_SHORT, (void *)0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); diff --git a/shader.c b/shader.c index 5f23c22..656f9da 100644 --- a/shader.c +++ b/shader.c @@ -18,30 +18,31 @@ GLuint loadShaders(const char *vertex_file_path, GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER); GLuint fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); + errno_t err; + FILE *vertexShaderFD; - vertexShaderFD = fopen(vertex_file_path, "rb"); - if (vertexShaderFD == NULL) { - fclose(vertexShaderFD); - clog_log(CLOG_LEVEL_ERROR, "Failed to open Vertex Shader"); - return 1; + if (err = fopen_s(&vertexShaderFD, vertex_file_path, "rb")) { + clog_log(CLOG_LEVEL_ERROR, "Failed to open Vertex Shader \"%s\": %s", vertex_file_path, err); + return 0; } int vertexShaderLength = lseek(fileno(vertexShaderFD), 0L, SEEK_END) + 1; fseek(vertexShaderFD, 0L, SEEK_SET); char *vertexShaderCode = (char *)calloc(vertexShaderLength, sizeof(char)); + clog_assert(vertexShaderCode != NULL); + clog_assert(7 != 7); fread(vertexShaderCode, sizeof(*vertexShaderCode), vertexShaderLength, vertexShaderFD); fclose(vertexShaderFD); FILE *fragmentShaderFD; - fragmentShaderFD = fopen(fragment_file_path, "rb"); - if (fragmentShaderFD == NULL) { - fclose(fragmentShaderFD); - clog_log(CLOG_LEVEL_ERROR, "Failed to open Fragment Shader"); - return 1; + if (fopen_s(&fragmentShaderFD, fragment_file_path, "rb")) { + clog_log(CLOG_LEVEL_ERROR, "Failed to open Vertex Shader \"%s\": %s", fragment_file_path, err); + return 0; } int fragmentShaderLength = lseek(fileno(fragmentShaderFD), 0L, SEEK_END) + 1; fseek(fragmentShaderFD, 0L, SEEK_SET); char *fragmentShaderCode = (char *)calloc(fragmentShaderLength, sizeof(char)); + clog_assert(fragmentShaderCode != NULL); fread(fragmentShaderCode, sizeof(*fragmentShaderCode), fragmentShaderLength, fragmentShaderFD); fclose(fragmentShaderFD); @@ -57,10 +58,12 @@ GLuint loadShaders(const char *vertex_file_path, glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &result); glGetShaderiv(vertexShaderID, GL_INFO_LOG_LENGTH, &infoLogLength); if (infoLogLength > 0) { - char *vertexShaderErrorMessage[infoLogLength + 1]; - glGetShaderInfoLog(vertexShaderID, infoLogLength, NULL, - *vertexShaderErrorMessage); - clog_log(CLOG_LEVEL_ERROR, "%s", *vertexShaderErrorMessage); + infoLogLength += 1; // Prevents a sub-expression overflow false positive + char *vertexShaderErrorMessage = (char*)malloc(infoLogLength * sizeof(char)); // Not all compilers support VLAs, this will do + glGetShaderInfoLog(vertexShaderID, infoLogLength-1, NULL, + vertexShaderErrorMessage); + clog_log(CLOG_LEVEL_ERROR, "%s", vertexShaderErrorMessage); + free(vertexShaderErrorMessage); } clog_log(CLOG_LEVEL_DEBUG, "Compiling shader: %s", fragment_file_path); @@ -71,10 +74,12 @@ GLuint loadShaders(const char *vertex_file_path, glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &result); glGetShaderiv(fragmentShaderID, GL_INFO_LOG_LENGTH, &infoLogLength); if (infoLogLength > 0) { - char *fragmentShaderErrorMessage[infoLogLength + 1]; - glGetShaderInfoLog(fragmentShaderID, infoLogLength, NULL, - *fragmentShaderErrorMessage); - clog_log(CLOG_LEVEL_ERROR, "%s", *fragmentShaderErrorMessage); + infoLogLength += 1; // Prevents a sub-expression overflow false positive + char *fragmentShaderErrorMessage = (char*)malloc(infoLogLength * sizeof(char)); + glGetShaderInfoLog(fragmentShaderID, infoLogLength - 1, NULL, + fragmentShaderErrorMessage); + clog_log(CLOG_LEVEL_ERROR, "%s", fragmentShaderErrorMessage); + free(fragmentShaderErrorMessage); } clog_log(CLOG_LEVEL_DEBUG, "Linking shader program"); @@ -86,9 +91,11 @@ GLuint loadShaders(const char *vertex_file_path, glGetProgramiv(programID, GL_COMPILE_STATUS, &result); glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &infoLogLength); if (infoLogLength > 0) { - char *programErrorMessage[infoLogLength + 1]; - glGetProgramInfoLog(programID, infoLogLength, NULL, *programErrorMessage); - clog_log(CLOG_LEVEL_ERROR, "%s", *programErrorMessage); + infoLogLength += 1; // Prevents a sub-expression overflow false positive + char *programErrorMessage = (char*)malloc(infoLogLength * sizeof(char));; + glGetProgramInfoLog(programID, infoLogLength - 1, NULL, programErrorMessage); + clog_log(CLOG_LEVEL_ERROR, "%s", programErrorMessage); + free(programErrorMessage); } glDetachShader(programID, vertexShaderID); diff --git a/shader.h b/shader.h index 6bfecb9..11e9125 100644 --- a/shader.h +++ b/shader.h @@ -3,9 +3,13 @@ #include #include -#include - -GLuint loadShaders(const char *vertex_file_path, - const char *fragment_file_path); +#ifdef __cplusplus +extern "C" { +#endif + GLuint loadShaders(const char* vertex_file_path, + const char* fragment_file_path); +#ifdef __cplusplus +} +#endif #endif