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 char16_t c16;
typedef uint16_t u16;
typedef int16_t i16;
typedef int32_t b32;
typedef int32_t i32;
typedef uint32_t u32;
@ -19,16 +20,6 @@ typedef char byte;
typedef ptrdiff_t size;
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 {
u8* data;
usize size;

121
main.c
View File

@ -7,6 +7,7 @@
#include "lib.h"
#include "stb_image.h"
#include "rendering.h"
#include "animation.h"
#include "libcyaml/include/cyaml/cyaml.h"
#define PI 3.14159f
@ -20,6 +21,7 @@ typedef struct State {
float px;
float py;
int spriteY;
int currentAnim;
} State;
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
@ -35,11 +37,17 @@ void processInput(GLFWwindow *window, State* state) {
}
float amount = 1.0f;
if (glfwGetKey(window, GLFW_KEY_J) == GLFW_RELEASE) {
state->spriteY -= 1;
if (glfwGetKey(window, GLFW_KEY_1) == GLFW_PRESS) {
state->currentAnim = 0;
}
if (glfwGetKey(window, GLFW_KEY_K) == GLFW_RELEASE) {
state->spriteY += 1;
if (glfwGetKey(window, GLFW_KEY_2) == GLFW_PRESS) {
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) {
state->camY -= amount;
@ -53,7 +61,7 @@ void processInput(GLFWwindow *window, State* state) {
if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) {
state->camX += amount;
}
amount = 1.1f;
amount = 2.1f;
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
state->py -= amount;
}
@ -128,13 +136,63 @@ int main(void) {
unsigned int textureID;
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);
if (data == NULL) {
fprintf(stderr, "Could not load texture\n");
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);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID);
@ -169,7 +227,6 @@ int main(void) {
glUseProgram(shaderProgram);
// vec4 vec = {1.0f, 0.0f, 0.0f, 1.0f};
mat4 model;
mat4 projection;
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){0.f, 0.f, 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_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 hw = (SCREEN_WIDTH / 2.f) / worldUnitSizeInPixels;
@ -197,26 +252,56 @@ int main(void) {
location = glGetUniformLocation(shaderProgram, "projection");
glUniformMatrix4fv(location, 1, GL_FALSE, projection[0]);
location = glGetUniformLocation(shaderProgram, "spriteColor");
glUniform3f(location, 1.0f, 1.0f, 1.0f);
glUniform1i(glGetUniformLocation(shaderProgram, "image"), 0);
Animation anim = playerAnims[state.currentAnim];
elapsed += deltaTime;
if (elapsed > 0.1f) {
frameCount += 1;
if (frameCount > 9) {
if (frameCount >= anim.cols) {
frameCount = 0;
}
elapsed = 0.0f;
}
location = glGetUniformLocation(shaderProgram, "spriteX");
float spriteX = (float)frameCount / 10;
glUniform1f(location, spriteX);
location = glGetUniformLocation(shaderProgram, "posX");
glUniform1f(location, anim.posX);
location = glGetUniformLocation(shaderProgram, "spriteY");
glUniform1f(location, state.camY);
location = glGetUniformLocation(shaderProgram, "posY");
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);
glBindTexture(GL_TEXTURE_2D, textureID);

View File

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