From 855070a2870b7f2fe777fded9bb705385f6cd2e2 Mon Sep 17 00:00:00 2001 From: Aldrik Ramaekers Date: Fri, 12 Jun 2020 19:55:06 +0200 Subject: cpu rendering working --- src/assets.c | 26 ++- src/assets.h | 7 +- src/localization.c | 2 +- src/platform.h | 1 - src/render.c | 441 +++++++++++++++++++++++++++++++++++++++---------- src/windows/platform.c | 8 +- 6 files changed, 368 insertions(+), 117 deletions(-) diff --git a/src/assets.c b/src/assets.c index a0808d0..c81a70a 100644 --- a/src/assets.c +++ b/src/assets.c @@ -83,9 +83,6 @@ bool assets_do_post_process() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); task->image->loaded = true; glBindTexture(GL_TEXTURE_2D, 0); - - if (!task->image->keep_in_memory && task->type == ASSET_IMAGE) - stbi_image_free(task->image->data); } } else if (task->type == ASSET_FONT) @@ -106,8 +103,6 @@ bool assets_do_post_process() glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, g->width,g->height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap ); - - mem_free(g->bitmap); } task->font->loaded = true; @@ -276,7 +271,7 @@ void *assets_queue_worker() return 0; } -image *assets_load_image(u8 *start_addr, u8 *end_addr, bool keep_in_memory) +image *assets_load_image(u8 *start_addr, u8 *end_addr) { // check if image is already loaded or loading for (int i = 0; i < global_asset_collection.images.length; i++) @@ -296,7 +291,6 @@ image *assets_load_image(u8 *start_addr, u8 *end_addr, bool keep_in_memory) new_image.start_addr = start_addr; new_image.end_addr = end_addr; new_image.references = 1; - new_image.keep_in_memory = keep_in_memory; // NOTE(Aldrik): we should never realloc the image array because pointers will be // invalidated. @@ -319,11 +313,12 @@ void assets_destroy_image(image *image_to_destroy) { if (image_to_destroy->references == 1) { - glBindTexture(GL_TEXTURE_2D, 0); - glDeleteTextures(1, &image_to_destroy->textureID); - - if (image_to_destroy->keep_in_memory) + if (global_use_gpu) + { + glBindTexture(GL_TEXTURE_2D, 0); + glDeleteTextures(1, &image_to_destroy->textureID); stbi_image_free(image_to_destroy->data); + } //array_remove(&global_asset_collection.images, image_at); } @@ -421,7 +416,6 @@ image *assets_load_bitmap(u8 *start_addr, u8 *end_addr) new_image.start_addr = start_addr; new_image.end_addr = end_addr; new_image.references = 1; - new_image.keep_in_memory = false; // NOTE(Aldrik): we should never realloc the image array because pointers will be // invalidated. @@ -444,9 +438,11 @@ void assets_destroy_bitmap(image *image_to_destroy) { if (image_to_destroy->references == 1) { - glBindTexture(GL_TEXTURE_2D, 0); - glDeleteTextures(1, &image_to_destroy->textureID); - + if (global_use_gpu) + { + glBindTexture(GL_TEXTURE_2D, 0); + glDeleteTextures(1, &image_to_destroy->textureID); + } //array_remove(&global_asset_collection.images, image_at); } else diff --git a/src/assets.h b/src/assets.h index 6f7e40f..8b459a8 100644 --- a/src/assets.h +++ b/src/assets.h @@ -11,7 +11,6 @@ typedef struct t_image { u8 *start_addr; u8 *end_addr; bool loaded; - bool keep_in_memory; bool is_bitmap; s32 width; s32 height; @@ -91,7 +90,7 @@ void assets_destroy(); bool assets_do_post_process(); void *assets_queue_worker(); -image *assets_load_image(u8 *start_addr, u8 *end_addr, bool keep_in_memory); +image *assets_load_image(u8 *start_addr, u8 *end_addr); void assets_destroy_image(image *image); image *assets_load_bitmap(u8 *start_addr, u8 *end_addr); @@ -100,8 +99,8 @@ void assets_destroy_bitmap(image *image); font *assets_load_font(u8 *start_addr, u8 *end_addr, s16 size); void assets_destroy_font(font *font); -#define load_image(_name, _inmem) assets_load_image(_binary____data_imgs_##_name##_start,_binary____data_imgs_##_name##_end, _inmem) -#define load_font(_name, _inmem) assets_load_font(_binary____data_fonts_##_name##_start,_binary____data_fonts_##_name##_end, _inmem) +#define load_image(_name, _inmem) assets_load_image(_binary____data_imgs_##_name##_start,_binary____data_imgs_##_name##_end) +#define load_font(_name, _size) assets_load_font(_binary____data_fonts_##_name##_start,_binary____data_fonts_##_name##_end, _size) #define load_bitmap(_name) assets_load_bitmap(_binary____data_imgs_##_name##_start,_binary____data_imgs_##_name##_end) #endif \ No newline at end of file diff --git a/src/localization.c b/src/localization.c index 6512d40..4d9ee38 100644 --- a/src/localization.c +++ b/src/localization.c @@ -141,7 +141,7 @@ void destroy_available_localizations() mem_free(file->locale_full); if (file->icon) - assets_destroy_image(file->icon); + assets_destroy_bitmap(file->icon); } array_destroy(&global_localization.mo_files); } diff --git a/src/platform.h b/src/platform.h index bf0ae82..e72bb8c 100644 --- a/src/platform.h +++ b/src/platform.h @@ -178,7 +178,6 @@ typedef struct t_backbuffer { s32 width; s32 height; - u8 *pixels; // 5bytes color u8 *buffer; // 4bytes color + 1byte depth BITMAPINFO bitmapInfo; } backbuffer; diff --git a/src/render.c b/src/render.c index a5d0d51..bd14a37 100644 --- a/src/render.c +++ b/src/render.c @@ -64,19 +64,59 @@ inline void set_render_depth(s32 depth) void render_image(image *image, s32 x, s32 y, s32 width, s32 height) { assert(image); - if (image->loaded) + + if (global_use_gpu) { - glBindTexture(GL_TEXTURE_2D, image->textureID); - glEnable(GL_TEXTURE_2D); - glBegin(GL_QUADS); - glColor4f(1., 1., 1., 1.); - glTexCoord2i(0, 0); glVertex3i(x, y, render_depth); - glTexCoord2i(0, 1); glVertex3i(x, y+height, render_depth); - glTexCoord2i(1, 1); glVertex3i(x+width, y+height, render_depth); - glTexCoord2i(1, 0); glVertex3i(x+width, y, render_depth); - glEnd(); - - glDisable(GL_TEXTURE_2D); + if (image->loaded) + { + glBindTexture(GL_TEXTURE_2D, image->textureID); + glEnable(GL_TEXTURE_2D); + glBegin(GL_QUADS); + glColor4f(1., 1., 1., 1.); + glTexCoord2i(0, 0); glVertex3i(x, y, render_depth); + glTexCoord2i(0, 1); glVertex3i(x, y+height, render_depth); + glTexCoord2i(1, 1); glVertex3i(x+width, y+height, render_depth); + glTexCoord2i(1, 0); glVertex3i(x+width, y, render_depth); + glEnd(); + + glDisable(GL_TEXTURE_2D); + } + } + else + { + if (image->loaded) + { + vec4 rec = _get_actual_rect(x, y, image->width, image->height); + + for (s32 x = rec.x; x < rec.w; x++) + { + for (s32 y = rec.y; y < rec.h; y++) + { + s32 offset = (y * (drawing_window->backbuffer.width) * 5) + x * 5; + u8 *buffer_entry = drawing_window->backbuffer.buffer+offset; + + if (buffer_entry[4] > render_depth) continue; + buffer_entry[4] = render_depth; + + s32 _x = x - rec.x; + s32 _y = y - rec.y; + s32 image_offset = (_y * (image->width) * 4) + _x * 4; + u8 *color = image->data+image_offset; + + float32 alpha = color[3] / 255.0f; + float32 oneminusalpha = 1 - alpha; + + u8 b = ((color[0] * alpha) + (oneminusalpha * buffer_entry[0])); + u8 g = ((color[1] * alpha) + (oneminusalpha * buffer_entry[1])); + u8 r = ((color[2] * alpha) + (oneminusalpha * buffer_entry[2])); + u8 a = color[3]; + + s32 c = (a << 24) | (r << 16) | (g << 8) | (b << 0); + + memcpy(buffer_entry, &c, 4); + } + } + } } } @@ -85,17 +125,24 @@ void render_image_tint(image *image, s32 x, s32 y, s32 width, s32 height, color assert(image); if (image->loaded) { - glBindTexture(GL_TEXTURE_2D, image->textureID); - glEnable(GL_TEXTURE_2D); - glBegin(GL_QUADS); - glColor4f(tint.r/255.0f, tint.g/255.0f, tint.b/255.0f, tint.a/255.0f); - glTexCoord2i(0, 0); glVertex3i(x, y, render_depth); - glTexCoord2i(0, 1); glVertex3i(x, y+height, render_depth); - glTexCoord2i(1, 1); glVertex3i(x+width, y+height, render_depth); - glTexCoord2i(1, 0); glVertex3i(x+width, y, render_depth); - glEnd(); - - glDisable(GL_TEXTURE_2D); + if (global_use_gpu) + { + glBindTexture(GL_TEXTURE_2D, image->textureID); + glEnable(GL_TEXTURE_2D); + glBegin(GL_QUADS); + glColor4f(tint.r/255.0f, tint.g/255.0f, tint.b/255.0f, tint.a/255.0f); + glTexCoord2i(0, 0); glVertex3i(x, y, render_depth); + glTexCoord2i(0, 1); glVertex3i(x, y+height, render_depth); + glTexCoord2i(1, 1); glVertex3i(x+width, y+height, render_depth); + glTexCoord2i(1, 0); glVertex3i(x+width, y, render_depth); + glEnd(); + + glDisable(GL_TEXTURE_2D); + } + else + { + assert(0 && "not implemented"); + } } } @@ -104,8 +151,11 @@ s32 render_text_ellipsed(font *font, s32 x, s32 y, s32 maxw, char *text, color t if (!font->loaded) return 0; - glEnable(GL_TEXTURE_2D); - glColor4f(tint.r/255.0f, tint.g/255.0f, tint.b/255.0f, tint.a/255.0f); + if (global_use_gpu) + { + glEnable(GL_TEXTURE_2D); + glColor4f(tint.r/255.0f, tint.g/255.0f, tint.b/255.0f, tint.a/255.0f); + } char *ellipse = "..."; bool in_ellipse = false; @@ -129,20 +179,56 @@ s32 render_text_ellipsed(font *font, s32 x, s32 y, s32 maxw, char *text, color t glyph g = font->glyphs[ch]; - glBindTexture(GL_TEXTURE_2D, g.textureID); - glBegin(GL_QUADS); - - s32 width = g.width; - s32 y_ = y + font->px_h + g.yoff; s32 x_to_render = x_ + (g.lsb); - glTexCoord2i(0, 0); glVertex3i(x_to_render,y_, render_depth); - glTexCoord2i(0, 1); glVertex3i(x_to_render,y_+g.height, render_depth); - glTexCoord2i(1, 1); glVertex3i(x_to_render+g.width,y_+g.height, render_depth); - glTexCoord2i(1, 0); glVertex3i(x_to_render+g.width,y_, render_depth); - - glEnd(); + if (global_use_gpu) + { + glBindTexture(GL_TEXTURE_2D, g.textureID); + glBegin(GL_QUADS); + + s32 width = g.width; + + glTexCoord2i(0, 0); glVertex3i(x_to_render,y_, render_depth); + glTexCoord2i(0, 1); glVertex3i(x_to_render,y_+g.height, render_depth); + glTexCoord2i(1, 1); glVertex3i(x_to_render+g.width,y_+g.height, render_depth); + glTexCoord2i(1, 0); glVertex3i(x_to_render+g.width,y_, render_depth); + + glEnd(); + } + else + { + vec4 rec = _get_actual_rect(x_to_render, y_, g.width, g.height); + + for (s32 x = rec.x; x < rec.w; x++) + { + for (s32 y = rec.y; y < rec.h; y++) + { + s32 offset = (y * (drawing_window->backbuffer.width) * 5) + x * 5; + u8 *buffer_entry = drawing_window->backbuffer.buffer+offset; + + if (buffer_entry[4] > render_depth) continue; + buffer_entry[4] = render_depth; + + s32 _x = x - rec.x; + s32 _y = y - rec.y; + s32 image_offset = (_y * g.width) + _x; + u8 *color = g.bitmap+image_offset; + + float32 alpha = color[0] / 255.0f; + float32 oneminusalpha = 1 - alpha; + + u8 r = ((tint.r * alpha) + (oneminusalpha * buffer_entry[0])); + u8 g = ((tint.g * alpha) + (oneminusalpha * buffer_entry[1])); + u8 b = ((tint.b * alpha) + (oneminusalpha * buffer_entry[2])); + u8 a = color[0]; + + s32 c = (a << 24) | (r << 16) | (g << 8) | (b << 0); + + memcpy(buffer_entry, &c, 4); + } + } + } /* add kerning */ //kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next); @@ -155,7 +241,8 @@ s32 render_text_ellipsed(font *font, s32 x, s32 y, s32 maxw, char *text, color t } } - glDisable(GL_TEXTURE_2D); + if (global_use_gpu) + glDisable(GL_TEXTURE_2D); return maxw; } @@ -165,8 +252,11 @@ s32 render_text_with_selection(font *font, s32 x, s32 y, char *text, color tint, if (!font->loaded) return 0; - glEnable(GL_TEXTURE_2D); - glColor4f(tint.r/255.0f, tint.g/255.0f, tint.b/255.0f, tint.a/255.0f); + if (global_use_gpu) + { + glEnable(GL_TEXTURE_2D); + glColor4f(tint.r/255.0f, tint.g/255.0f, tint.b/255.0f, tint.a/255.0f); + } s32 x_ = x; utf8_int32_t ch; @@ -186,20 +276,56 @@ s32 render_text_with_selection(font *font, s32 x, s32 y, char *text, color tint, glyph g = font->glyphs[ch]; - glBindTexture(GL_TEXTURE_2D, g.textureID); - glBegin(GL_QUADS); - - s32 width = g.width; - s32 y_ = y + font->px_h + g.yoff; s32 x_to_render = x_ + (g.lsb); - glTexCoord2i(0, 0); glVertex3i(x_to_render,y_, render_depth); - glTexCoord2i(0, 1); glVertex3i(x_to_render,y_+g.height, render_depth); - glTexCoord2i(1, 1); glVertex3i(x_to_render+g.width,y_+g.height, render_depth); - glTexCoord2i(1, 0); glVertex3i(x_to_render+g.width,y_, render_depth); - - glEnd(); + if (global_use_gpu) + { + glBindTexture(GL_TEXTURE_2D, g.textureID); + glBegin(GL_QUADS); + + s32 width = g.width; + + glTexCoord2i(0, 0); glVertex3i(x_to_render,y_, render_depth); + glTexCoord2i(0, 1); glVertex3i(x_to_render,y_+g.height, render_depth); + glTexCoord2i(1, 1); glVertex3i(x_to_render+g.width,y_+g.height, render_depth); + glTexCoord2i(1, 0); glVertex3i(x_to_render+g.width,y_, render_depth); + + glEnd(); + } + else + { + vec4 rec = _get_actual_rect(x_to_render, y_, g.width, g.height); + + for (s32 x = rec.x; x < rec.w; x++) + { + for (s32 y = rec.y; y < rec.h; y++) + { + s32 offset = (y * (drawing_window->backbuffer.width) * 5) + x * 5; + u8 *buffer_entry = drawing_window->backbuffer.buffer+offset; + + if (buffer_entry[4] > render_depth) continue; + buffer_entry[4] = render_depth; + + s32 _x = x - rec.x; + s32 _y = y - rec.y; + s32 image_offset = (_y * g.width) + _x; + u8 *color = g.bitmap+image_offset; + + float32 alpha = color[0] / 255.0f; + float32 oneminusalpha = 1 - alpha; + + u8 r = ((tint.r * alpha) + (oneminusalpha * buffer_entry[0])); + u8 g = ((tint.g * alpha) + (oneminusalpha * buffer_entry[1])); + u8 b = ((tint.b * alpha) + (oneminusalpha * buffer_entry[2])); + u8 a = color[0]; + + s32 c = (a << 24) | (r << 16) | (g << 8) | (b << 0); + + memcpy(buffer_entry, &c, 4); + } + } + } /* add kerning */ //kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next); @@ -216,7 +342,8 @@ s32 render_text_with_selection(font *font, s32 x, s32 y, char *text, color tint, } } - glDisable(GL_TEXTURE_2D); + if (global_use_gpu) + glDisable(GL_TEXTURE_2D); render_rectangle(selection_start_x, y-3, selection_end_x-selection_start_x, TEXTBOX_HEIGHT - 10, rgba(66, 134, 244, 120)); @@ -228,8 +355,11 @@ s32 render_text_with_cursor(font *font, s32 x, s32 y, char *text, color tint, s3 if (!font->loaded) return 0; - glEnable(GL_TEXTURE_2D); - glColor4f(tint.r/255.0f, tint.g/255.0f, tint.b/255.0f, tint.a/255.0f); + if (global_use_gpu) + { + glEnable(GL_TEXTURE_2D); + glColor4f(tint.r/255.0f, tint.g/255.0f, tint.b/255.0f, tint.a/255.0f); + } float x_ = x; utf8_int32_t ch; @@ -248,18 +378,54 @@ s32 render_text_with_cursor(font *font, s32 x, s32 y, char *text, color tint, s3 glyph g = font->glyphs[ch]; - glBindTexture(GL_TEXTURE_2D, g.textureID); - glBegin(GL_QUADS); - s32 y_ = y + font->px_h + g.yoff; s32 x_to_render = x_ + (g.lsb); - glTexCoord2i(0, 0); glVertex3i(x_to_render,y_, render_depth); - glTexCoord2i(0, 1); glVertex3i(x_to_render,y_+g.height, render_depth); - glTexCoord2i(1, 1); glVertex3i(x_to_render+g.width,y_+g.height, render_depth); - glTexCoord2i(1, 0); glVertex3i(x_to_render+g.width,y_, render_depth); - - glEnd(); + if (global_use_gpu) + { + glBindTexture(GL_TEXTURE_2D, g.textureID); + glBegin(GL_QUADS); + + glTexCoord2i(0, 0); glVertex3i(x_to_render,y_, render_depth); + glTexCoord2i(0, 1); glVertex3i(x_to_render,y_+g.height, render_depth); + glTexCoord2i(1, 1); glVertex3i(x_to_render+g.width,y_+g.height, render_depth); + glTexCoord2i(1, 0); glVertex3i(x_to_render+g.width,y_, render_depth); + + glEnd(); + } + else + { + vec4 rec = _get_actual_rect(x_to_render, y_, g.width, g.height); + + for (s32 x = rec.x; x < rec.w; x++) + { + for (s32 y = rec.y; y < rec.h; y++) + { + s32 offset = (y * (drawing_window->backbuffer.width) * 5) + x * 5; + u8 *buffer_entry = drawing_window->backbuffer.buffer+offset; + + if (buffer_entry[4] > render_depth) continue; + buffer_entry[4] = render_depth; + + s32 _x = x - rec.x; + s32 _y = y - rec.y; + s32 image_offset = (_y * g.width) + _x; + u8 *color = g.bitmap+image_offset; + + float32 alpha = color[0] / 255.0f; + float32 oneminusalpha = 1 - alpha; + + u8 r = ((tint.r * alpha) + (oneminusalpha * buffer_entry[0])); + u8 g = ((tint.g * alpha) + (oneminusalpha * buffer_entry[1])); + u8 b = ((tint.b * alpha) + (oneminusalpha * buffer_entry[2])); + u8 a = color[0]; + + s32 c = (a << 24) | (r << 16) | (g << 8) | (b << 0); + + memcpy(buffer_entry, &c, 4); + } + } + } /* add kerning */ //kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next); @@ -271,7 +437,9 @@ s32 render_text_with_cursor(font *font, s32 x, s32 y, char *text, color tint, s3 cursor_x = x_; } } - glDisable(GL_TEXTURE_2D); + + if (global_use_gpu) + glDisable(GL_TEXTURE_2D); render_rectangle(cursor_x, y-3, 2, TEXTBOX_HEIGHT - 10, global_ui_context.style.textbox_foreground); @@ -283,8 +451,11 @@ s32 render_text(font *font, s32 x, s32 y, char *text, color tint) if (!font->loaded) return 0; - glEnable(GL_TEXTURE_2D); - glColor4f(tint.r/255.0f, tint.g/255.0f, tint.b/255.0f, tint.a/255.0f); + if (global_use_gpu) + { + glEnable(GL_TEXTURE_2D); + glColor4f(tint.r/255.0f, tint.g/255.0f, tint.b/255.0f, tint.a/255.0f); + } s32 x_ = x; utf8_int32_t ch; @@ -302,25 +473,64 @@ s32 render_text(font *font, s32 x, s32 y, char *text, color tint) glyph g = font->glyphs[ch]; - glBindTexture(GL_TEXTURE_2D, g.textureID); - glBegin(GL_QUADS); - s32 y_ = y + font->px_h + g.yoff; s32 x_to_render = x_ + (g.lsb); - glTexCoord2i(0, 0); glVertex3i(x_to_render,y_, render_depth); - glTexCoord2i(0, 1); glVertex3i(x_to_render,y_+g.height, render_depth); - glTexCoord2i(1, 1); glVertex3i(x_to_render+g.width,y_+g.height, render_depth); - glTexCoord2i(1, 0); glVertex3i(x_to_render+g.width,y_, render_depth); - - glEnd(); + if (global_use_gpu) + { + glBindTexture(GL_TEXTURE_2D, g.textureID); + glBegin(GL_QUADS); + + glTexCoord2i(0, 0); glVertex3i(x_to_render,y_, render_depth); + glTexCoord2i(0, 1); glVertex3i(x_to_render,y_+g.height, render_depth); + glTexCoord2i(1, 1); glVertex3i(x_to_render+g.width,y_+g.height, render_depth); + glTexCoord2i(1, 0); glVertex3i(x_to_render+g.width,y_, render_depth); + + glEnd(); + } + else + { + vec4 rec = _get_actual_rect(x_to_render, y_, g.width, g.height); + + for (s32 x = rec.x; x < rec.w; x++) + { + for (s32 y = rec.y; y < rec.h; y++) + { + s32 offset = (y * (drawing_window->backbuffer.width) * 5) + x * 5; + u8 *buffer_entry = drawing_window->backbuffer.buffer+offset; + + if (buffer_entry[4] > render_depth) continue; + buffer_entry[4] = render_depth; + + s32 _x = x - rec.x; + s32 _y = y - rec.y; + s32 image_offset = (_y * g.width) + _x; + u8 *color = g.bitmap+image_offset; + + if (color[0] == 0) continue; + + float32 alpha = color[0] / 255.0f; + float32 oneminusalpha = 1 - alpha; + + u8 r = ((tint.r * alpha) + (oneminusalpha * buffer_entry[0])); + u8 g = ((tint.g * alpha) + (oneminusalpha * buffer_entry[1])); + u8 b = ((tint.b * alpha) + (oneminusalpha * buffer_entry[2])); + u8 a = color[0]; + + s32 c = (a << 24) | (r << 16) | (g << 8) | (b << 0); + + memcpy(buffer_entry, &c, 4); + } + } + } /* add kerning */ //kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next); x_ += (g.advance); } - glDisable(GL_TEXTURE_2D); + if (global_use_gpu) + glDisable(GL_TEXTURE_2D); return x_ - x; } @@ -330,8 +540,11 @@ s32 render_text_cutoff(font *font, s32 x, s32 y, char *text, color tint, u16 cut if (!font->loaded) return 0; - glEnable(GL_TEXTURE_2D); - glColor4f(tint.r/255.0f, tint.g/255.0f, tint.b/255.0f, tint.a/255.0f); + if (global_use_gpu) + { + glEnable(GL_TEXTURE_2D); + glColor4f(tint.r/255.0f, tint.g/255.0f, tint.b/255.0f, tint.a/255.0f); + } s32 x_ = x; s32 y_ = y; @@ -368,18 +581,54 @@ s32 render_text_cutoff(font *font, s32 x, s32 y, char *text, color tint, u16 cut glyph g = font->glyphs[ch]; - glBindTexture(GL_TEXTURE_2D, g.textureID); - glBegin(GL_QUADS); - s32 y__ = y_ + font->px_h + g.yoff; s32 x_to_render = x_ + (g.lsb); - glTexCoord2i(0, 0); glVertex3i(x_to_render,y__, render_depth); - glTexCoord2i(0, 1); glVertex3i(x_to_render,y__+g.height, render_depth); - glTexCoord2i(1, 1); glVertex3i(x_to_render+g.width,y__+g.height, render_depth); - glTexCoord2i(1, 0); glVertex3i(x_to_render+g.width,y__, render_depth); - - glEnd(); + if (global_use_gpu) + { + glBindTexture(GL_TEXTURE_2D, g.textureID); + glBegin(GL_QUADS); + + glTexCoord2i(0, 0); glVertex3i(x_to_render,y__, render_depth); + glTexCoord2i(0, 1); glVertex3i(x_to_render,y__+g.height, render_depth); + glTexCoord2i(1, 1); glVertex3i(x_to_render+g.width,y__+g.height, render_depth); + glTexCoord2i(1, 0); glVertex3i(x_to_render+g.width,y__, render_depth); + + glEnd(); + } + else + { + vec4 rec = _get_actual_rect(x_to_render, y__, g.width, g.height); + + for (s32 x = rec.x; x < rec.w; x++) + { + for (s32 y = rec.y; y < rec.h; y++) + { + s32 offset = (y * (drawing_window->backbuffer.width) * 5) + x * 5; + u8 *buffer_entry = drawing_window->backbuffer.buffer+offset; + + if (buffer_entry[4] > render_depth) continue; + buffer_entry[4] = render_depth; + + s32 _x = x - rec.x; + s32 _y = y - rec.y; + s32 image_offset = (_y * g.width) + _x; + u8 *color = g.bitmap+image_offset; + + float32 alpha = color[0] / 255.0f; + float32 oneminusalpha = 1 - alpha; + + u8 r = ((tint.r * alpha) + (oneminusalpha * buffer_entry[0])); + u8 g = ((tint.g * alpha) + (oneminusalpha * buffer_entry[1])); + u8 b = ((tint.b * alpha) + (oneminusalpha * buffer_entry[2])); + u8 a = color[0]; + + s32 c = (a << 24) | (r << 16) | (g << 8) | (b << 0); + + memcpy(buffer_entry, &c, 4); + } + } + } /* add kerning */ //kern = stbtt_GetCodepointKernAdvance(&font->info, ch, ch_next); @@ -393,7 +642,8 @@ s32 render_text_cutoff(font *font, s32 x, s32 y, char *text, color tint, u16 cut } } - glDisable(GL_TEXTURE_2D); + if (global_use_gpu) + glDisable(GL_TEXTURE_2D); return (y_ - y) + font->size; @@ -594,7 +844,18 @@ void render_rectangle(s32 x, s32 y, s32 width, s32 height, color tint) if (buffer_entry[4] > render_depth) continue; buffer_entry[4] = render_depth; - memcpy(buffer_entry, &tint, 4); + + float32 alpha = tint.a / 255.0f; + float32 oneminusalpha = 1 - alpha; + + u8 r = ((tint.r * alpha) + (oneminusalpha * buffer_entry[0])); + u8 g = ((tint.g * alpha) + (oneminusalpha * buffer_entry[1])); + u8 b = ((tint.b * alpha) + (oneminusalpha * buffer_entry[2])); + u8 a = tint.a; + + s32 c = (a << 24) | (r << 16) | (g << 8) | (b << 0); + + memcpy(buffer_entry, &c, 4); } } } @@ -621,7 +882,7 @@ void render_set_scissor(platform_window *window, s32 x, s32 y, s32 w, s32 h) } else { - current_scissor = (vec4){x,y,w,h}; + current_scissor = (vec4){x,y,w+1,h+1}; } } @@ -651,6 +912,6 @@ void render_reset_scissor() } else { - current_scissor = (vec4){0,0,drawing_window->width,drawing_window->height}; + current_scissor = (vec4){0,0,drawing_window->width+1,drawing_window->height+1}; } } diff --git a/src/windows/platform.c b/src/windows/platform.c index 40d2d7a..e1a664e 100644 --- a/src/windows/platform.c +++ b/src/windows/platform.c @@ -321,7 +321,6 @@ void platform_show_message(platform_window *window, char *message, char *title) static void _allocate_backbuffer(platform_window *window) { - if (window->backbuffer.pixels) mem_free(window->backbuffer.pixels); if (window->backbuffer.buffer) mem_free(window->backbuffer.buffer); BITMAPINFO info; @@ -337,9 +336,7 @@ static void _allocate_backbuffer(platform_window *window) window->backbuffer.height = window->height; s32 bufferMemorySize = (window->width*window->height)*5; - s32 pixelsMemorySize = (window->width*window->height)*4; window->backbuffer.buffer = mem_alloc(bufferMemorySize); - window->backbuffer.pixels = mem_alloc(pixelsMemorySize); } LRESULT CALLBACK main_window_callback(HWND window, UINT message, WPARAM wparam, LPARAM lparam) @@ -591,7 +588,6 @@ platform_window platform_open_window_ex(char *name, u16 width, u16 height, u16 m window.max_height = max_h; window.curr_cursor_type = -1; window.next_cursor_type = CURSOR_DEFAULT; - window.backbuffer.pixels = 0; window.backbuffer.buffer = 0; window.do_draw = true; @@ -904,13 +900,13 @@ void platform_window_swap_buffers(platform_window *window) for (s32 i = 0; i < pixel_count; i++) { u8 *buffer_entry = window->backbuffer.buffer + (i*5); - memcpy(window->backbuffer.pixels + (i*4), buffer_entry, 4); + memcpy(window->backbuffer.buffer + (i*4), buffer_entry, 4); } StretchDIBits(window->hdc,0,0,window->width,window->height, 0,window->backbuffer.height,window->backbuffer.width, -window->backbuffer.height, - window->backbuffer.pixels, &window->backbuffer.bitmapInfo, DIB_RGB_COLORS, SRCCOPY); + window->backbuffer.buffer, &window->backbuffer.bitmapInfo, DIB_RGB_COLORS, SRCCOPY); } else { -- cgit v1.2.3-70-g09d2