feat: web export

This commit is contained in:
orangerot 2025-10-14 08:21:09 +02:00
parent 2d359fb932
commit 1be303f6f6
3 changed files with 72 additions and 52 deletions

View file

@ -1,7 +1,9 @@
CFLAGS := -Wall -Wextra CFLAGS := -Wall -Wextra
LDFLAGS = -lglfw -lm -lGL -I./glad/include LDFLAGS = -lglfw -lm -lGL -I./glad/include
domino-dungeon: main.c game.c game.h glad/src/glad.c assets/dominos.h SOURCES = main.c game.c game.h glad/src/glad.c assets/dominos.h
domino-dungeon: ${SOURCES}
$(CC) ${CFLAGS} ${LDFLAGS} -o $@ $^ $(CC) ${CFLAGS} ${LDFLAGS} -o $@ $^
assets/dominos.h: src_build/domino_assets assets/dominos.h: src_build/domino_assets
@ -10,3 +12,7 @@ assets/dominos.h: src_build/domino_assets
src_build/domino_assets: src_build/domino_assets.c src_build/domino_assets: src_build/domino_assets.c
$(CC) -o $@ $^ -lm $(CC) -o $@ $^ -lm
# https://gist.github.com/ousttrue/0f3a11d5d28e365b129fe08f18f4e141
domino-dungeon.html: ${SOURCES}
emcc -sUSE_WEBGL2=1 -sUSE_GLFW=3 -sWASM=1 -I./glad/include $(filter %.c,$^) -o $@

3
game.c
View file

@ -1,4 +1,3 @@
#include <glad/glad.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
@ -40,7 +39,7 @@ void mouse_button_callback(int button, int action, int mods) {
} }
void draw_image(decoded_image img) { void draw_image(decoded_image img) {
// for (int i = 0; i < img.buf_size; i++) img.buf[i] = i; for (int i = 0; i < img.buf_size; i++) img.buf[i] = i;
for (int y = 0; y < DOMINO_HEIGHT; y++) { for (int y = 0; y < DOMINO_HEIGHT; y++) {
for (int x = 0; x < DOMINO_WIDTH; x++) { for (int x = 0; x < DOMINO_WIDTH; x++) {

113
main.c
View file

@ -4,26 +4,37 @@
#include <glad/glad.h> #include <glad/glad.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <math.h> #include <math.h>
#include <stdlib.h>
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
#include "game.h" #include "game.h"
unsigned int SCR_WIDTH = 800; unsigned int SCR_WIDTH = 800;
unsigned int SCR_HEIGHT = 600; unsigned int SCR_HEIGHT = 600;
GLFWwindow* window;
unsigned int texture;
GLuint shader_program;
unsigned int VAO;
extern void key_callback(int key, int scancode, int action, int mods); extern void key_callback(int key, int scancode, int action, int mods);
extern void cursor_position_callback(int xpos, int ypos); extern void cursor_position_callback(int xpos, int ypos);
extern void mouse_button_callback(int button, int action, int mods); extern void mouse_button_callback(int button, int action, int mods);
extern void draw_image(decoded_image img); extern void draw_image(decoded_image img);
uint32_t buffer[256 * 240] = {0};
struct decoded_image canvas = { struct decoded_image canvas = {
.width = 256, .width = 256,
.height = 240, .height = 240,
.buf_size = 256 * 240, .buf_size = 256 * 240,
.buf = buffer,
}; };
const char *vertex_shader_source = const char *vertex_shader_source =
"#version 330 core\n" "#version 300 es\n"
"layout (location = 0) in vec3 aPos;\n" "layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec3 aColor;\n" "layout (location = 1) in vec3 aColor;\n"
"layout (location = 2) in vec2 aTexCoord;\n" "layout (location = 2) in vec2 aTexCoord;\n"
@ -40,7 +51,8 @@ const char *vertex_shader_source =
"}\n"; "}\n";
const char *fragment_shader_source = const char *fragment_shader_source =
"#version 330 core\n" "#version 300 es\n"
"precision mediump float;\n"
"out vec4 FragColor;\n" "out vec4 FragColor;\n"
"\n" "\n"
"in vec3 ourColor;\n" "in vec3 ourColor;\n"
@ -89,9 +101,47 @@ void glfw_mouse_button_callback(GLFWwindow* window, int button, int action, int
mouse_button_callback(button, action, mods); mouse_button_callback(button, action, mods);
} }
int main() { void loop() {
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, 1);
canvas.buf = malloc(canvas.buf_size * sizeof(int)); glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
draw_image(canvas);
// bind textures on corresponding texture units
glActiveTexture(GL_TEXTURE);
glBindTexture(GL_TEXTURE_2D, texture);
float scale_x = fmin(
(float) SCR_HEIGHT / SCR_WIDTH * (float) canvas.height / canvas.width,
1.0
);
float scale_y = fmin((float) SCR_WIDTH / SCR_HEIGHT * (float) canvas.width / canvas.height,
1.0
);
float m[] = {
2.0 * scale_x, 0.0, 0.0, 0.0,
0.0, 2.0 * scale_y, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
};
// render container
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, canvas.width, canvas.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, canvas.buf);
glUseProgram(shader_program);
glUniform1i(glGetUniformLocation(shader_program, "texture1"), 0);
glUniformMatrix4fv(glGetUniformLocation(shader_program, "transform"), 1, GL_FALSE, m);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
int main() {
glfwInit(); glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
@ -102,7 +152,7 @@ int main() {
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif #endif
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "202-anything", NULL, NULL); window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "202-anything", NULL, NULL);
if (window == NULL) { if (window == NULL) {
printf("Failed to create GLFW window\n"); printf("Failed to create GLFW window\n");
glfwTerminate(); glfwTerminate();
@ -146,7 +196,7 @@ int main() {
return 1; return 1;
} }
GLuint shader_program = glCreateProgram(); shader_program = glCreateProgram();
glAttachShader(shader_program, vertex_shader); glAttachShader(shader_program, vertex_shader);
glAttachShader(shader_program, fragment_shader); glAttachShader(shader_program, fragment_shader);
glLinkProgram(shader_program); glLinkProgram(shader_program);
@ -162,7 +212,7 @@ int main() {
0, 1, 3, // first triangle 0, 1, 3, // first triangle
1, 2, 3 // second triangle 1, 2, 3 // second triangle
}; };
unsigned int VBO, VAO, EBO; unsigned int VBO, EBO;
glGenVertexArrays(1, &VAO); glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO); glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO); glGenBuffers(1, &EBO);
@ -185,7 +235,6 @@ int main() {
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float))); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2); glEnableVertexAttribArray(2);
unsigned int texture;
// texture 1 // texture 1
// --------- // ---------
glGenTextures(1, &texture); glGenTextures(1, &texture);
@ -202,46 +251,12 @@ int main() {
glUseProgram(shader_program); glUseProgram(shader_program);
glUniform1i(glGetUniformLocation(shader_program, "texture1"), 0); glUniform1i(glGetUniformLocation(shader_program, "texture1"), 0);
while (!glfwWindowShouldClose(window)) { #ifdef __EMSCRIPTEN__
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) emscripten_set_main_loop(loop, 0, true);
glfwSetWindowShouldClose(window, 1); #else
while (!glfwWindowShouldClose(window))
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); loop();
glClear(GL_COLOR_BUFFER_BIT); #endif
draw_image(canvas);
// bind textures on corresponding texture units
glActiveTexture(GL_TEXTURE);
glBindTexture(GL_TEXTURE_2D, texture);
float scale_x = fmin(
(float) SCR_HEIGHT / SCR_WIDTH * (float) canvas.height / canvas.width,
1.0
);
float scale_y = fmin((float) SCR_WIDTH / SCR_HEIGHT * (float) canvas.width / canvas.height,
1.0
);
float m[] = {
2.0 * scale_x, 0.0, 0.0, 0.0,
0.0, 2.0 * scale_y, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
};
// render container
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, canvas.width, canvas.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, canvas.buf);
glUseProgram(shader_program);
glUniform1i(glGetUniformLocation(shader_program, "texture1"), 0);
glUniformMatrix4fv(glGetUniformLocation(shader_program, "transform"), 1, GL_FALSE, m);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate(); glfwTerminate();