This commit is contained in:
Joseph Ferano 2023-09-29 22:23:01 +07:00
parent 043ba26281
commit ac0875103d
13 changed files with 383 additions and 161 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
.godot/
/Assets/
/game/tenchu
/game/.idea/

View File

@ -47,84 +47,6 @@ tracks/2/keys = {
"values": [0, 1, 2, 3, 4, 5, 5, 6, 7]
}
[sub_resource type="Animation" id="Animation_1l7dh"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [0]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath(".:texture")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [ExtResource("1_h6xei")]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath(".:hframes")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [10]
}
[sub_resource type="Animation" id="Animation_dl063"]
resource_name = "Walk"
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:texture")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [ExtResource("1_h6xei")]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath(".:hframes")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [8]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath(".:frame")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1),
"update": 1,
"values": [0, 1, 2, 3, 4, 5, 6]
}
[sub_resource type="Animation" id="Animation_2yfkp"]
resource_name = "Jump"
tracks/0/type = "value"
@ -164,6 +86,45 @@ tracks/2/keys = {
"values": [0, 1, 2]
}
[sub_resource type="Animation" id="Animation_1l7dh"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [0]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath(".:texture")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [ExtResource("1_h6xei")]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath(".:hframes")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [10]
}
[sub_resource type="Animation" id="Animation_oejr4"]
resource_name = "Run"
length = 0.75
@ -204,6 +165,45 @@ tracks/2/keys = {
"values": [0, 1, 2, 3, 4, 5, 6, 7]
}
[sub_resource type="Animation" id="Animation_dl063"]
resource_name = "Walk"
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:texture")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [ExtResource("1_h6xei")]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath(".:hframes")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [8]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath(".:frame")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1),
"update": 1,
"values": [0, 1, 2, 3, 4, 5, 6]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_6srtp"]
_data = {
"Idle": SubResource("Animation_vrt4p"),

View File

@ -1,8 +1,8 @@
P=tenchu
OBJECTS=
OBJECTS=-l:libcglm.so
CFLAGS=-g -Wall -Wextra -O0
LDLIBS=-lglfw -lOpenGL
INCLUDES=-I./libs/glad/include/
LDLIBS=-lglfw -lOpenGL -lm
INCLUDES=-Ilibs/glad/include/ -Ilibs/
CC=gcc
RM=rm -vf
@ -18,3 +18,5 @@ run: build
clean:
$(RM) $(P)
.PHONY: all
all: build

View File

@ -19,3 +19,4 @@ gcc -Ilibs/glad/include/ -c libs/glad/src/glad.c
* Terms
VBO - vertex buffer objects
VAO - vertex array object
EBO - element buffer objects

BIN
game/assets/idle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
game/assets/jump.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1021 B

BIN
game/assets/land.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
game/assets/run.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
game/assets/walk.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

117
game/lib.h Normal file
View File

@ -0,0 +1,117 @@
#ifndef TENCHU_LIB_H
#define TENCHU_LIB_H
#include <string.h>
void checkCode(int code, char* errorMsg) {
if (code < 0) {
fprintf(stderr, "Application Error %i: %s\n", code, errorMsg);
exit(1);
}
}
void* checkPtr(void *ptr, char* errorMsg) {
if (ptr == NULL) {
fprintf(stderr, "Application Error: %s\n", errorMsg);
exit(1);
}
return ptr;
}
void checkShader(unsigned int shader, int statusFlag, char* actionName) {
int success;
glGetShaderiv(shader, statusFlag, &success);
if (success < 0) {
fprintf(stderr, "%s Error %i\n", actionName, success);
exit(1);
}
}
char* loadText(char* path) {
char* buffer = NULL;
long length;
FILE* f = fopen(path, "rb");
if (f) {
fseek(f, 0, SEEK_END);
length = ftell(f);
fseek(f, 0, SEEK_SET);
buffer = calloc(length, sizeof(char));
if (buffer) {
fread(buffer, 1, length, f);
}
fclose(f);
}
return buffer;
}
void checkCompileErrors(unsigned int object, char* type)
{
int success;
char infoLog[1024];
if (strcmp("PROGRAM", type))
{
glGetShaderiv(object, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(object, 1024, NULL, infoLog);
fprintf(stderr, "| ERROR::SHADER: Compile-time error: Type: %s \n %s\n", type, infoLog);
}
}
else
{
glGetProgramiv(object, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(object, 1024, NULL, infoLog);
fprintf(stderr, "| ERROR::Shader: Link-time error: Type: %s \n %s\n", type, infoLog);
}
}
}
unsigned int compileShaderProgram(char* vertSrcPath, char* fragSrcPath, char* geoSrcPath) {
unsigned int vertShader, fragShader, geoShader;
char* vertSrc = loadText(vertSrcPath);
vertShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertShader, 1, (const GLchar* const*)&vertSrc, NULL);
glCompileShader(vertShader);
checkCompileErrors(vertShader, "VERTEX");
char* fragSrc = loadText(fragSrcPath);
fragShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragShader, 1, (const GLchar* const*)&fragSrc, NULL);
glCompileShader(fragShader);
checkCompileErrors(fragShader, "FRAGMENT");
char* geoSrc = NULL;
if (geoSrcPath != NULL) {
geoSrc = loadText(geoSrcPath);
geoShader = glCreateShader(GL_GEOMETRY_SHADER);
glShaderSource(geoShader, 1, (const GLchar* const*)&geoSrc, NULL);
glCompileShader(geoShader);
checkCompileErrors(geoShader, "GEOMETRY");
}
unsigned int program = glCreateProgram();
glAttachShader(program, vertShader);
glAttachShader(program, fragShader);
if (geoSrcPath != NULL) {
glAttachShader(program, geoShader);
}
glLinkProgram(program);
checkCompileErrors(program, "PROGRAM");
glDeleteShader(vertShader);
glDeleteShader(fragShader);
free(vertSrc);
free(fragSrc);
if (geoSrc != NULL) {
free(geoSrc);
}
return program;
}
#endif

10
game/shaders/main.frag Normal file
View File

@ -0,0 +1,10 @@
#version 330 core
in vec2 TexCoords;
out vec4 color;
uniform sampler2D image;
uniform vec3 spriteColor;
void main() {
color = vec4(spriteColor, 1.0f) * texture(image, TexCoords);
}

13
game/shaders/main.vert Normal file
View File

@ -0,0 +1,13 @@
#version 330 core
layout (location = 0) in vec4 vertex;
out vec2 TexCoords;
uniform mat4 model;
uniform mat4 projection;
void main() {
TexCoords = vertex.zw;
// gl_Position = model * vec4(vertex.xy, 0.0, 1.0);
gl_Position = projection * model * vec4(vertex.xy, 0.0, 1.0);
}

View File

@ -3,82 +3,62 @@
#include <stdbool.h>
#include "glad/glad.h"
#include <GLFW/glfw3.h>
#include "cglm/cglm.h"
#include "lib.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#define PI 3.14159f
int SCREEN_WIDTH = 1024;
int SCREEN_HEIGHT = 768;
void checkCode(int code, char* errorMsg) {
if (code < 0) {
fprintf(stderr, "Application Error %i: %s\n", code, errorMsg);
exit(1);
}
}
struct State {
float camX;
float camY;
float px;
float py;
};
void* checkPtr(void *ptr, char* errorMsg) {
if (ptr == NULL) {
fprintf(stderr, "Application Error: %s\n", errorMsg);
exit(1);
}
return ptr;
}
void checkShader(unsigned int shader, int statusFlag, char* actionName) {
int success;
glGetShaderiv(shader, statusFlag, &success);
if (success < 0) {
fprintf(stderr, "%s Error %i\n", actionName, success);
exit(1);
}
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
(void)window;
glViewport(0, 0, width, height);
SCREEN_WIDTH = width;
SCREEN_HEIGHT = height;
}
void processInput(GLFWwindow *window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
void processInput(GLFWwindow *window, struct State* state) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
const char* vertSrc =
"#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\n";
unsigned int compileVertShader() {
unsigned int vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertSrc, NULL);
glCompileShader(vertexShader);
checkShader(vertexShader, GL_COMPILE_STATUS, "Vertex Shader");
return vertexShader;
}
const char* fragSrc =
"#version 330 core\n"
"out vec4 FragColor;\n"
"\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n";
unsigned int compileFragShader() {
unsigned int fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragSrc, NULL);
glCompileShader(fragmentShader);
checkShader(fragmentShader, GL_COMPILE_STATUS, "Fragment Shader");
return fragmentShader;
float amount = 1.0f;
if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) {
state->camY -= amount;
}
if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) {
state->camY += amount;
}
if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) {
state->camX -= amount;
}
if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) {
state->camX += amount;
}
amount = 1.1f;
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) {
state->py -= amount;
}
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) {
state->py += amount;
}
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) {
state->px -= amount;
}
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) {
state->px += amount;
}
}
int main(void) {
@ -101,45 +81,143 @@ int main(void) {
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
unsigned int vertexShader = compileVertShader();
unsigned int fragmentShader = compileFragShader();
unsigned int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
checkShader(vertexShader, GL_LINK_STATUS, "Shader Program");
unsigned int shaderProgram =
compileShaderProgram("shaders/main.vert", "shaders/main.frag", NULL);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glEnable(GL_FRAMEBUFFER_SRGB);
glDisable(0x809D);
glEnable(GL_BLEND);
// CHECK: Do we need this?
// glEnable(GL_DEPTH_TEST);
// glDepthFunc(GL_GREATER);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
float vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
// pos // tex
0.0f, 1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 0.0f
};
unsigned int VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(VAO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
mat4 camOrtho;
glm_ortho(0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, -1.0f, 1.0f, camOrtho);
unsigned int textureID;
int width, height, channels;
char* data = (char*)stbi_load("assets/idle.png", &width, &height, &channels, 4);
if (data == NULL) {
fprintf(stderr, "Could not load texture");
return -1;
}
glGenTextures(1, &textureID);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID);
// // set Texture wrap and filter modes
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, data);
stbi_image_free(data);
// glBindTexture(GL_TEXTURE_2D, 0);
// float deltaTime = 0.0f;
// float lastFrame = 0.0f;
struct State state = {0};
while (!glfwWindowShouldClose(window)) {
processInput(window);
float currentFrame = glfwGetTime();
// deltaTime = currentFrame - lastFrame;
// lastFrame = currentFrame;
processInput(window, &state);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
// vec4 vec = {1.0f, 0.0f, 0.0f, 1.0f};
mat4 model;
mat4 projection;
glm_mat4_identity(model);
glm_mat4_identity(projection);
// glm_ortho(0.0f, SCREEN_WIDTH, SCREEN_HEIGHT, 0.0f, -1.0f, 1.0f, projection);
// glm_perspective(60.0f, 3.0f / 4.0f , 1.0f, 200.0f, projection);
// glm_scale(model, (vec3){4.0f, 0.5f, 1.0f});
float pivotx = 0.5f;
float pivoty = 0.5f;
glm_translate(model, (vec3){pivotx, pivoty, 0.0f});
glm_rotate(model, currentFrame, (vec3){0.0f, 0.0f, 1.0f});
glm_scale(model, (vec3){400.0f, 50.0f, 0.0f});
glm_translate(model, (vec3){-pivotx, -pivoty, 0.0f});
// glm_translate(model, (vec3){-255.5f, 0.f, 0.0f});
// glm_translate(model, (vec3){200.0f, 200.0f, 0.0f});
// glm_translate(model, (vec3){-1.8f, -2.0f, 0.0f});
// glm_translate(model, (vec3){-1.8f, -2.0f, 0.0f});
// glm_translate();
// 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;
float hh = (SCREEN_HEIGHT / 2.f) / worldUnitSizeInPixels;
glm_ortho(-hw, hw, hh, -hh, -1.0f, 1.0f, projection);
glm_translate(projection, (vec3){0.0f + state.camX, 0.0f + state.camY, 0.0f});
// float proj = ortho(-hw, hw, -hh, hh, ...);
// // or
// float proj = ortho(-hw, hw, hh, -hh, ...);
mat4 final;
glm_mat4_identity(final);
glm_mat4_mul(final, projection, final);
glm_mat4_mul(final, model, final);
// printf("X:%f Y:%f Z:%f\n", final[3][0], final[3][1], final[3][2]);
GLint location = glGetUniformLocation(shaderProgram, "model");
glUniformMatrix4fv(location, 1, GL_FALSE, model[0]);
location = glGetUniformLocation(shaderProgram, "projection");
glUniformMatrix4fv(location, 1, GL_FALSE, projection[0]);
// glm_mat4_identity(model);
location = glGetUniformLocation(shaderProgram, "spriteColor");
glUniform3f(location, 1.0f, 1.0f, 1.0f);
glUniform1i(glGetUniformLocation(shaderProgram, "image"), 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glDrawArrays(GL_TRIANGLES, 0, 6);
// glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();