WIP - macOS rendering - a lot of junk currently.

Based on these modifications: 18c5ff8afa
This commit is contained in:
Sven Andersson 2020-05-22 13:29:36 +02:00
parent adad2a65be
commit a6130eebba
6 changed files with 154 additions and 28 deletions

View File

@ -319,6 +319,19 @@ function core.on_event(type, ...)
return did_keymap
end
local function fix_mouse_scale(type,a,b,c,d)
if type == "mousepressed" or type == "mousereleased"then
b = b * SCALE
c = c * SCALE
elseif type == "mousemoved" then
a = a * SCALE
b = b * SCALE
c = c * SCALE
d = d * SCALE
end
return a,b,c,d
end
function core.step()
-- handle events
@ -327,6 +340,9 @@ function core.step()
local mouse = { x = 0, y = 0, dx = 0, dy = 0 }
for type, a,b,c,d in system.poll_event do
a,b,c,d = fix_mouse_scale(type,a,b,c,d)
if type == "mousemoved" then
mouse_moved = true
mouse.x, mouse.y = a, b

View File

@ -49,6 +49,8 @@ top:
case SDL_WINDOWEVENT:
if (e.window.event == SDL_WINDOWEVENT_RESIZED) {
ren_resize(e.window.data1, e.window.data2);
lua_pushstring(L, "resized");
lua_pushnumber(L, e.window.data1);
lua_pushnumber(L, e.window.data2);

View File

@ -15,17 +15,22 @@
SDL_Window *window;
static double get_scale(void) {
float dpi;
SDL_GetDisplayDPI(0, NULL, &dpi, NULL);
#if _WIN32
return dpi / 96.0;
#elif __APPLE__
return 1.0; /* dpi / 72.0; */
#else
return 1.0;
#endif
}
// static double get_scale(void) {
// float dpi;
// SDL_GetDisplayDPI(0, NULL, &dpi, NULL);
// printf("dpi: %f, %f\n", dpi, dpi / 96.0);
// #if _WIN32
// return dpi / 96.0;
// #elif __APPLE__
// SDL_DisplayMode dm;
// SDL_GetDesktopDisplayMode(0, &dm);
// printf("dm.h: %d, %f\n", dm.h, dm.h / 786.0);
// // return dm.h / 786.0;
// return 2.0;
// #else
// return 1.0;
// #endif
// }
static void get_exe_filename(char *buf, int sz) {
@ -106,7 +111,7 @@ int main(int argc, char **argv) {
lua_pushstring(L, SDL_GetPlatform());
lua_setglobal(L, "PLATFORM");
lua_pushnumber(L, get_scale());
lua_pushnumber(L, ren_get_scale());
lua_setglobal(L, "SCALE");
char exename[2048];

View File

@ -119,7 +119,7 @@ void rencache_set_clip_rect(RenRect rect) {
void rencache_draw_rect(RenRect rect, RenColor color) {
if (!rects_overlap(screen_rect, rect)) { return; }
// if (!rects_overlap(screen_rect, rect)) { return; }
Command *cmd = push_command(DRAW_RECT, sizeof(Command));
if (cmd) {
cmd->rect = rect;

View File

@ -8,7 +8,9 @@
#define MAX_GLYPHSET 256
struct RenImage {
RenColor *pixels;
//RenColor *pixels;
SDL_Surface *surface;
SDL_Texture *texture;
int width, height;
};
@ -27,7 +29,13 @@ struct RenFont {
static SDL_Window *window;
static struct { int left, top, right, bottom; } clip;
//static struct { int left, top, right, bottom; } clip;
static SDL_Renderer *renderer;
static SDL_Texture *target_texture;
static SDL_Texture *buffer_texture;
static int texture_format;
static double scale = 1.0;
int fb_w, fb_h;
static void* check_alloc(void *ptr) {
@ -55,37 +63,91 @@ static const char* utf8_to_codepoint(const char *p, unsigned *dst) {
return p + 1;
}
// float dpi;
// SDL_GetDisplayDPI(0, NULL, &dpi, NULL);
// printf("dpi: %f, %f\n", dpi, dpi / 96.0);
// #if _WIN32
// return dpi / 96.0;
// #elif __APPLE__
// SDL_DisplayMode dm;
// SDL_GetDesktopDisplayMode(0, &dm);
// printf("dm.h: %d, %f\n", dm.h, dm.h / 786.0);
// // return dm.h / 786.0;
// return 2.0;
// #else
// return 1.0;
// #endif
double ren_get_scale() {
return scale;
}
void ren_init(SDL_Window *win) {
assert(win);
window = win;
SDL_Surface *surf = SDL_GetWindowSurface(window);
ren_set_clip_rect( (RenRect) { 0, 0, surf->w, surf->h } );
renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
assert(renderer != NULL);
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
SDL_RendererInfo info;
SDL_GetRendererInfo(renderer, &info);
texture_format = info.texture_formats[0];
int w, h;
SDL_GetWindowSize(window, &w, &h);
// Calculate scale using render framebuffer size and window pixel size
SDL_GetRendererOutputSize(renderer, &fb_w, &fb_h);
scale = (double)fb_w / (double)w;
target_texture = SDL_CreateTexture(renderer, texture_format, SDL_TEXTUREACCESS_TARGET, fb_w, fb_h);
assert(target_texture != NULL);
buffer_texture = SDL_CreateTexture(renderer, texture_format, SDL_TEXTUREACCESS_TARGET, fb_w, fb_h);
assert(buffer_texture != NULL);
assert(SDL_SetRenderTarget(renderer, target_texture) == 0);
ren_set_clip_rect( (RenRect) { 0, 0, fb_w, fb_h } );
}
void ren_update_rects(RenRect *rects, int count) {
SDL_UpdateWindowSurfaceRects(window, (SDL_Rect*) rects, count);
//SDL_UpdateWindowSurfaceRects(window, (SDL_Rect*) rects, count);
static bool initial_frame = true;
if (initial_frame) {
SDL_ShowWindow(window);
initial_frame = false;
}
assert(SDL_SetRenderTarget(renderer, buffer_texture) == 0);
for (int i = 0; i < count; i++) {
SDL_RenderCopy(renderer, target_texture, &rects[i], &rects[i]);
}
SDL_SetRenderTarget(renderer, NULL);
SDL_RenderCopy(renderer, buffer_texture, NULL, NULL);
SDL_RenderPresent(renderer);
assert(SDL_SetRenderTarget(renderer, target_texture) == 0);
}
void ren_set_clip_rect(RenRect rect) {
/*
clip.left = rect.x;
clip.top = rect.y;
clip.right = rect.x + rect.width;
clip.bottom = rect.y + rect.height;
*/
SDL_RenderSetClipRect(renderer, (SDL_Rect *)&rect);
}
void ren_get_size(int *x, int *y) {
SDL_Surface *surf = SDL_GetWindowSurface(window);
*x = surf->w;
*y = surf->h;
SDL_GetRendererOutputSize(renderer, x, y);
}
@ -93,14 +155,22 @@ RenImage* ren_new_image(int width, int height) {
assert(width > 0 && height > 0);
RenImage *image = malloc(sizeof(RenImage) + width * height * sizeof(RenColor));
check_alloc(image);
image->pixels = (void*) (image + 1);
//image->pixels = (void*) (image + 1);
void *pixels = (void*) (image + 1);
image->width = width;
image->height = height;
image->surface = SDL_CreateRGBSurfaceWithFormatFrom(
pixels, image->width, image->height, 32, image->width * 4, SDL_PIXELFORMAT_ARGB8888);
image->texture = SDL_CreateTextureFromSurface(renderer, image->surface);
return image;
}
void ren_free_image(RenImage *image) {
SDL_DestroyTexture(image->texture);
SDL_FreeSurface(image->surface);
free(image);
}
@ -119,7 +189,7 @@ retry:
stbtt_ScaleForMappingEmToPixels(&font->stbfont, 1) /
stbtt_ScaleForPixelHeight(&font->stbfont, 1);
int res = stbtt_BakeFontBitmap(
font->data, 0, font->size * s, (void*) set->image->pixels,
font->data, 0, font->size * s, (void*) set->image->surface->pixels,
width, height, idx * 256, 256, set->glyphs);
/* retry with a larger image buffer if the buffer wasn't large enough */
@ -142,10 +212,12 @@ retry:
/* convert 8bit data to 32bit */
for (int i = width * height - 1; i >= 0; i--) {
uint8_t n = *((uint8_t*) set->image->pixels + i);
set->image->pixels[i] = (RenColor) { .r = 255, .g = 255, .b = 255, .a = n };
uint8_t n = *((uint8_t*) set->image->surface->pixels + i);
((RenColor *) set->image->surface->pixels)[i] = (RenColor) { .r = 255, .g = 255, .b = 255, .a = n };
}
SDL_UpdateTexture(set->image->texture, NULL, set->image->surface->pixels, width * 4);
return set;
}
@ -240,7 +312,7 @@ int ren_get_font_height(RenFont *font) {
return font->height;
}
/*
static inline RenColor blend_pixel(RenColor dst, RenColor src) {
int ia = 0xff - src.a;
dst.r = ((src.r * src.a) + (dst.r * ia)) >> 8;
@ -258,7 +330,7 @@ static inline RenColor blend_pixel2(RenColor dst, RenColor src, RenColor color)
dst.b = ((src.b * color.b * src.a) >> 16) + ((dst.b * ia) >> 8);
return dst;
}
*/
#define rect_draw_loop(expr) \
for (int j = y1; j < y2; j++) { \
@ -271,7 +343,7 @@ static inline RenColor blend_pixel2(RenColor dst, RenColor src, RenColor color)
void ren_draw_rect(RenRect rect, RenColor color) {
if (color.a == 0) { return; }
/*
int x1 = rect.x < clip.left ? clip.left : rect.x;
int y1 = rect.y < clip.top ? clip.top : rect.y;
int x2 = rect.x + rect.width;
@ -289,6 +361,11 @@ void ren_draw_rect(RenRect rect, RenColor color) {
} else {
rect_draw_loop(blend_pixel(*d, color));
}
*/
SDL_Rect sdl_rect = { .x = rect.x, .y = rect.y, .w = rect.width, .h = rect.height };
assert(SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a) == 0);
assert(SDL_RenderFillRect(renderer, &sdl_rect) == 0);
}
@ -296,6 +373,7 @@ void ren_draw_image(RenImage *image, RenRect *sub, int x, int y, RenColor color)
if (color.a == 0) { return; }
/* clip */
/*
int n;
if ((n = clip.left - x) > 0) { sub->width -= n; sub->x += n; x += n; }
if ((n = clip.top - y) > 0) { sub->height -= n; sub->y += n; y += n; }
@ -305,8 +383,12 @@ void ren_draw_image(RenImage *image, RenRect *sub, int x, int y, RenColor color)
if (sub->width <= 0 || sub->height <= 0) {
return;
}
*/
SDL_SetTextureColorMod(image->texture, color.r, color.g, color.b);
SDL_SetTextureAlphaMod(image->texture, color.a);
/* draw */
/*
SDL_Surface *surf = SDL_GetWindowSurface(window);
RenColor *s = image->pixels;
RenColor *d = (RenColor*) surf->pixels;
@ -324,6 +406,9 @@ void ren_draw_image(RenImage *image, RenRect *sub, int x, int y, RenColor color)
d += dr;
s += sr;
}
*/
SDL_Rect dst = { .x = x, .y = y, .w = sub->width, .h = sub->height };
assert(SDL_RenderCopy(renderer, image->texture, sub, &dst) == 0);
}
@ -344,3 +429,19 @@ int ren_draw_text(RenFont *font, const char *text, int x, int y, RenColor color)
}
return x;
}
void ren_resize(int w, int h) {
SDL_DestroyTexture(target_texture);
SDL_DestroyTexture(buffer_texture);
SDL_GetRendererOutputSize(renderer, &fb_w, &fb_h);
scale = (double)fb_w / (double)w;
target_texture = SDL_CreateTexture(renderer, texture_format, SDL_TEXTUREACCESS_TARGET, fb_w, fb_h);
assert(target_texture != NULL);
buffer_texture = SDL_CreateTexture(renderer, texture_format, SDL_TEXTUREACCESS_TARGET, fb_w, fb_h);
assert(buffer_texture != NULL);
SDL_SetRenderTarget(renderer, target_texture);
}

View File

@ -15,6 +15,8 @@ void ren_init(SDL_Window *win);
void ren_update_rects(RenRect *rects, int count);
void ren_set_clip_rect(RenRect rect);
void ren_get_size(int *x, int *y);
void ren_resize(int x, int y);
double ren_get_scale();
RenImage* ren_new_image(int width, int height);
void ren_free_image(RenImage *image);