228 lines
6.9 KiB
C
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;
|
|
}
|