Ennix/main.c
2023-10-16 09:23:19 +07:00

228 lines
6.9 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "glad/glad.h"
#include <GLFW/glfw3.h>
#include "cglm/cglm.h"
#include "lib.h"
#include "stb_image.h"
#define PI 3.14159f
int SCREEN_WIDTH = 1024;
int SCREEN_HEIGHT = 768;
typedef struct State {
float camX;
float camY;
float px;
float py;
} State;
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, State* state) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
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) {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window =
checkPtr(glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "2D Engine", NULL, NULL),
"Error creating GLFW window");
if (window == NULL) glfwTerminate();
glfwMakeContextCurrent(window);
checkCode(gladLoadGLLoader((GLADloadproc)glfwGetProcAddress), "Error initializing GLAD");
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
unsigned int shaderProgram =
compileShaderProgram("shaders/main.vert", "shaders/main.frag", NULL);
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[] = {
// 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);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
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;
State state = {0};
int frameCount = 0;
float elapsed = 0.0f;
float lastFrame;
while (!glfwWindowShouldClose(window)) {
float currentFrame = glfwGetTime();
float 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);
float pivotx = 0.5f;
float pivoty = 0.5f;
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;
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});
GLint location = glGetUniformLocation(shaderProgram, "model");
glUniformMatrix4fv(location, 1, GL_FALSE, model[0]);
location = glGetUniformLocation(shaderProgram, "projection");
glUniformMatrix4fv(location, 1, GL_FALSE, projection[0]);
location = glGetUniformLocation(shaderProgram, "spriteColor");
glUniform3f(location, 1.0f, 1.0f, 1.0f);
elapsed += deltaTime;
if (elapsed > 0.1f) {
frameCount += 1;
if (frameCount > 9) {
frameCount = 0;
}
elapsed = 0.0f;
}
location = glGetUniformLocation(shaderProgram, "spriteX");
float spriteX = (float)frameCount / 10;
glUniform1f(location, spriteX);
location = glGetUniformLocation(shaderProgram, "spriteY");
glUniform1f(location, state.py);
glUniform1i(glGetUniformLocation(shaderProgram, "image"), 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
glfwTerminate();
return 0;
}