Pressing 1-4 loads a different sprite animation

This commit is contained in:
Joseph Ferano 2023-10-26 14:49:27 +07:00
parent dc054cacfb
commit f548bdebb9
5 changed files with 149 additions and 36 deletions

24
animation.h Normal file
View File

@ -0,0 +1,24 @@
#pragma once
typedef struct {
char* name;
byte* imgData;
u16 animCount;
u16 width;
u16 height;
} SpriteSheet;
typedef struct {
char* name;
f32 posX;
f32 posY;
u16 rows;
u16 cols;
u16 width;
u16 height;
} Animation;
typedef struct {
float timeElapsed;
int frame;
} AnimationPlayback;

BIN
assets/player.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

11
lib.h
View File

@ -8,6 +8,7 @@
typedef uint8_t u8; typedef uint8_t u8;
// typedef char16_t c16; // typedef char16_t c16;
typedef uint16_t u16; typedef uint16_t u16;
typedef int16_t i16;
typedef int32_t b32; typedef int32_t b32;
typedef int32_t i32; typedef int32_t i32;
typedef uint32_t u32; typedef uint32_t u32;
@ -19,16 +20,6 @@ typedef char byte;
typedef ptrdiff_t size; typedef ptrdiff_t size;
typedef size_t usize; typedef size_t usize;
typedef struct Animation {
char* name;
u16 x_pos;
u16 y_pos;
u16 rows;
u16 cols;
u16 width;
u16 height;
} Animation;
typedef struct s8 { typedef struct s8 {
u8* data; u8* data;
usize size; usize size;

121
main.c
View File

@ -7,6 +7,7 @@
#include "lib.h" #include "lib.h"
#include "stb_image.h" #include "stb_image.h"
#include "rendering.h" #include "rendering.h"
#include "animation.h"
#include "libcyaml/include/cyaml/cyaml.h" #include "libcyaml/include/cyaml/cyaml.h"
#define PI 3.14159f #define PI 3.14159f
@ -20,6 +21,7 @@ typedef struct State {
float px; float px;
float py; float py;
int spriteY; int spriteY;
int currentAnim;
} State; } State;
void framebuffer_size_callback(GLFWwindow* window, int width, int height) { void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
@ -35,11 +37,17 @@ void processInput(GLFWwindow *window, State* state) {
} }
float amount = 1.0f; float amount = 1.0f;
if (glfwGetKey(window, GLFW_KEY_J) == GLFW_RELEASE) { if (glfwGetKey(window, GLFW_KEY_1) == GLFW_PRESS) {
state->spriteY -= 1; state->currentAnim = 0;
} }
if (glfwGetKey(window, GLFW_KEY_K) == GLFW_RELEASE) { if (glfwGetKey(window, GLFW_KEY_2) == GLFW_PRESS) {
state->spriteY += 1; state->currentAnim = 1;
}
if (glfwGetKey(window, GLFW_KEY_3) == GLFW_PRESS) {
state->currentAnim = 2;
}
if (glfwGetKey(window, GLFW_KEY_4) == GLFW_PRESS) {
state->currentAnim = 3;
} }
if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) {
state->camY -= amount; state->camY -= amount;
@ -53,7 +61,7 @@ void processInput(GLFWwindow *window, State* state) {
if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) {
state->camX += amount; state->camX += amount;
} }
amount = 1.1f; amount = 2.1f;
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) { if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
state->py -= amount; state->py -= amount;
} }
@ -128,13 +136,63 @@ int main(void) {
unsigned int textureID; unsigned int textureID;
int width, height, channels; int width, height, channels;
char* data = (char*)stbi_load("assets/player.png", &width, &height, &channels, 4); byte* data = (char*)stbi_load("assets/player.png", &width, &height, &channels, 4);
// char* data = (char*)stbi_load("imports/sprites/player/idle.png", &width, &height, &channels, 4); // char* data = (char*)stbi_load("imports/sprites/player/idle.png", &width, &height, &channels, 4);
if (data == NULL) { if (data == NULL) {
fprintf(stderr, "Could not load texture\n"); fprintf(stderr, "Could not load texture\n");
return -1; return -1;
} }
SpriteSheet spriteSheet = {
.name = "player",
.imgData = data,
.animCount = 4,
.width = width,
.height = height,
};
Animation idle = {
.name = "idle",
.posX = 0,
.posY = 0,
.rows = 1,
.cols = 10,
.width = 48,
.height = 48,
};
Animation run = {
.name = "run",
.posX = 0,
.posY = 48 * 3,
.rows = 1,
.cols = 8,
.width = 48,
.height = 48,
};
Animation jump = {
.name = "jump",
.posX = 0,
.posY = 48,
.rows = 1,
.cols = 3,
.width = 48,
.height = 48,
};
Animation land = {
.name = "land",
.posX = 0,
.posY = 48 * 2,
.rows = 1,
.cols = 9,
.width = 48,
.height = 48,
};
Animation playerAnims[4] = {idle, run, jump, land};
glGenTextures(1, &textureID); glGenTextures(1, &textureID);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID); glBindTexture(GL_TEXTURE_2D, textureID);
@ -169,7 +227,6 @@ int main(void) {
glUseProgram(shaderProgram); glUseProgram(shaderProgram);
// vec4 vec = {1.0f, 0.0f, 0.0f, 1.0f};
mat4 model; mat4 model;
mat4 projection; mat4 projection;
glm_mat4_identity(model); glm_mat4_identity(model);
@ -179,10 +236,8 @@ int main(void) {
glm_translate(model, (vec3){state.px, state.py, 0.0f}); glm_translate(model, (vec3){state.px, state.py, 0.0f});
glm_translate(model, (vec3){0.f, 0.f, 0.0f}); glm_translate(model, (vec3){0.f, 0.f, 0.0f});
glm_translate(model, (vec3){pivotx, pivoty, 0.0f}); glm_translate(model, (vec3){pivotx, pivoty, 0.0f});
// glm_rotate(model, currentFrame, (vec3){0.0f, 0.0f, 1.0f});
glm_scale(model, (vec3){100.0f, 100.0f, 0.0f}); glm_scale(model, (vec3){100.0f, 100.0f, 0.0f});
glm_translate(model, (vec3){-pivotx, -pivoty, 0.0f}); glm_translate(model, (vec3){-pivotx, -pivoty, 0.0f});
// printf("X:%f Y:%f Z:%f\n", projection[3][0], projection[3][1], projection[3][2]);
float worldUnitSizeInPixels = 2; // Desired size of a 1x1 area on the screen float worldUnitSizeInPixels = 2; // Desired size of a 1x1 area on the screen
float hw = (SCREEN_WIDTH / 2.f) / worldUnitSizeInPixels; float hw = (SCREEN_WIDTH / 2.f) / worldUnitSizeInPixels;
@ -197,26 +252,56 @@ int main(void) {
location = glGetUniformLocation(shaderProgram, "projection"); location = glGetUniformLocation(shaderProgram, "projection");
glUniformMatrix4fv(location, 1, GL_FALSE, projection[0]); glUniformMatrix4fv(location, 1, GL_FALSE, projection[0]);
location = glGetUniformLocation(shaderProgram, "spriteColor"); glUniform1i(glGetUniformLocation(shaderProgram, "image"), 0);
glUniform3f(location, 1.0f, 1.0f, 1.0f);
Animation anim = playerAnims[state.currentAnim];
elapsed += deltaTime; elapsed += deltaTime;
if (elapsed > 0.1f) { if (elapsed > 0.1f) {
frameCount += 1; frameCount += 1;
if (frameCount > 9) { if (frameCount >= anim.cols) {
frameCount = 0; frameCount = 0;
} }
elapsed = 0.0f; elapsed = 0.0f;
} }
location = glGetUniformLocation(shaderProgram, "spriteX"); location = glGetUniformLocation(shaderProgram, "posX");
float spriteX = (float)frameCount / 10; glUniform1f(location, anim.posX);
glUniform1f(location, spriteX);
location = glGetUniformLocation(shaderProgram, "spriteY"); location = glGetUniformLocation(shaderProgram, "posY");
glUniform1f(location, state.camY); glUniform1f(location, anim.posY);
location = glGetUniformLocation(shaderProgram, "animRow");
glUniform1i(location, frameCount);
// We don't animate on the Y axis yet
location = glGetUniformLocation(shaderProgram, "animCol");
glUniform1i(location, 0);
location = glGetUniformLocation(shaderProgram, "rows");
glUniform1i(location, anim.rows);
location = glGetUniformLocation(shaderProgram, "cols");
glUniform1i(location, anim.cols);
location = glGetUniformLocation(shaderProgram, "spriteWidth");
glUniform1i(location, anim.width);
location = glGetUniformLocation(shaderProgram, "spriteHeight");
glUniform1i(location, anim.height);
location = glGetUniformLocation(shaderProgram, "atlasWidth");
glUniform1i(location, spriteSheet.width);
location = glGetUniformLocation(shaderProgram, "atlasHeight");
glUniform1i(location, spriteSheet.height);
// location = glGetUniformLocation(shaderProgram, "spriteColor");
// glUniform3f(location, 1.0f, 1.0f, 1.0f);
// SpriteSheet spriteSheet = spriteSheet;
// printf("%i\n", state.currentAnim);
glUniform1i(glGetUniformLocation(shaderProgram, "image"), 0);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID); glBindTexture(GL_TEXTURE_2D, textureID);

View File

@ -3,20 +3,33 @@ in vec2 TexCoords;
out vec4 color; out vec4 color;
uniform sampler2D image; uniform sampler2D image;
uniform float posX;
uniform float posY;
uniform int animRow;
uniform int animCol;
uniform int rows;
uniform int cols;
uniform int spriteWidth;
uniform int spriteHeight;
uniform int atlasWidth;
uniform int atlasHeight;
// Unused for now
uniform vec3 spriteColor; uniform vec3 spriteColor;
uniform float spriteX;
uniform float spriteY;
void main() { void main() {
float r = (48.0 / 512.0); float rw = (float(spriteWidth) / float(atlasWidth));
float x = TexCoords.x * r + (int(spriteX * 10)) * r; float rh = (float(spriteHeight) / float(atlasHeight));
// float y = TexCoords.y * r + (int(spriteY * 10)) * r; float x = TexCoords.x * rw + posX + animRow * rw;
float y = TexCoords.y * r; float y = TexCoords.y * rh + (posY / float(atlasHeight)) + animCol * rh;
float minb = 0.005; float minb = 0.005;
float maxb = 0.995; float maxb = 0.995;
if (TexCoords.x <= minb || TexCoords.x >= maxb bool drawDebugBorders =
|| TexCoords.y <= minb || TexCoords.y >= maxb) { TexCoords.x <= minb || TexCoords.x >= maxb
|| TexCoords.y <= minb || TexCoords.y >= maxb;
if (drawDebugBorders) {
color = vec4(1,0,0,1); color = vec4(1,0,0,1);
} else { } else {
color = texture(image, vec2(x, y)); color = texture(image, vec2(x, y));