Uhhhhhhhhhhhhh

This commit is contained in:
illegitimate-egg 2024-10-18 00:57:50 +01:00
parent f77dc55a68
commit 87352034fd
6 changed files with 149 additions and 40 deletions

3
.gitmodules vendored
View File

@ -22,3 +22,6 @@
[submodule "extern/glad"] [submodule "extern/glad"]
path = extern/glad path = extern/glad
url = https://github.com/Dav1dde/glad.git url = https://github.com/Dav1dde/glad.git
[submodule "extern/ImGuizmo"]
path = extern/ImGuizmo
url = https://github.com/maritim/ImGuizmo.git

View File

@ -55,6 +55,17 @@ add_library(
extern/imgui/backends/imgui_impl_opengl3.cpp) extern/imgui/backends/imgui_impl_opengl3.cpp)
target_link_libraries(imgui glfw) target_link_libraries(imgui glfw)
include_directories(extern/ImGuizmo)
add_library(
imguizmo STATIC
extern/ImGuizmo/GraphEditor.cpp
extern/ImGuizmo/ImCurveEdit.cpp
extern/ImGuizmo/ImGradient.cpp
extern/ImGuizmo/ImGuizmo.cpp
extern/ImGuizmo/ImSequencer.cpp
)
target_link_libraries(imguizmo imgui)
add_executable(fred src/engine.cpp src/shader.c) add_executable(fred src/engine.cpp src/shader.c)
target_link_libraries(fred $<$<PLATFORM_ID:Linux>:-lm> glad_gl_core_33 glm glfw target_link_libraries(fred $<$<PLATFORM_ID:Linux>:-lm> glad_gl_core_33 glm glfw
soil2 assimp imgui clog) soil2 assimp imgui imguizmo clog)

2
extern/CLog vendored

@ -1 +1 @@
Subproject commit 78f58ffefc782c3bcc0bccaf7df38b064da6f170 Subproject commit 8fafc54518584db67f3e85dab29ba7afa5cdd284

1
extern/ImGuizmo vendored Submodule

@ -0,0 +1 @@
Subproject commit 315acb262ce7358a84bbce1b5d2684024035529d

View File

@ -1,6 +1,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <string>
#include <vector> #include <vector>
#include <glad/gl.h> #include <glad/gl.h>
@ -17,6 +18,7 @@
#include <backends/imgui_impl_opengl3.h> #include <backends/imgui_impl_opengl3.h>
#include <imgui.h> #include <imgui.h>
#include <imgui_internal.h> #include <imgui_internal.h>
#include <ImGuizmo.h>
#include <clog/clog.h> #include <clog/clog.h>
#include <SOIL2.h> #include <SOIL2.h>
@ -32,7 +34,7 @@ constexpr int WIDTH = 1366;
constexpr int HEIGHT = 768; constexpr int HEIGHT = 768;
static void glfwErrorCallback(int e, const char *description) { static void glfwErrorCallback(int e, const char *description) {
clog_log(CLOG_LEVEL_ERROR, "GLFW Error %d: %s", e, description); clog_log(CLOG_LEVEL_ERROR, "GLFW Error %d: %s\n", e, description);
} }
namespace fred { namespace fred {
@ -41,14 +43,14 @@ static bool loadModel(const char *path, std::vector<unsigned short> &indices,
std::vector<glm::vec3> &vertices, std::vector<glm::vec3> &vertices,
std::vector<glm::vec2> &uvs, std::vector<glm::vec2> &uvs,
std::vector<glm::vec3> &normals) { std::vector<glm::vec3> &normals) {
clog_log(CLOG_LEVEL_DEBUG, "Loading model: %s", path); clog_log(CLOG_LEVEL_DEBUG, "Loading model: %s\n", path);
Assimp::Importer importer; Assimp::Importer importer;
const aiScene *scene = importer.ReadFile( const aiScene *scene = importer.ReadFile(
path, aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | path, aiProcess_Triangulate | aiProcess_JoinIdenticalVertices |
aiProcess_SortByPType); aiProcess_SortByPType);
if (!scene) { if (!scene) {
clog_log(CLOG_LEVEL_ERROR, "%s", importer.GetErrorString()); clog_log(CLOG_LEVEL_ERROR, "%s\n", importer.GetErrorString());
return false; return false;
} }
const aiMesh *mesh = scene->mMeshes[0]; const aiMesh *mesh = scene->mMeshes[0];
@ -80,13 +82,13 @@ static bool loadModel(const char *path, std::vector<unsigned short> &indices,
} }
GLuint loadTexture(const char *path) { GLuint loadTexture(const char *path) {
clog_log(CLOG_LEVEL_DEBUG, "Loading texture: %s", path); clog_log(CLOG_LEVEL_DEBUG, "Loading texture: %s\n", path);
GLuint texture = SOIL_load_OGL_texture( GLuint texture = SOIL_load_OGL_texture(
path, SOIL_LOAD_AUTO, path, SOIL_LOAD_AUTO,
SOIL_CREATE_NEW_ID, SOIL_CREATE_NEW_ID,
SOIL_FLAG_MIPMAPS | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_INVERT_Y); SOIL_FLAG_MIPMAPS | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_INVERT_Y);
if (texture == 0) { if (texture == 0) {
clog_log(CLOG_LEVEL_WARN, "Texture failed to load"); clog_log(CLOG_LEVEL_WARN, "Texture failed to load\n");
return 0; return 0;
} }
return texture; return texture;
@ -285,15 +287,24 @@ float getUnscaledDeltaTime() {
return deltaTime; return deltaTime;
} }
bool exitFlag = false;
static bool shouldExit() { static bool shouldExit() {
return glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0; return !(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0) || exitFlag;
}
std::string log;
void appendLog(clog_log_level_e, char *message, int length) {
log.append(message);
} }
static int initWindow() { static int initWindow() {
clog_set_append_newline(0);
clog_set_log_callback(appendLog, 1);
glfwSetErrorCallback(glfwErrorCallback); glfwSetErrorCallback(glfwErrorCallback);
if (!glfwInit()) { if (!glfwInit()) {
clog_log(CLOG_LEVEL_ERROR, "GLFW went shitty time (failed to init)"); clog_log(CLOG_LEVEL_ERROR, "GLFW went shitty time (failed to init)\n");
return 1; return 1;
} }
@ -305,7 +316,7 @@ static int initWindow() {
window = glfwCreateWindow(WIDTH, HEIGHT, "Fred", NULL, NULL); window = glfwCreateWindow(WIDTH, HEIGHT, "Fred", NULL, NULL);
if (window == NULL) { if (window == NULL) {
clog_log(CLOG_LEVEL_ERROR, "Failed to open window."); clog_log(CLOG_LEVEL_ERROR, "Failed to open window.\n");
glfwTerminate(); glfwTerminate();
return 1; return 1;
} }
@ -315,10 +326,10 @@ static int initWindow() {
int version; int version;
if ((version = gladLoadGL(glfwGetProcAddress))) { if ((version = gladLoadGL(glfwGetProcAddress))) {
clog_log(CLOG_LEVEL_DEBUG, "GL version: %d.%d", GLAD_VERSION_MAJOR(version), clog_log(CLOG_LEVEL_DEBUG, "GL version: %d.%d\n", GLAD_VERSION_MAJOR(version),
GLAD_VERSION_MINOR(version)); GLAD_VERSION_MINOR(version));
} else { } else {
clog_log(CLOG_LEVEL_ERROR, "Failed to init GL!"); clog_log(CLOG_LEVEL_ERROR, "Failed to init GL!\n");
return 1; return 1;
} }
@ -329,7 +340,7 @@ static int initWindow() {
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
//io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
@ -404,6 +415,7 @@ void destroy() {
void render(Scene scene) { void render(Scene scene) {
static ImVec2 viewportSize = ImVec2(1024, 768); static ImVec2 viewportSize = ImVec2(1024, 768);
static ImVec2 viewportPosition = ImVec2(0, 0);
static ImVec2 viewportSizeOld = viewportSize; static ImVec2 viewportSizeOld = viewportSize;
if (viewportSizeOld != viewportSize) { if (viewportSizeOld != viewportSize) {
glBindTexture(GL_TEXTURE_2D, renderedTexture); glBindTexture(GL_TEXTURE_2D, renderedTexture);
@ -428,6 +440,7 @@ void render(Scene scene) {
ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame(); ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();
ImGuizmo::BeginFrame();
static ImGuiDockNodeFlags dockspaceFlags = ImGuiDockNodeFlags_PassthruCentralNode; static ImGuiDockNodeFlags dockspaceFlags = ImGuiDockNodeFlags_PassthruCentralNode;
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking; ImGuiWindowFlags windowFlags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
@ -444,11 +457,25 @@ void render(Scene scene) {
windowFlags |= ImGuiWindowFlags_NoBackground; windowFlags |= ImGuiWindowFlags_NoBackground;
} }
ImGui::ShowDemoWindow();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
ImGui::Begin("DockSpace", nullptr, windowFlags); ImGui::Begin("DockSpace", nullptr, windowFlags);
ImGui::PopStyleVar(); ImGui::PopStyleVar();
ImGui::PopStyleVar(2); ImGui::PopStyleVar(2);
if (ImGui::BeginMenuBar()) {
if (ImGui::BeginMenu("File")) {
if (ImGui::MenuItem("Exit")) {
exitFlag = true;
}
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
ImGuiIO &io = ImGui::GetIO(); ImGuiIO &io = ImGui::GetIO();
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) { if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) {
ImGuiID dockspace_id = ImGui::GetID("myDockSpace"); ImGuiID dockspace_id = ImGui::GetID("myDockSpace");
@ -461,11 +488,14 @@ void render(Scene scene) {
ImGui::DockBuilderAddNode(dockspace_id, dockspaceFlags | ImGuiDockNodeFlags_DockSpace); ImGui::DockBuilderAddNode(dockspace_id, dockspaceFlags | ImGuiDockNodeFlags_DockSpace);
ImGui::DockBuilderSetNodeSize(dockspace_id, viewport->Size); ImGui::DockBuilderSetNodeSize(dockspace_id, viewport->Size);
ImGuiID dock_id_left = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Left, 0.2f, nullptr, &dockspace_id);
ImGuiID dock_id_down = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Down, 0.25f, nullptr, &dockspace_id); ImGuiID dock_id_down = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Down, 0.25f, nullptr, &dockspace_id);
ImGuiID dock_id_left = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Left, 0.2f, nullptr, &dockspace_id);
ImGuiID dock_id_right = ImGui::DockBuilderSplitNode(dockspace_id, ImGuiDir_Right, 0.3f, nullptr, &dockspace_id);
ImGui::DockBuilderDockWindow("Down", dock_id_down); ImGui::DockBuilderDockWindow("Console", dock_id_down);
ImGui::DockBuilderDockWindow("Left", dock_id_left); ImGui::DockBuilderDockWindow("User Render Callback", dock_id_left);
ImGui::DockBuilderDockWindow("Viewport", ImGui::DockBuilderGetCentralNode(dockspace_id)->ID);
ImGui::DockBuilderDockWindow("Asset Information", dock_id_right);
ImGui::DockBuilderFinish(dockspace_id); ImGui::DockBuilderFinish(dockspace_id);
} }
} }
@ -490,17 +520,6 @@ void render(Scene scene) {
glm::mat4 mvp = projectionMatrix * viewMatrix * modelMatrix; glm::mat4 mvp = projectionMatrix * viewMatrix * modelMatrix;
char assetName[] = "Asset: 00";
sprintf(assetName, "Asset: %d", i);
ImGui::Begin(assetName);
ImGui::Text("Frametime/Deltatime (ms): %f", deltaTime * 1000);
glm::vec3 rotationEuler = glm::degrees(eulerAngles(currentAsset->rotation));
ImGui::DragFloat3("Translate", (float*)&currentAsset->position, 0.01f);
ImGui::DragFloat3("Rotate", (float*)&rotationEuler);
ImGui::DragFloat3("Scale", (float*)&currentAsset->scaling, 0.01f);
currentAsset->rotation = glm::quat(glm::radians(rotationEuler));
ImGui::End();
glUniformMatrix4fv(currentAsset->matrixID, 1, GL_FALSE, &mvp[0][0]); glUniformMatrix4fv(currentAsset->matrixID, 1, GL_FALSE, &mvp[0][0]);
glUniformMatrix4fv(currentAsset->modelMatrixID, 1, GL_FALSE, &modelMatrix[0][0]); glUniformMatrix4fv(currentAsset->modelMatrixID, 1, GL_FALSE, &modelMatrix[0][0]);
glUniformMatrix4fv(currentAsset->viewMatrixID, 1, GL_FALSE, &viewMatrix[0][0]); glUniformMatrix4fv(currentAsset->viewMatrixID, 1, GL_FALSE, &viewMatrix[0][0]);
@ -556,18 +575,93 @@ void render(Scene scene) {
ImGui::Begin("Viewport"); ImGui::Begin("Viewport");
ImGui::Image((ImTextureID)frameBufferName, viewportSize, ImVec2(0, 1), ImVec2(1, 0)); ImGui::Image((ImTextureID)frameBufferName, viewportSize, ImVec2(0, 1), ImVec2(1, 0));
viewportSize = ImGui::GetWindowContentRegionMax() - ImGui::GetWindowContentRegionMin(); viewportSize = ImGui::GetWindowContentRegionMax() - ImGui::GetWindowContentRegionMin();
viewportPosition = ImGui::GetWindowPos();
ImGui::End(); ImGui::End();
ImGui::PopStyleVar(); ImGui::PopStyleVar();
ImGui::Begin("Console");
bool autoScroll = true;
if(ImGui::BeginPopup("Options")) {
ImGui::Checkbox("Auto-scroll", &autoScroll);
ImGui::EndPopup();
}
if (ImGui::Button("Options")) {
ImGui::OpenPopup("Options");
}
ImGui::Separator();
const float footerHeightToReserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
if (ImGui::BeginChild("ScrollingRegion", ImVec2(0, 0), ImGuiChildFlags_NavFlattened, ImGuiWindowFlags_HorizontalScrollbar)) {
if (ImGui::BeginPopupContextWindow()) {
if (ImGui::Selectable("Clear")) {
log = "";
ImGui::EndPopup();
}
ImGui::EndChild();
ImGui::Separator();
}
ImGui::Text("%s", log.c_str());
static std::string oldLog = log;
if (oldLog != log && autoScroll) {
ImGui::SetScrollHereY(1.0f);
oldLog = log;
}
ImGui::EndChild();
}
ImGui::End();
ImGui::Begin("Asset Information");
static int assetNum = 0;
ImGui::Text("Select asset ID");
for (int i = 0; i < scene.assets.size(); i++) {
char index[4]; // Probably never will need more than 3 digits of precision
sprintf(index, "%d", i);
if (ImGui::RadioButton(index, assetNum == i)) {
assetNum = i;
}
}
ImGui::Separator();
Asset *currentAsset = scene.assets[assetNum];
ImGuizmo::SetOwnerWindowName("Viewport");
static ImGuizmo::OPERATION currentGizmoOperation(ImGuizmo::ROTATE);
static ImGuizmo::MODE currentGizmoMode(ImGuizmo::WORLD);
if (ImGui::RadioButton("Translate", currentGizmoOperation == ImGuizmo::TRANSLATE)) {
currentGizmoOperation = ImGuizmo::TRANSLATE;
}
ImGui::SameLine();
if (ImGui::RadioButton("Rotate", currentGizmoOperation == ImGuizmo::ROTATE)) {
currentGizmoOperation = ImGuizmo::ROTATE;
}
ImGui::SameLine();
if (ImGui::RadioButton("Scale", currentGizmoOperation == ImGuizmo::SCALE)) {
currentGizmoOperation = ImGuizmo::SCALE;
}
ImGui::DragFloat3("Translate", &currentAsset->position[0], 0.01);
ImGui::DragFloat4("Rotate", &currentAsset->rotation[0], 0.01);
ImGui::DragFloat3("Scale", &currentAsset->scaling[0], 0.01);
glm::mat4 rotationMatrix = mat4_cast(currentAsset->rotation);
glm::mat4 translationMatrix = glm::translate(glm::mat4(1), currentAsset->position);
glm::mat4 scalingMatrix = glm::scale(glm::mat4(1), currentAsset->scaling);
glm::mat4 modelMatrix = translationMatrix * rotationMatrix * scalingMatrix;
ImGuizmo::SetRect(viewportPosition.x, viewportPosition.y, viewportSize.x, viewportSize.y);
ImGuizmo::Manipulate((const float *)&viewMatrix, (const float *)&projectionMatrix, currentGizmoOperation, currentGizmoMode, (float *)&modelMatrix, NULL, NULL);
glm::vec3 shitAngles;
ImGuizmo::DecomposeMatrixToComponents((float *)&modelMatrix, &currentAsset->position[0], (float *)&shitAngles, &currentAsset->scaling[0]);
currentAsset->rotation = glm::quat(glm::radians(shitAngles));
ImGui::End();
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, WIDTH, HEIGHT); glViewport(0, 0, WIDTH, HEIGHT);
ImGui::Render(); ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
//ImGui::UpdatePlatformWindows(); ImGui::UpdatePlatformWindows();
//ImGui::RenderPlatformWindowsDefault(); ImGui::RenderPlatformWindowsDefault();
//glfwMakeContextCurrent(window); glfwMakeContextCurrent(window);
// Swap buffers // Swap buffers
glfwSwapBuffers(window); glfwSwapBuffers(window);
@ -618,11 +712,11 @@ int main() {
scene.addAsset(cone); scene.addAsset(cone);
scene.addAsset(suzanne); scene.addAsset(suzanne);
scene.setRenderCallback(&renderCallback); scene.setRenderCallback(renderCallback);
fred::setDeltaTimeMultiplier(20.0f); fred::setDeltaTimeMultiplier(20.0f);
while (fred::shouldExit()) { while (!fred::shouldExit()) {
fred::render(scene); fred::render(scene);
cone.position.x += 0.01 * fred::getDeltaTime(); cone.position.x += 0.01 * fred::getDeltaTime();
glm::vec3 eulerAngles = glm::eulerAngles(suzanne.rotation); glm::vec3 eulerAngles = glm::eulerAngles(suzanne.rotation);

View File

@ -35,7 +35,7 @@ GLuint loadShaders(const char *vertex_file_path,
FILE *vertexShaderFD; FILE *vertexShaderFD;
if ((err = fopen_s(&vertexShaderFD, vertex_file_path, "rb"))) { if ((err = fopen_s(&vertexShaderFD, vertex_file_path, "rb"))) {
clog_log(CLOG_LEVEL_ERROR, "Failed to open Vertex Shader \"%s\": %d", clog_log(CLOG_LEVEL_ERROR, "Failed to open Vertex Shader \"%s\": %d\n",
vertex_file_path, err); vertex_file_path, err);
return 0; return 0;
} }
@ -48,7 +48,7 @@ GLuint loadShaders(const char *vertex_file_path,
FILE *fragmentShaderFD; FILE *fragmentShaderFD;
if ((err = fopen_s(&fragmentShaderFD, fragment_file_path, "rb"))) { if ((err = fopen_s(&fragmentShaderFD, fragment_file_path, "rb"))) {
clog_log(CLOG_LEVEL_ERROR, "Failed to open Vertex Shader \"%s\": %d", clog_log(CLOG_LEVEL_ERROR, "Failed to open Vertex Shader \"%s\": %d\n",
fragment_file_path, err); fragment_file_path, err);
return 0; return 0;
} }
@ -62,7 +62,7 @@ GLuint loadShaders(const char *vertex_file_path,
GLint result = GL_FALSE; GLint result = GL_FALSE;
int infoLogLength; int infoLogLength;
clog_log(CLOG_LEVEL_DEBUG, "Compiling shader: %s", vertex_file_path); clog_log(CLOG_LEVEL_DEBUG, "Compiling shader: %s\n", vertex_file_path);
char const *vertexShaderCodeConst = vertexShaderCode; char const *vertexShaderCodeConst = vertexShaderCode;
glShaderSource(vertexShaderID, 1, &vertexShaderCodeConst, NULL); glShaderSource(vertexShaderID, 1, &vertexShaderCodeConst, NULL);
glCompileShader(vertexShaderID); glCompileShader(vertexShaderID);
@ -76,11 +76,11 @@ GLuint loadShaders(const char *vertex_file_path,
sizeof(char)); // Not all compilers support VLAs, this will do sizeof(char)); // Not all compilers support VLAs, this will do
glGetShaderInfoLog(vertexShaderID, infoLogLength - 1, NULL, glGetShaderInfoLog(vertexShaderID, infoLogLength - 1, NULL,
vertexShaderErrorMessage); vertexShaderErrorMessage);
clog_log(CLOG_LEVEL_ERROR, "%s", vertexShaderErrorMessage); clog_log(CLOG_LEVEL_ERROR, "%s\n", vertexShaderErrorMessage);
free(vertexShaderErrorMessage); free(vertexShaderErrorMessage);
} }
clog_log(CLOG_LEVEL_DEBUG, "Compiling shader: %s", fragment_file_path); clog_log(CLOG_LEVEL_DEBUG, "Compiling shader: %s\n", fragment_file_path);
char const *fragmentShaderCodeConst = fragmentShaderCode; char const *fragmentShaderCodeConst = fragmentShaderCode;
glShaderSource(fragmentShaderID, 1, &fragmentShaderCodeConst, NULL); glShaderSource(fragmentShaderID, 1, &fragmentShaderCodeConst, NULL);
glCompileShader(fragmentShaderID); glCompileShader(fragmentShaderID);
@ -93,11 +93,11 @@ GLuint loadShaders(const char *vertex_file_path,
(char *)malloc(infoLogLength * sizeof(char)); (char *)malloc(infoLogLength * sizeof(char));
glGetShaderInfoLog(fragmentShaderID, infoLogLength - 1, NULL, glGetShaderInfoLog(fragmentShaderID, infoLogLength - 1, NULL,
fragmentShaderErrorMessage); fragmentShaderErrorMessage);
clog_log(CLOG_LEVEL_ERROR, "%s", fragmentShaderErrorMessage); clog_log(CLOG_LEVEL_ERROR, "%s\n", fragmentShaderErrorMessage);
free(fragmentShaderErrorMessage); free(fragmentShaderErrorMessage);
} }
clog_log(CLOG_LEVEL_DEBUG, "Linking shader program"); clog_log(CLOG_LEVEL_DEBUG, "Linking shader program\n");
GLuint programID = glCreateProgram(); GLuint programID = glCreateProgram();
glAttachShader(programID, vertexShaderID); glAttachShader(programID, vertexShaderID);
glAttachShader(programID, fragmentShaderID); glAttachShader(programID, fragmentShaderID);
@ -111,7 +111,7 @@ GLuint loadShaders(const char *vertex_file_path,
; ;
glGetProgramInfoLog(programID, infoLogLength - 1, NULL, glGetProgramInfoLog(programID, infoLogLength - 1, NULL,
programErrorMessage); programErrorMessage);
clog_log(CLOG_LEVEL_ERROR, "%s", programErrorMessage); clog_log(CLOG_LEVEL_ERROR, "%s\n", programErrorMessage);
free(programErrorMessage); free(programErrorMessage);
} }