HMN viz jam

This commit is contained in:
Martin Fouilleul 2023-04-14 11:48:36 +02:00
parent 17c0f02962
commit db7fe504bb
7 changed files with 129 additions and 284 deletions

View File

@ -37,7 +37,7 @@ elif [ $target = wasm3 ] ; then
elif [ $target = orca ] ; then elif [ $target = orca ] ; then
echo "building orca" echo "building orca"
# copies libraries # copy libraries
cp milepost/bin/mtl_renderer.metallib bin/ cp milepost/bin/mtl_renderer.metallib bin/
cp milepost/bin/libmilepost.dylib bin/ cp milepost/bin/libmilepost.dylib bin/
cp milepost/bin/libGLESv2.dylib bin/ cp milepost/bin/libGLESv2.dylib bin/
@ -51,6 +51,12 @@ elif [ $target = orca ] ; then
./scripts/bindgen.py core ./src ./scripts/bindgen.py core ./src
./scripts/bindgen.py gles ./src ./scripts/bindgen.py gles ./src
./scripts/bindgen2.py canvas \
src/canvas_api.json \
--guest-stubs sdk/graphics.c \
--guest-include graphics.h \
--wasm3-bindings ./src/canvas_api_bind_gen.c
# compile orca # compile orca
clang $FLAGS $INCLUDES $LIBS -o bin/orca src/main.c clang $FLAGS $INCLUDES $LIBS -o bin/orca src/main.c

View File

@ -6,8 +6,10 @@ wasmFlags="--target=wasm32 \
-Wl,--no-entry \ -Wl,--no-entry \
-Wl,--export-all \ -Wl,--export-all \
-Wl,--allow-undefined \ -Wl,--allow-undefined \
-I ../../sdk" -g \
-D__ORCA__ \
-I ../../sdk -I ../../milepost/src"
/usr/local/opt/llvm/bin/clang $wasmFlags -o ./module.wasm main.c /usr/local/opt/llvm/bin/clang $wasmFlags -o ./module.wasm ../../sdk/graphics.c ../../sdk/orca.c main.c
python3 ../../scripts/mkapp.py --orca-dir ../.. --name Pong --icon icon.png module.wasm #python3 ../../scripts/mkapp.py --orca-dir ../.. --name Pong --icon icon.png module.wasm

View File

@ -6,16 +6,11 @@
* @revision: * @revision:
* *
*****************************************************************/ *****************************************************************/
#include"typedefs.h"
#include"keys.h"
#include"macro_helpers.h"
#include"GLES3/gl32.h"
typedef struct str8 #include"keys.h"
{ #include"graphics.h"
unsigned long long len;
char* ptr; #include"orca.h"
} str8;
#define str8_lit(s) ((str8){.len = sizeof(s)-1, .ptr = (char*)(s)}) #define str8_lit(s) ((str8){.len = sizeof(s)-1, .ptr = (char*)(s)})
@ -31,69 +26,10 @@ void log_string(str8 string)
log_string_flat(string.len, string.ptr); log_string_flat(string.len, string.ptr);
} }
unsigned int program; const g_color paddleColor = {1, 0, 0, 1};
const char* vshaderSource =
"#version 300 es\n"
"precision mediump float;"
"layout(location=0) in vec4 vPosition;\n"
"layout(location=1) in vec4 aColor;\n"
"out vec4 vColor;\n"
"uniform mat4 transform;\n"
"void main()\n"
"{\n"
" gl_Position = transform*vPosition;\n"
" vColor = aColor;\n"
"}\n";
const char* fshaderSource =
"#version 300 es\n"
"precision mediump float;\n"
"out vec4 fragColor;\n"
"in vec4 vColor;\n"
"void main()\n"
"{\n"
" fragColor = vColor;\n"
"}\n";
void compile_shader(GLuint shader, const char* source)
{
glShaderSource(shader, 1, &source, 0);
glCompileShader(shader);
GLint success = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if(success == GL_FALSE)
{
char message[1024];
int length = 0;
glGetShaderInfoLog(shader, 1024, &length, message);
log_string(str8_lit("gl shader error: \n"));
log_string_flat(length, message);
}
}
void OnInit(void)
{
//log_string(str8_lit("init procedure\n"));
unsigned int vshader = glCreateShader(GL_VERTEX_SHADER);
unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram();
compile_shader(vshader, vshaderSource);
compile_shader(fshader, fshaderSource);
glAttachShader(program, vshader);
glAttachShader(program, fshader);
glLinkProgram(program);
glUseProgram(program);
}
const vec4 paddleColor = {1, 0, 0, 1};
mp_rect paddle = {200, 40, 200, 40}; mp_rect paddle = {200, 40, 200, 40};
const vec4 ballColor = {1, 1, 0, 1}; const g_color ballColor = {1, 1, 0, 1};
mp_rect ball = {200, 200, 60, 60}; mp_rect ball = {200, 200, 60, 60};
vec2 velocity = {10, 10}; vec2 velocity = {10, 10};
@ -104,6 +40,14 @@ float rotationDir = 1;
bool leftDown = false; bool leftDown = false;
bool rightDown = false; bool rightDown = false;
g_font font;
void OnInit(void)
{
font = g_font_create_default();
//log_string(str8_lit("init procedure\n"));
}
void OnFrameResize(u32 width, u32 height) void OnFrameResize(u32 width, u32 height)
{ {
log_string(str8_lit("frame resize ")); log_string(str8_lit("frame resize "));
@ -113,10 +57,11 @@ void OnFrameResize(u32 width, u32 height)
frameSize.x = width; frameSize.x = width;
frameSize.y = height; frameSize.y = height;
/*
paddle.x = width/2. - paddle.w/2.; paddle.x = width/2. - paddle.w/2.;
ball.x = width/2. - ball.w/2.; ball.x = width/2. - ball.w/2.;
ball.y = height/2. - ball.h/2.; ball.y = height/2. - ball.h/2.;
*/
} }
void OnMouseDown(int button) void OnMouseDown(int button)
@ -148,82 +93,12 @@ void OnKeyUp(int key)
} }
} }
void debug_draw_rotating_triangle()
{
static float alpha = 0;
f32 aspect = frameSize.x/frameSize.y;
GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0,
-sinf(alpha)/aspect, cosf(alpha), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1};
alpha += rotationDir*2*M_PI/120;
glUniformMatrix4fv(0, 1, false, matrix);
GLfloat vertices[] = {
-0.866/2, -0.5/2, 0,
0.866/2, -0.5/2, 0,
0, 0.5, 0};
GLfloat colors[] = {
1, 0, 0, 1,
0, 1, 0, 1,
0, 0, 1, 1};
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, colors);
glEnableVertexAttribArray(1);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
void draw_rect(mp_rect rect, vec4 color)
{
GLfloat vertices[6*3] = {
rect.x, rect.y, 0,
rect.x, rect.y + rect.h, 0,
rect.x+rect.w, rect.y + rect.h, 0,
rect.x, rect.y, 0,
rect.x+rect.w, rect.y + rect.h, 0,
rect.x+rect.w, rect.y, 0};
GLfloat colors[6*4];
for(int i=0; i<6*4; i+=4)
{
colors[i] = color.x;
colors[i+1] = color.y;
colors[i+2] = color.z;
colors[i+3] = color.w;
}
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, colors);
glEnableVertexAttribArray(1);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
void OnFrameRefresh(void) void OnFrameRefresh(void)
{ {
//log_string(str8_lit("frame procedure\n")); //log_string(str8_lit("frame procedure\n"));
glClearColor(0, 1, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
f32 aspect = frameSize.x/frameSize.y; f32 aspect = frameSize.x/frameSize.y;
GLfloat matrix[] = {2./frameSize.x, 0, 0, 0,
0, 2./frameSize.y, 0, 0,
0, 0, 1, 0,
-1, -1, 0, 1};
glUniformMatrix4fv(0, 1, false, matrix);
if(leftDown) if(leftDown)
{ {
paddle.x -= 10; paddle.x -= 10;
@ -267,6 +142,30 @@ void OnFrameRefresh(void)
ball.y = frameSize.y/2. - ball.h; ball.y = frameSize.y/2. - ball.h;
} }
draw_rect(paddle, paddleColor); g_set_color_rgba(0, 1, 1, 1);
draw_rect(ball, ballColor); g_clear();
g_mat2x3 transform = {1, 0, 0,
0, -1, frameSize.y};
g_matrix_push(transform);
g_set_color(paddleColor);
g_rectangle_fill(paddle.x, paddle.y, paddle.w, paddle.h);
g_set_color(ballColor);
g_circle_fill(ball.x+ball.w/2, ball.y + ball.w/2, ball.w/2.);
g_set_font(font);
g_set_font_size(16);
g_set_color_rgba(0, 0, 0, 1);
g_set_text_flip(true);
str8 str = {.len = 13, .ptr = (char*)"Hello, world!"};
g_move_to(10, 10);
g_text_outlines(str);
g_fill();
g_matrix_pop();
} }

View File

@ -20,7 +20,10 @@ outFile = open(outPath, 'w')
stubs = [] stubs = []
links = [] links = []
def gen_stub(name, sig): def gen_stub(name, sig, native_name):
if native_name == None:
native_name = name
src = 'const void* ' + name + '_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t * _sp, void * _mem)\n' src = 'const void* ' + name + '_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t * _sp, void * _mem)\n'
src += '{\n' src += '{\n'
spIndex = 0 spIndex = 0
@ -56,7 +59,7 @@ def gen_stub(name, sig):
print('returning pointers is not supported yet\n') print('returning pointers is not supported yet\n')
break break
else: else:
print('unrecognized type ' + c + ' in procedure signature\n') print('unrecognized type ' + c + ' in procedure return\n')
break break
retCount += 1 retCount += 1
else: else:
@ -83,7 +86,7 @@ def gen_stub(name, sig):
argString += ', ' argString += ', '
argCount += 1 argCount += 1
src += '\t' + retString + name + '(' + argString + ');\n' src += '\t' + retString + native_name + '(' + argString + ');\n'
src += '\treturn(0);\n' src += '\treturn(0);\n'
src += '}\n' src += '}\n'
stubs.append(src) stubs.append(src)
@ -104,7 +107,8 @@ for line in inFile:
if line.isspace(): if line.isspace():
continue continue
desc = line.split() desc = line.split()
gen_stub(desc[0], desc[1])
gen_stub(desc[0], desc[1], desc[2] if len(desc) > 2 else None)
gen_link(desc[0], desc[1]) gen_link(desc[0], desc[1])
linkProc = 'int bindgen_link_' + apiName + '_api(IM3Module module)\n' linkProc = 'int bindgen_link_' + apiName + '_api(IM3Module module)\n'

View File

@ -76,6 +76,7 @@ if args.res_dirs != None:
for res in args.res_dirs: for res in args.res_dirs:
shutil.copytree(res, res_dir) shutil.copytree(res, res_dir)
shutil.copy(args.orca_dir + '/resources/OpenSansLatinSubset.ttf', res_dir)
#----------------------------------------------------------- #-----------------------------------------------------------
#NOTE make icon #NOTE make icon
#----------------------------------------------------------- #-----------------------------------------------------------

View File

@ -1,129 +0,0 @@
/************************************************************//**
*
* @file: macro_helpers.h
* @author: Martin Fouilleul
* @date: 27/03/2020
* @revision:
*
*****************************************************************/
#ifndef __MACRO_HELPERS_H_
#define __MACRO_HELPERS_H_
//NOTE(martin): macro concatenation
#define _cat2_(a, b) a##b
#define _cat3_(a, b, c) a##b##c
//NOTE(martin): inline, but still generate code
// (eg. use the inline version inside a library, but still exports the function for client code)
//TODO(martin): this is a compiler-specific attribute, recognized by clang and gcc. See if there's a more portable approach
//#define INLINE_GEN __attribute__((used)) static inline
//NOTE(martin): typed and array mallocs
#define malloc_type(type) ((type*)malloc(sizeof(type)))
#define malloc_array(type, count) ((type*)malloc(sizeof(type)*count))
//NOTE(martin): 'hygienic' templates, to replace macros and avoid multiple evaluation problems.
#ifdef __cplusplus
//NOTE(martin): in C++ we use templates and decltype/declval
// (overloaded functions would be ambiguous because of the
// overload resolution and conversion/promotion rules)
#include<utility>
template<typename Ta, typename Tb>
inline decltype(std::declval<Ta>()+std::declval<Tb>()) minimum_safe(Ta a, Tb b)
{
return(a < b ? a : b);
}
template<typename Ta, typename Tb>
inline decltype(std::declval<Ta>()+std::declval<Tb>()) maximum_safe(Ta a, Tb b)
{
return(a > b ? a : b);
}
template<typename T>
inline T square_safe(T a) {return(a*a);}
template<typename T>
inline T cube_safe(T a) {return(a*a*a);}
#else // (__cplusplus not defined)
//NOTE(martin): Type generic arithmetic functions helpers
// this macros helps generate variants of a generic 'template' for all arithmetic types.
// the def parameter must be a macro that take a type, and optional arguments
#define tga_generate_variants(def, ...) \
def(u8, ##__VA_ARGS__) def(i8, ##__VA_ARGS__ ) def(u16, ##__VA_ARGS__) def(i16, ##__VA_ARGS__) \
def(u32, ##__VA_ARGS__) def(i32, ##__VA_ARGS__) def(u64, ##__VA_ARGS__) def(i64, ##__VA_ARGS__) \
def(f32, ##__VA_ARGS__) def(f64, ##__VA_ARGS__)
// This macro generates the name of a typed variant
#define tga_variant_name(name, type) _cat3_(name, _, type)
// This macro generates a _Generic association between a type and its variant
#define tga_variant_association(type, name) , type: tga_variant_name(name, type)
// This macros selects the appropriate variant for a 2 parameters functions
#define tga_select_binary(name, a, b) \
_Generic((a+b) tga_generate_variants(tga_variant_association, name))(a, b)
// This macros selects the appropriate variant for a 1 parameters functions
#define tga_select_unary(name, a) \
_Generic((a) tga_generate_variants(tga_variant_association, name))(a)
//NOTE(martin): type generic templates
#define minimum_def(type) static inline type tga_variant_name(minimum_safe, type)(type a, type b) {return(a < b ? a : b);}
#define maximum_def(type) static inline type tga_variant_name(maximum_safe, type)(type a, type b) {return(a > b ? a : b);}
#define square_def(type) static inline type tga_variant_name(square_safe, type)(type a) {return(a*a);}
#define cube_def(type) static inline type tga_variant_name(cube_safe, type)(type a) {return(a*a*a);}
//NOTE(martin): instantiante our templates for all arithmetic types
tga_generate_variants(minimum_def)
tga_generate_variants(maximum_def)
tga_generate_variants(square_def)
tga_generate_variants(cube_def)
//NOTE(martin): select the correct variant according to the argument types
#define minimum_safe(a, b) tga_select_binary(minimum_safe, a, b)
#define maximum_safe(a, b) tga_select_binary(maximum_safe, a, b)
#define square_safe(a) tga_select_unary(square_safe, a)
#define cube_safe(a) tga_select_unary(cube_safe, a)
#endif // __cplusplus else branch
//NOTE(martin): these macros are calling the safe functions defined above, so they don't evaluate their
// arguments twice
#define minimum(a, b) minimum_safe(a, b)
#define maximum(a, b) maximum_safe(a, b)
#define ClampLowBound(a, low) (maximum((a), (low)))
#define ClampHighBound(a, high) (minimum((a), (high)))
#define Clamp(a, low, high) (ClampLowBound(ClampHighBound((a), (high)), (low)))
#define Square(a) square_safe(a)
#define Cube(a) cube_safe(a)
#define AlignUpOnPow2(x, a) (((x) + (a) - 1) & ~((a)-1))
#define AlignDownOnPow2(x, a) ((x) & ~((a)-1))
static inline u64 next_pow2_u64(u64 x)
{
x--;
x |= x>>1;
x |= x>>2;
x |= x>>4;
x |= x>>8;
x |= x>>16;
x |= x>>32;
x++;
return(x);
}
#define defer_loop(begin, end) begin; for(int __i__=0; __i__<1; __i__++, end)
#endif //__MACRO_HELPERS_H_

View File

@ -6,6 +6,7 @@
* *
*****************************************************************/ *****************************************************************/
#include<stdio.h> #include<stdio.h>
#include<errno.h>
#include<pthread.h> #include<pthread.h>
#include<math.h> #include<math.h>
@ -29,7 +30,48 @@ void log_int(int i)
printf("%i ", i); printf("%i ", i);
} }
void mg_matrix_push_flat(float a11, float a12, float a13,
float a21, float a22, float a23)
{
mg_mat2x3 m = {a11, a12, a13, a21, a22, a23};
mg_matrix_push(m);
}
mg_font mg_font_create_default()
{
//NOTE(martin): create default font
str8 fontPath = mp_app_get_resource_path(mem_scratch(), "../resources/OpenSansLatinSubset.ttf");
char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath);
FILE* fontFile = fopen(fontPathCString, "r");
if(!fontFile)
{
LOG_ERROR("Could not load font file '%s': %s\n", fontPathCString, strerror(errno));
return(mg_font_nil());
}
unsigned char* fontData = 0;
fseek(fontFile, 0, SEEK_END);
u32 fontDataSize = ftell(fontFile);
rewind(fontFile);
fontData = (unsigned char*)malloc(fontDataSize);
fread(fontData, 1, fontDataSize, fontFile);
fclose(fontFile);
unicode_range ranges[5] = {UNICODE_RANGE_BASIC_LATIN,
UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT,
UNICODE_RANGE_LATIN_EXTENDED_A,
UNICODE_RANGE_LATIN_EXTENDED_B,
UNICODE_RANGE_SPECIALS};
mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges);
free(fontData);
return(font);
}
#include"bindgen_core_api.c" #include"bindgen_core_api.c"
#include"canvas_api_bind.c"
#include"bindgen_gles_api.c" #include"bindgen_gles_api.c"
#include"manual_gles_api.c" #include"manual_gles_api.c"
@ -37,6 +79,7 @@ typedef struct orca_app
{ {
mp_window window; mp_window window;
mg_surface surface; mg_surface surface;
mg_surface mtlSurface;
mg_canvas canvas; mg_canvas canvas;
} orca_app; } orca_app;
@ -188,6 +231,7 @@ void* orca_runloop(void* user)
//NOTE: bind orca APIs //NOTE: bind orca APIs
bindgen_link_core_api(module); bindgen_link_core_api(module);
bindgen_link_canvas_api(module);
bindgen_link_gles_api(module); bindgen_link_gles_api(module);
manual_link_gles_api(module); manual_link_gles_api(module);
@ -319,7 +363,9 @@ void* orca_runloop(void* user)
case MP_EVENT_WINDOW_RESIZE: case MP_EVENT_WINDOW_RESIZE:
{ {
//TODO: resize surface! mp_rect frame = {0, 0, event.frame.rect.w, event.frame.rect.h};
mg_surface_set_frame(app->surface, frame);
if(eventHandlers[G_EVENT_FRAME_RESIZE]) if(eventHandlers[G_EVENT_FRAME_RESIZE])
{ {
u32 width = (u32)event.frame.rect.w; u32 width = (u32)event.frame.rect.w;
@ -385,7 +431,7 @@ void* orca_runloop(void* user)
} }
} }
mg_surface_prepare(app->surface); /* mg_surface_prepare(app->surface);
glClearColor(1, 0, 1, 1); glClearColor(1, 0, 1, 1);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
@ -395,6 +441,17 @@ void* orca_runloop(void* user)
} }
mg_surface_present(app->surface); mg_surface_present(app->surface);
*/
mg_canvas_prepare(app->canvas);
if(eventHandlers[G_EVENT_FRAME_REFRESH])
{
m3_Call(eventHandlers[G_EVENT_FRAME_REFRESH], 0, 0);
}
mg_present();
//TODO: update and render //TODO: update and render
mem_scratch_clear(); mem_scratch_clear();
} }
@ -427,9 +484,14 @@ int main(int argc, char** argv)
mp_window_bring_to_front(window); mp_window_bring_to_front(window);
mp_window_focus(window); mp_window_focus(window);
mg_surface mtlSurface = mg_surface_create_for_window(window, MG_BACKEND_DEFAULT);
mg_surface_swap_interval(mtlSurface, 1);
mg_canvas canvas = mg_canvas_create(mtlSurface);
orca_app app = {.window = window, orca_app app = {.window = window,
.surface = surface}; .surface = surface,
// .canvas = canvas}; .mtlSurface = mtlSurface,
.canvas = canvas};
pthread_t runloopThread; pthread_t runloopThread;
pthread_create(&runloopThread, 0, orca_runloop, &app); pthread_create(&runloopThread, 0, orca_runloop, &app);