first commit

This commit is contained in:
2025-06-15 22:03:02 -04:00
commit 91d01a1441
25 changed files with 24689 additions and 0 deletions

54
src/COMMON.h Normal file
View File

@ -0,0 +1,54 @@
#pragma once
#include <SDL3/SDL.h>
#include <SDL3_mixer/SDL_mixer.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <limits.h>
#include <math.h>
#include <pugixml.hpp>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <vector>
#include "STRINGS.h"
#include "RESOURCES.h"
using namespace glm;
using namespace pugi;
using namespace std;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
typedef float f32;
typedef double f64;
#define PI (GLM_PI)
#define TAU (PI * 2)
#define ATAN(x1, x2, y1, y2) (fmod((atan2(y2 - y1, x2 - x1) + TAU), TAU)) /* [0, 2PI] */
struct State
{
SDL_Window* window;
SDL_Renderer* renderer;
SDL_GLContext glContext;
vec3 clearColor = {0.69, 0.69, 0.69};
u64 tick = 0;
u64 lastTick = 0;
bool isRunning = true;
};

4
src/RESOURCES.h Normal file
View File

@ -0,0 +1,4 @@
#pragma once
#define RESOURCE_SHADER_VERTEX_TEXTURE_QUAD "res/shader/texture_quad.vs"
#define RESOURCE_SHADER_FRAGMENT_TEXTURE_QUAD "res/shader/texture_quad.fs"

26
src/STRINGS.h Normal file
View File

@ -0,0 +1,26 @@
#pragma once
#define STRING_WINDOW_TITLE "Anm2Ed"
#define STRING_ERROR_SDL_INIT "[ERROR] Could not initialize SDL (%s)\n"
#define STRING_ERROR_GL_CONTEXT_INIT "[ERROR] Could not initialize OpenGL context (%s)\n"
#define STRING_ERROR_FILE_READ "[ERROR] Could not read from file: %s\n"
#define STRING_ERROR_SHADER_INIT "[ERROR] Could not initialize shader: %s\n%s"
#define STRING_ERROR_TEXTURE_INIT "[ERROR] Could not initialize texture: %s (%s)\n"
#define STRING_ERROR_ANM2_INIT "[ERROR] Could not initialize anm2: %s (%s)\n"
#define STRING_INFO_INIT "[INFO] Initializing\n"
#define STRING_INFO_QUIT "[INFO] Exited\n"
#define STRING_INFO_SDL_INIT "[INFO] Initialized SDL\n"
#define STRING_INFO_SDL_QUIT "[INFO] Quit SDL\n"
#define STRING_INFO_GLEW_INIT "[INFO] Initialized GLEW\n"
#define STRING_INFO_GL_CONTEXT_INIT "[INFO] Initialized OpenGL context\n"
#define STRING_INFO_FILE_READ "[INFO] Read from file: %s\n"
#define STRING_INFO_SHADER_INIT "[INFO] Initialized shader: %s & %s\n"
#define STRING_INFO_TEXTURE_INIT "[INFO] Initialized texture: %s\n"
#define STRING_INFO_ANM2_INIT "[INFO] Initialized anm2: %s\n"
#define STRING_INFO_IMGUI_INIT "[INFO] Initialized Dear Imgui\n"
#define STRING_INFO_IMGUI_FREE "[INFO] Freed Dear Imgui\n"
#define STRING_OPENGL_VERSION "#version 330"

32
src/anm2.cpp Normal file
View File

@ -0,0 +1,32 @@
#include "anm2.h"
bool
anm2_init(Anm2* self, const char* path)
{
xml_document document;
xml_parse_result result;
memset(self, '\0', sizeof(Anm2));
result = document.load_file(path);
if (!result)
{
printf(STRING_ERROR_ANM2_INIT, path, result.description());
return false;
}
for (pugi::xml_node node : document.children())
printf("%s\n", node.name());
printf(STRING_INFO_ANM2_INIT, path);
return true;
}
void
anm2_free(Anm2* self)
{
}

289
src/anm2.h Normal file
View File

@ -0,0 +1,289 @@
#pragma once
#include "COMMON.h"
#define ANM2_SCALE_CONVERT(x) ((f32)x / 100.0f)
#define ANM2_TINT_CONVERT(x) ((f32)x / 255.0f)
#define ANM2_STRING_MAX 255
/* Elements */
#define STRING_ANM2_ELEMENT_ANIMATED_ACTOR "AnimatedActor"
#define STRING_ANM2_ELEMENT_INFO "Info"
#define STRING_ANM2_ELEMENT_CONTENT "Content"
#define STRING_ANM2_ELEMENT_SPRITESHEETS "Spritesheets"
#define STRING_ANM2_ELEMENT_SPRITESHEET "Spritesheet"
#define STRING_ANM2_ELEMENT_LAYERS "Layers"
#define STRING_ANM2_ELEMENT_LAYER "Layer"
#define STRING_ANM2_ELEMENT_NULLS "Nulls"
#define STRING_ANM2_ELEMENT_NULL "Null"
#define STRING_ANM2_ELEMENT_EVENTS "Events"
#define STRING_ANM2_ELEMENT_EVENT "Event"
#define STRING_ANM2_ELEMENT_ANIMATIONS "Animations"
#define STRING_ANM2_ELEMENT_ANIMATION "Animation"
#define STRING_ANM2_ELEMENT_ROOT_ANIMATION "RootAnimation"
#define STRING_ANM2_ELEMENT_FRAME "Frame"
#define STRING_ANM2_ELEMENT_LAYER_ANIMATIONS "LayerAnimations"
#define STRING_ANM2_ELEMENT_LAYER_ANIMATION "LayerAnimation"
#define STRING_ANM2_ELEMENT_NULL_ANIMATIONS "NullAnimations"
#define STRING_ANM2_ELEMENT_NULL_ANIMATION "NullAnimation"
#define STRING_ANM2_ELEMENT_TRIGGERS "Triggers"
#define STRING_ANM2_ELEMENT_TRIGGER "Trigger"
/* Attributes */
#define STRING_ANM2_ATTRIBUTE_CREATED_BY "CreatedBy"
#define STRING_ANM2_ATTRIBUTE_CREATED_ON "CreatedOn"
#define STRING_ANM2_ATTRIBUTE_FPS "Fps"
#define STRING_ANM2_ATTRIBUTE_VERSION "Version"
#define STRING_ANM2_ATTRIBUTE_ID "Id"
#define STRING_ANM2_ATTRIBUTE_PATH "Path"
#define STRING_ANM2_ATTRIBUTE_NAME "Name"
#define STRING_ANM2_ATTRIBUTE_SPRITESHEET_ID "SpritesheetId"
#define STRING_ANM2_ATTRIBUTE_SHOW_RECT "ShowRect"
#define STRING_ANM2_ATTRIBUTE_DEFAULT_ANIMATION "DefaultAnimation"
#define STRING_ANM2_ATTRIBUTE_FRAME_NUM "FrameNum"
#define STRING_ANM2_ATTRIBUTE_LOOP "Loop"
#define STRING_ANM2_ATTRIBUTE_X_POSITION "XPosition"
#define STRING_ANM2_ATTRIBUTE_Y_POSITION "YPosition"
#define STRING_ANM2_ATTRIBUTE_X_PIVOT "XPivot"
#define STRING_ANM2_ATTRIBUTE_Y_PIVOT "YPivot"
#define STRING_ANM2_ATTRIBUTE_X_CROP "XCrop"
#define STRING_ANM2_ATTRIBUTE_Y_CROP "YCrop"
#define STRING_ANM2_ATTRIBUTE_WIDTH "Width"
#define STRING_ANM2_ATTRIBUTE_HEIGHT "Height"
#define STRING_ANM2_ATTRIBUTE_X_SCALE "XScale"
#define STRING_ANM2_ATTRIBUTE_Y_SCALE "YScale"
#define STRING_ANM2_ATTRIBUTE_DELAY "Delay"
#define STRING_ANM2_ATTRIBUTE_VISIBLE "Visible"
#define STRING_ANM2_ATTRIBUTE_RED_TINT "RedTint"
#define STRING_ANM2_ATTRIBUTE_GREEN_TINT "GreenTint"
#define STRING_ANM2_ATTRIBUTE_BLUE_TINT "BlueTint"
#define STRING_ANM2_ATTRIBUTE_ALPHA_TINT "AlphaTint"
#define STRING_ANM2_ATTRIBUTE_RED_OFFSET "RedOffset"
#define STRING_ANM2_ATTRIBUTE_GREEN_OFFSET "GreenOffset"
#define STRING_ANM2_ATTRIBUTE_BLUE_OFFSET "BlueOffset"
#define STRING_ANM2_ATTRIBUTE_ROTATION "Rotation"
#define STRING_ANM2_ATTRIBUTE_INTERPOLATED "Interpolated"
#define STRING_ANM2_ATTRIBUTE_LAYER_ID "LayerId"
#define STRING_ANM2_ATTRIBUTE_NULL_ID "NullId"
#define STRING_ANM2_ATTRIBUTE_EVENT_ID "EventId"
#define STRING_ANM2_ATTRIBUTE_AT_FRAME "AtFrame"
#define ANM2_ELEMENT_COUNT (ANM2_ELEMENT_TRIGGER + 1)
enum Anm2Element
{
ANM2_ELEMENT_ANIMATED_ACTOR,
ANM2_ELEMENT_INFO,
ANM2_ELEMENT_CONTENT,
ANM2_ELEMENT_SPRITESHEETS,
ANM2_ELEMENT_SPRITESHEET,
ANM2_ELEMENT_LAYERS,
ANM2_ELEMENT_LAYER,
ANM2_ELEMENT_NULLS,
ANM2_ELEMENT_NULL,
ANM2_ELEMENT_EVENTS,
ANM2_ELEMENT_EVENT,
ANM2_ELEMENT_ANIMATIONS,
ANM2_ELEMENT_ANIMATION,
ANM2_ELEMENT_ROOT_ANIMATION,
ANM2_ELEMENT_FRAME,
ANM2_ELEMENT_LAYER_ANIMATIONS,
ANM2_ELEMENT_LAYER_ANIMATION,
ANM2_ELEMENT_NULL_ANIMATIONS,
ANM2_ELEMENT_NULL_ANIMATION,
ANM2_ELEMENT_TRIGGERS,
ANM2_ELEMENT_TRIGGER
};
static const char* ANM2_ELEMENT_STRINGS[ANM2_ELEMENT_COUNT] =
{
STRING_ANM2_ELEMENT_ANIMATED_ACTOR,
STRING_ANM2_ELEMENT_INFO,
STRING_ANM2_ELEMENT_CONTENT,
STRING_ANM2_ELEMENT_SPRITESHEETS,
STRING_ANM2_ELEMENT_SPRITESHEET,
STRING_ANM2_ELEMENT_LAYERS,
STRING_ANM2_ELEMENT_LAYER,
STRING_ANM2_ELEMENT_NULLS,
STRING_ANM2_ELEMENT_NULL,
STRING_ANM2_ELEMENT_EVENTS,
STRING_ANM2_ELEMENT_EVENT,
STRING_ANM2_ELEMENT_ANIMATIONS,
STRING_ANM2_ELEMENT_ANIMATION,
STRING_ANM2_ELEMENT_ROOT_ANIMATION,
STRING_ANM2_ELEMENT_FRAME,
STRING_ANM2_ELEMENT_LAYER_ANIMATIONS,
STRING_ANM2_ELEMENT_LAYER_ANIMATION,
STRING_ANM2_ELEMENT_NULL_ANIMATIONS,
STRING_ANM2_ELEMENT_NULL_ANIMATION,
STRING_ANM2_ELEMENT_TRIGGERS,
STRING_ANM2_ELEMENT_TRIGGER
};
#define ANM2_ATTRIBUTE_COUNT (ANM2_ATTRIBUTE_AT_FRAME + 1)
enum Anm2Attribute
{
ANM2_ATTRIBUTE_CREATED_BY,
ANM2_ATTRIBUTE_CREATED_ON,
ANM2_ATTRIBUTE_FPS,
ANM2_ATTRIBUTE_VERSION,
ANM2_ATTRIBUTE_ID,
ANM2_ATTRIBUTE_PATH,
ANM2_ATTRIBUTE_NAME,
ANM2_ATTRIBUTE_SPRITESHEET_ID,
ANM2_ATTRIBUTE_SHOW_RECT,
ANM2_ATTRIBUTE_DEFAULT_ANIMATION,
ANM2_ATTRIBUTE_FRAME_NUM,
ANM2_ATTRIBUTE_LOOP,
ANM2_ATTRIBUTE_X_POSITION,
ANM2_ATTRIBUTE_Y_POSITION,
ANM2_ATTRIBUTE_X_PIVOT,
ANM2_ATTRIBUTE_Y_PIVOT,
ANM2_ATTRIBUTE_X_CROP,
ANM2_ATTRIBUTE_Y_CROP,
ANM2_ATTRIBUTE_WIDTH,
ANM2_ATTRIBUTE_HEIGHT,
ANM2_ATTRIBUTE_X_SCALE,
ANM2_ATTRIBUTE_Y_SCALE,
ANM2_ATTRIBUTE_DELAY,
ANM2_ATTRIBUTE_VISIBLE,
ANM2_ATTRIBUTE_RED_TINT,
ANM2_ATTRIBUTE_GREEN_TINT,
ANM2_ATTRIBUTE_BLUE_TINT,
ANM2_ATTRIBUTE_ALPHA_TINT,
ANM2_ATTRIBUTE_RED_OFFSET,
ANM2_ATTRIBUTE_GREEN_OFFSET,
ANM2_ATTRIBUTE_BLUE_OFFSET,
ANM2_ATTRIBUTE_ROTATION,
ANM2_ATTRIBUTE_INTERPOLATED,
ANM2_ATTRIBUTE_LAYER_ID,
ANM2_ATTRIBUTE_NULL_ID,
ANM2_ATTRIBUTE_EVENT_ID,
ANM2_ATTRIBUTE_AT_FRAME
};
static const char* ANM2_ATTRIBUTE_STRINGS[ANM2_ATTRIBUTE_COUNT] =
{
STRING_ANM2_ATTRIBUTE_CREATED_BY,
STRING_ANM2_ATTRIBUTE_CREATED_ON,
STRING_ANM2_ATTRIBUTE_FPS,
STRING_ANM2_ATTRIBUTE_VERSION,
STRING_ANM2_ATTRIBUTE_ID,
STRING_ANM2_ATTRIBUTE_PATH,
STRING_ANM2_ATTRIBUTE_NAME,
STRING_ANM2_ATTRIBUTE_SPRITESHEET_ID,
STRING_ANM2_ATTRIBUTE_SHOW_RECT,
STRING_ANM2_ATTRIBUTE_DEFAULT_ANIMATION,
STRING_ANM2_ATTRIBUTE_FRAME_NUM,
STRING_ANM2_ATTRIBUTE_LOOP,
STRING_ANM2_ATTRIBUTE_X_POSITION,
STRING_ANM2_ATTRIBUTE_Y_POSITION,
STRING_ANM2_ATTRIBUTE_X_PIVOT,
STRING_ANM2_ATTRIBUTE_Y_PIVOT,
STRING_ANM2_ATTRIBUTE_X_CROP,
STRING_ANM2_ATTRIBUTE_Y_CROP,
STRING_ANM2_ATTRIBUTE_WIDTH,
STRING_ANM2_ATTRIBUTE_HEIGHT,
STRING_ANM2_ATTRIBUTE_X_SCALE,
STRING_ANM2_ATTRIBUTE_Y_SCALE,
STRING_ANM2_ATTRIBUTE_DELAY,
STRING_ANM2_ATTRIBUTE_VISIBLE,
STRING_ANM2_ATTRIBUTE_RED_TINT,
STRING_ANM2_ATTRIBUTE_GREEN_TINT,
STRING_ANM2_ATTRIBUTE_BLUE_TINT,
STRING_ANM2_ATTRIBUTE_ALPHA_TINT,
STRING_ANM2_ATTRIBUTE_RED_OFFSET,
STRING_ANM2_ATTRIBUTE_GREEN_OFFSET,
STRING_ANM2_ATTRIBUTE_BLUE_OFFSET,
STRING_ANM2_ATTRIBUTE_ROTATION,
STRING_ANM2_ATTRIBUTE_INTERPOLATED,
STRING_ANM2_ATTRIBUTE_LAYER_ID,
STRING_ANM2_ATTRIBUTE_NULL_ID,
STRING_ANM2_ATTRIBUTE_EVENT_ID,
STRING_ANM2_ATTRIBUTE_AT_FRAME
};
#define ANM2_ANIMATION_TYPE_COUNT (ANM2_ANIMATION_NULL + 1)
enum Anm2AnimationType
{
ANM2_ANIMATION_ROOT,
ANM2_ANIMATION_LAYER,
ANM2_ANIMATION_NULL
};
struct Anm2Spritesheet
{
s32 id;
char path[ANM2_STRING_MAX];
};
struct Anm2Layer
{
s32 id;
char name[ANM2_STRING_MAX];
s32 spritesheetID;
};
struct Anm2Event
{
s32 id;
char name[ANM2_STRING_MAX];
};
struct Anm2Trigger
{
s32 eventID;
s32 frame;
};
struct Anm2Frame
{
bool isInterpolated;
bool isVisible;
f32 rotation;
s32 delay;
ivec2 crop;
ivec2 pivot;
ivec2 position;
ivec2 size;
ivec2 scale;
ivec3 colorOffset;
ivec4 tint;
s32 index;
};
struct Anm2LayerAnimation
{
s32 layerID;
bool isVisible;
vector<Anm2Frame> frames;
};
struct Anm2Animation
{
s32 id;
s32 length;
char name[ANM2_STRING_MAX];
bool isVisible;
bool isLoop;
Anm2Frame rootAnimationFrame;
vector<Anm2LayerAnimation> layerAnimations;
vector<Anm2Trigger> triggers;
};
struct Anm2
{
s32 fps;
s32 version;
char createdBy[ANM2_STRING_MAX];
char createdOn[ANM2_STRING_MAX];
char defaultAnimation[ANM2_STRING_MAX];
bool isInit;
vector<Anm2Spritesheet> spritesheets;
vector<Anm2Layer> layers;
vector<Anm2Event> events;
vector<Anm2Animation> animations;
};
bool anm2_init(Anm2* self, const char* path);
void anm2_free(Anm2* self);

28
src/file.cpp Normal file
View File

@ -0,0 +1,28 @@
#include "file.h"
bool
file_read(const char* path, void* buffer, size_t size)
{
SDL_IOStream* ioStream;
memset(buffer, '\0', size);
ioStream = SDL_IOFromFile(path, "r");
if (!ioStream)
{
printf(STRING_ERROR_FILE_READ, path);
return false;
}
if (!SDL_ReadIO(ioStream, buffer, size))
{
printf(STRING_ERROR_FILE_READ, path);
return false;
}
SDL_CloseIO(ioStream);
return true;
}

5
src/file.h Normal file
View File

@ -0,0 +1,5 @@
#pragma once
#include "COMMON.h"
bool file_read(const char* path, void* buffer, size_t size);

45
src/imgui.cpp Normal file
View File

@ -0,0 +1,45 @@
#include "imgui.h"
void
imgui_init(SDL_Window* window, SDL_GLContext glContext)
{
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGui::StyleColorsDark();
ImGui_ImplSDL3_InitForOpenGL(window, glContext);
ImGui_ImplOpenGL3_Init(STRING_OPENGL_VERSION);
printf(STRING_INFO_IMGUI_INIT);
}
void
imgui_tick(State* state)
{
ImGui_ImplSDL3_NewFrame();
ImGui_ImplOpenGL3_NewFrame();
ImGui::NewFrame();
ImGui::Begin("Hello, world!");
ImGui::Text("Color");
ImGui::ColorEdit3("Color", value_ptr(state->clearColor));
ImGui::End();
}
void
imgui_draw(void)
{
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
void
imgui_free(void)
{
ImGui_ImplSDL3_Shutdown();
ImGui_ImplOpenGL3_Shutdown();
ImGui::DestroyContext();
printf(STRING_INFO_IMGUI_FREE);
}

15
src/imgui.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include "COMMON.h"
#define IMGUI_IMPL_OPENGL_LOADER_CUSTOM
#include <imgui/imgui.h>
#include <imgui/imgui_impl_sdl3.h>
#include <imgui/imgui_impl_opengl3.h>
#define IMGUI_DRAG_SPEED 1.0
void imgui_init(SDL_Window* window, SDL_GLContext glContext);
void imgui_tick(State* state);
void imgui_draw();
void imgui_free();

128
src/main.cpp Normal file
View File

@ -0,0 +1,128 @@
#include "main.h"
static void _init(State* state);
static void _draw(State* state);
static void _loop(State* state);
static void _quit(State* state);
static void _tick(State* state);
static void
_init(State* state)
{
Shader shader;
printf(STRING_INFO_INIT);
if (!SDL_Init(SDL_INIT_VIDEO))
{
printf(STRING_ERROR_SDL_INIT, SDL_GetError());
_quit(state);
}
printf(STRING_INFO_SDL_INIT);
SDL_CreateWindowAndRenderer
(
STRING_WINDOW_TITLE,
WINDOW_WIDTH,
WINDOW_HEIGHT,
WINDOW_FLAGS,
&state->window,
&state->renderer
);
state->glContext = SDL_GL_CreateContext(state->window);
if (!state->glContext)
{
printf(STRING_ERROR_GL_CONTEXT_INIT, SDL_GetError());
_quit(state);
}
glewInit();
printf(STRING_INFO_GLEW_INIT);
shader_init(&shader, RESOURCE_SHADER_VERTEX_TEXTURE_QUAD, RESOURCE_SHADER_FRAGMENT_TEXTURE_QUAD);
imgui_init(state->window, state->glContext);
Anm2 anm2;
anm2_init(&anm2, "res/anm2/005.031_key.anm2");
}
void
_loop(State* state)
{
state->tick = SDL_GetTicks();
while (state->tick > state->lastTick + TICK_DELAY)
{
state->tick = SDL_GetTicks();
if (state->tick - state->lastTick < TICK_DELAY)
SDL_Delay(TICK_DELAY - (state->tick - state->lastTick));
_tick(state);
imgui_tick(state);
_draw(state);
state->lastTick = state->tick;
}
}
void
_tick(State* state)
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
ImGui_ImplSDL3_ProcessEvent(&event);
if (event.type == SDL_EVENT_QUIT)
state->isRunning = false;
}
}
void
_draw(State* state)
{
glClearColor(state->clearColor.x, state->clearColor.y, state->clearColor.z, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
imgui_draw();
SDL_GL_SwapWindow(state->window);
}
void
_quit(State* state)
{
imgui_free();
SDL_GL_DestroyContext(state->glContext);
SDL_Quit();
printf(STRING_INFO_SDL_QUIT);
printf(STRING_INFO_QUIT);
}
s32
main(s32 argc, char* argv[])
{
State state;
_init(&state);
while (state.isRunning)
_loop(&state);
_quit(&state);
return EXIT_SUCCESS;
}

11
src/main.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
#include "texture.h"
#include "shader.h"
#include "imgui.h"
#include "anm2.h"
#define TICK_DELAY 16
#define WINDOW_WIDTH 1600
#define WINDOW_HEIGHT 900
#define WINDOW_FLAGS SDL_WINDOW_RESIZABLE

75
src/shader.cpp Normal file
View File

@ -0,0 +1,75 @@
#include "shader.h"
static bool _shader_compile(GLuint handle, const char* path);
static bool
_shader_compile(GLuint handle, const char* path)
{
char buffer[SHADER_BUFFER_MAX];
char compileLog[SHADER_BUFFER_MAX];
s32 isCompile;
file_read(path, buffer, SHADER_BUFFER_MAX);
const GLchar* source = buffer;
glShaderSource(handle, 1, &source, NULL);
glCompileShader(handle);
glGetShaderiv(handle, GL_COMPILE_STATUS, &isCompile);
if (!isCompile)
{
glGetShaderInfoLog(handle, SHADER_BUFFER_MAX, NULL, compileLog);
printf(STRING_ERROR_SHADER_INIT, path, compileLog);
return false;
}
return true;
}
bool
shader_init(Shader* self, const char* vertexPath, const char* fragmentPath)
{
GLuint vertexHandle;
GLuint fragmentHandle;
bool isSuccess;
memset(self, '\0', sizeof(Shader));
vertexHandle = glCreateShader(GL_VERTEX_SHADER);
fragmentHandle = glCreateShader(GL_FRAGMENT_SHADER);
if
(
!_shader_compile(vertexHandle, vertexPath) ||
!_shader_compile(fragmentHandle, fragmentPath)
)
return false;
self->handle = glCreateProgram();
glAttachShader(self->handle, vertexHandle);
glAttachShader(self->handle, fragmentHandle);
glLinkProgram(self->handle);
glDeleteShader(vertexHandle);
glDeleteShader(fragmentHandle);
printf(STRING_INFO_SHADER_INIT, vertexPath, fragmentPath);
return true;
}
void
shader_use(Shader* self)
{
glUseProgram(self->handle);
}
void
shader_free(Shader* self)
{
glDeleteProgram(self->handle);
}

14
src/shader.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include "file.h"
#define SHADER_BUFFER_MAX 2048
struct Shader
{
GLuint handle = 0;
};
bool shader_init(Shader* self, const char* vertexPath, const char* fragmentPath);
void shader_free(Shader* self);
void shader_use(Shader* self);

40
src/texture.cpp Normal file
View File

@ -0,0 +1,40 @@
#include "texture.h"
#define STBI_ONLY_PNG
#define STBI_NO_FAILURE_STRINGS
#define STBI_NO_HDR
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
bool
texture_init(Texture* self, const char* path)
{
void* data;
data = stbi_load(path, &self->size[0], &self->size[1], &self->channels, 4);
if (!data)
return false;
glGenTextures(1, &self->handle);
glBindTexture(GL_TEXTURE_2D, self->handle);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self->size.x, self->size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
return true;
}
void
texture_free(Texture* self)
{
glDeleteTextures(1, &self->handle);
memset(self, '\0', sizeof(Texture));
}

13
src/texture.h Normal file
View File

@ -0,0 +1,13 @@
#pragma once
#include "COMMON.h"
struct Texture
{
GLuint handle = 0;
ivec2 size = {0, 0};
s32 channels = -1;
};
bool texture_init(Texture* self, const char* path);
void texture_free(Texture* self);