- Restructure osx version to use mp_app_internal.h/mp_app.c

- test new run loop structure on osx
This commit is contained in:
Martin Fouilleul 2022-12-24 15:33:32 +01:00
parent 72338b1a25
commit db5b4966e9
14 changed files with 610 additions and 733 deletions

1
.gitignore vendored
View File

@ -1,4 +1,5 @@
.DS_Store
*.dSYM
bin/*
*.metallib

View File

@ -0,0 +1,2 @@
set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext
cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib user32.lib opengl32.lib gdi32.lib /out:test.exe

11
examples/glTriangle/build.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
BINDIR=../../bin
RESDIR=../../resources
SRCDIR=../../src
INCLUDES="-I$SRCDIR -I$SRCDIR/util -I$SRCDIR/platform -I$SRCDIR/app"
LIBS="-L$BINDIR -lmilepost -framework Carbon -framework Cocoa -framework Metal -framework QuartzCore"
FLAGS="-mmacos-version-min=10.15.4 -DDEBUG -DLOG_COMPILE_DEBUG"
clang -g $FLAGS $LIBS $INCLUDES -o test main.c

227
examples/glTriangle/main.c Normal file
View File

@ -0,0 +1,227 @@
/************************************************************//**
*
* @file: main.cpp
* @author: Martin Fouilleul
* @date: 30/07/2022
* @revision:
*
*****************************************************************/
#include<stdlib.h>
#include<string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h>
#include"milepost.h"
#define LOG_SUBSYSTEM "Main"
unsigned int program;
const char* vshaderSource =
"#version 430\n"
"attribute vec4 vPosition;\n"
"uniform mat4 transform;\n"
"void main()\n"
"{\n"
" gl_Position = transform*vPosition;\n"
"}\n";
const char* fshaderSource =
"#version 430\n"
"precision mediump float;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
void compile_shader(GLuint shader, const char* source)
{
glShaderSource(shader, 1, &source, 0);
glCompileShader(shader);
int err = glGetError();
if(err)
{
printf("gl error: %i\n", err);
}
int status = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetShaderInfoLog(shader, 256, &size, buffer);
printf("shader error: %.*s\n", size, buffer);
}
}
int main()
{
LogLevel(LOG_LEVEL_DEBUG);
mp_init();
mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600};
mp_window window = mp_window_create(rect, "test", 0);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_BACKEND_GL);
//NOTE: init shader and gl state
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
GLfloat vertices[] = {
-0.866/2, -0.5/2, 0, 0.866/2, -0.5/2, 0, 0, 0.5, 0};
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
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);
int status = 0;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetProgramInfoLog(program, 256, &size, buffer);
printf("link error: %.*s\n", size, buffer);
}
glUseProgram(program);
mp_window_bring_to_front(window);
// mp_window_focus(window);
while(!mp_should_quit())
{
mp_pump_events(0);
mp_event event = {0};
while(mp_next_event(&event))
{
switch(event.type)
{
case MP_EVENT_WINDOW_CLOSE:
{
mp_request_quit();
} break;
case MP_EVENT_WINDOW_RESIZE:
{
printf("resized, rect = {%f, %f, %f, %f}\n",
event.frame.rect.x,
event.frame.rect.y,
event.frame.rect.w,
event.frame.rect.h);
} break;
case MP_EVENT_WINDOW_MOVE:
{
printf("moved, rect = {%f, %f, %f, %f}\n",
event.frame.rect.x,
event.frame.rect.y,
event.frame.rect.w,
event.frame.rect.h);
} break;
case MP_EVENT_MOUSE_MOVE:
{
printf("mouse moved, pos = {%f, %f}, delta = {%f, %f}\n",
event.move.x,
event.move.y,
event.move.deltaX,
event.move.deltaY);
} break;
case MP_EVENT_MOUSE_WHEEL:
{
printf("mouse wheel, delta = {%f, %f}\n",
event.move.deltaX,
event.move.deltaY);
} break;
case MP_EVENT_MOUSE_ENTER:
{
printf("mouse enter\n");
} break;
case MP_EVENT_MOUSE_LEAVE:
{
printf("mouse leave\n");
} break;
case MP_EVENT_MOUSE_BUTTON:
{
printf("mouse button %i: %i\n",
event.key.code,
event.key.action == MP_KEY_PRESS ? 1 : 0);
} break;
case MP_EVENT_KEYBOARD_KEY:
{
printf("key %i: %s\n",
event.key.code,
event.key.action == MP_KEY_PRESS ? "press" : (event.key.action == MP_KEY_RELEASE ? "release" : "repeat"));
} break;
case MP_EVENT_KEYBOARD_CHAR:
{
printf("entered char %s\n", event.character.sequence);
} break;
default:
break;
}
}
mg_surface_prepare(surface);
glClearColor(0.3, 0.3, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
static float alpha = 0;
//f32 aspect = frameSize.x/frameSize.y;
f32 aspect = 800/(f32)600;
glViewport(0, 0, 800, 600);
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 += 2*M_PI/120;
glUniformMatrix4fv(0, 1, false, matrix);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
mg_surface_present(surface);
}
mp_terminate();
return(0);
}

View File

@ -9,54 +9,10 @@
#include<stdlib.h>
#include<string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include<math.h>
#include"milepost.h"
#define LOG_SUBSYSTEM "Main"
unsigned int program;
const char* vshaderSource =
"#version 430\n"
"attribute vec4 vPosition;\n"
"uniform mat4 transform;\n"
"void main()\n"
"{\n"
" gl_Position = transform*vPosition;\n"
"}\n";
const char* fshaderSource =
"#version 430\n"
"precision mediump float;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
void compile_shader(GLuint shader, const char* source)
{
glShaderSource(shader, 1, &source, 0);
glCompileShader(shader);
int err = glGetError();
if(err)
{
printf("gl error: %i\n", err);
}
int status = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetShaderInfoLog(shader, 256, &size, buffer);
printf("shader error: %.*s\n", size, buffer);
}
}
int main()
{
LogLevel(LOG_LEVEL_DEBUG);
@ -66,49 +22,8 @@ int main()
mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600};
mp_window window = mp_window_create(rect, "test", 0);
//NOTE: create surface
mg_surface surface = mg_surface_create_for_window(window, MG_BACKEND_GL);
//NOTE: init shader and gl state
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
GLfloat vertices[] = {
-0.866/2, -0.5/2, 0, 0.866/2, -0.5/2, 0, 0, 0.5, 0};
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
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);
int status = 0;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetProgramInfoLog(program, 256, &size, buffer);
printf("link error: %.*s\n", size, buffer);
}
glUseProgram(program);
mp_window_bring_to_front(window);
// mp_window_focus(window);
mp_window_focus(window);
while(!mp_should_quit())
{
@ -190,35 +105,6 @@ int main()
break;
}
}
mg_surface_prepare(surface);
glClearColor(0.3, 0.3, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
static float alpha = 0;
//f32 aspect = frameSize.x/frameSize.y;
f32 aspect = 800/(f32)600;
glViewport(0, 0, 800, 600);
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 += 2*M_PI/120;
glUniformMatrix4fv(0, 1, false, matrix);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
mg_surface_present(surface);
}
mp_terminate();

View File

@ -355,6 +355,11 @@ mg_surface mg_surface_nil()
return((mg_surface){.h = 0});
}
bool mg_surface_is_nil(mg_surface surface)
{
return(surface.h == 0);
}
mg_surface mg_surface_alloc_handle(mg_surface_info* surface)
{
mg_resource_slot* slot = mg_resource_slot_alloc(&__mgInfo.surfaces);

View File

@ -31,6 +31,7 @@ typedef enum { MG_BACKEND_DUMMY,
void mg_init();
mg_surface mg_surface_nil();
bool mg_surface_is_nil(mg_surface surface);
mg_surface mg_surface_create_for_window(mp_window window, mg_backend_id backend);
mg_surface mg_surface_create_for_view(mp_view view, mg_backend_id backend);
mg_surface mg_surface_create_offscreen(mg_backend_id backend, u32 width, u32 height);

View File

@ -259,7 +259,7 @@ mg_surface mg_metal_surface_create_for_window(mp_window window)
}
else
{
return(mg_metal_surface_create_for_view(windowData->mainView));
return(mg_metal_surface_create_for_view(windowData->osx.mainView));
}
}

View File

@ -207,7 +207,7 @@ typedef enum {
typedef struct mp_key_event // keyboard and mouse buttons input
{
mp_key_action action;
mp_key_code code;
i32 code;
mp_key_mods mods;
char label[8];
u8 labelLen;

View File

@ -136,6 +136,9 @@ typedef struct mp_app
mp_window_data windowPool[MP_APP_MAX_WINDOWS];
list_info windowFreeList;
mp_live_resize_callback liveResizeCallback;
void* liveResizeData;
mp_input_state inputState;
mp_key_utf8 keyLabels[256];

View File

@ -9,29 +9,32 @@
#ifndef __OSX_APP_H_
#define __OSX_APP_H_
#import<Cocoa/Cocoa.h>
#import<Carbon/Carbon.h>
#include"mp_app.h"
#include"graphics.h"
typedef struct mp_window_data
{
list_elt freeListElt;
u32 generation;
#ifdef __OBJC__
#import<Cocoa/Cocoa.h>
#else
#define NSWindow void
#define NSView void
#define NSObject void
#define NSTimer void
#define NSCursor void
#endif
#include<Carbon/Carbon.h>
typedef struct osx_window_data
{
NSWindow* nsWindow;
NSView* nsView;
NSObject* nsWindowDelegate;
mp_rect contentRect;
mp_rect frameRect;
mp_window_style style;
bool shouldClose; //TODO could be in status flags
bool hidden;
mp_view mainView;
} mp_window_data;
} osx_window_data;
#define MP_PLATFORM_WINDOW_DATA osx_window_data osx;
typedef struct mp_view_data
{
@ -43,15 +46,23 @@ typedef struct mp_view_data
mg_surface surface;
} mp_view_data;
@interface MPNativeWindow : NSWindow
{
mp_window_data* mpWindow;
}
- (id)initWithMPWindow:(mp_window_data*) window contentRect:(NSRect) rect styleMask:(uint32) style;
@end
const u32 MP_APP_MAX_VIEWS = 128;
mp_window_data* mp_window_ptr_from_handle(mp_window handle);
mp_view_data* mp_view_ptr_from_handle(mp_view handle);
typedef struct osx_app_data
{
NSTimer* frameTimer;
NSCursor* cursor;
TISInputSourceRef kbLayoutInputSource;
void* kbLayoutUnicodeData;
id kbLayoutListener;
list_info viewFreeList;
mp_view_data viewPool[MP_APP_MAX_VIEWS];
} osx_app_data;
#define MP_PLATFORM_APP_DATA osx_app_data osx;

File diff suppressed because it is too large Load Diff

View File

@ -19,4 +19,4 @@
#include<stdatomic.h>
#endif
#endif __ATOMIC_H_
#endif //__ATOMIC_H_

View File

@ -19,30 +19,39 @@ Windows port
(mp_app.c can 'see' platform specific stuff, so ObjectiveC defs pose a problem, but we can define id as void*
when not in ObjC...)
[ ] Check changes in macos version
[x] Restructure macos version to use mp_app_internal.h/mp_app.c
[x] test new run loop structure on macos
[x] Fix resize crash when there's no surface
[ ] separate data for key and mouse event?
[ ] Clarify how we want to do view handling across platforms
[ ] Views (using docked windows?) -- or see if we can use surfaces and restrict their location?
[ ] pull views in common stuff
[ ] use isARepeat in macos keyDown event and simplify update key state
[ ] Simplify event structs
[.] Implement input polling
[ ] Simplify input polling API names
[/] Try to simplify input state and polling once we have UI usage code
[ ] Finish window properties query/setting
[ ] use isARepeat in macos keyDown event and simplify update key state
[ ] Implement clipboard
[ ] Implement file dialogs
[ ] Impement resource path... -> maybe in abstracted file handling
[ ] Clean backend selection (compile time and runtime)
[ ] Finish OpenGL loader
[ ] Test compute shaders
[ ] Initial version of vector graphics backend
[ ] Check integration of UI.
[ ] Views (using docked windows?) -- or see if we can use surfaces and restrict their location?
[ ] test new run loop structure on macos
[ ] Remove unused APIs
[ ] OpenGL backend on OSX
[ ] Port vector graphics to OpenGL
[ ] Check OpenGL vector graphics on windows
Misc