Merge pull request #638 from ccawley2011/rawfb-pixel-format
Support arbitrary pixel formats with more rawfb demos
This commit is contained in:
commit
6286f22996
@ -28,23 +28,23 @@
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
|
||||
#ifndef NK_RAWFB_H_
|
||||
#define NK_RAWFB_H_
|
||||
|
||||
struct rawfb_context;
|
||||
|
||||
typedef enum rawfb_pixel_layout {
|
||||
PIXEL_LAYOUT_XRGB_8888,
|
||||
PIXEL_LAYOUT_RGBX_8888
|
||||
}
|
||||
rawfb_pl;
|
||||
|
||||
struct rawfb_pl {
|
||||
unsigned char bytesPerPixel;
|
||||
unsigned char rshift, gshift, bshift, ashift;
|
||||
unsigned char rloss, gloss, bloss, aloss;
|
||||
};
|
||||
|
||||
/* All functions are thread-safe */
|
||||
NK_API struct rawfb_context *nk_rawfb_init(void *fb, void *tex_mem, const unsigned int w, const unsigned int h, const unsigned int pitch, const rawfb_pl pl);
|
||||
NK_API struct rawfb_context *nk_rawfb_init(void *fb, void *tex_mem, const unsigned int w, const unsigned int h, const unsigned int pitch, const struct rawfb_pl pl);
|
||||
NK_API void nk_rawfb_render(const struct rawfb_context *rawfb, const struct nk_color clear, const unsigned char enable_clear);
|
||||
NK_API void nk_rawfb_shutdown(struct rawfb_context *rawfb);
|
||||
NK_API void nk_rawfb_resize_fb(struct rawfb_context *rawfb, void *fb, const unsigned int w, const unsigned int h, const unsigned int pitch, const rawfb_pl pl);
|
||||
NK_API void nk_rawfb_resize_fb(struct rawfb_context *rawfb, void *fb, const unsigned int w, const unsigned int h, const unsigned int pitch, const struct rawfb_pl pl);
|
||||
|
||||
#endif
|
||||
/*
|
||||
@ -62,8 +62,7 @@ NK_API void nk_rawfb_resize_fb(struct rawfb_context *rawfb, voi
|
||||
struct rawfb_image {
|
||||
void *pixels;
|
||||
int w, h, pitch;
|
||||
rawfb_pl pl;
|
||||
enum nk_font_atlas_format format;
|
||||
struct rawfb_pl pl;
|
||||
};
|
||||
struct rawfb_context {
|
||||
struct nk_context ctx;
|
||||
@ -81,54 +80,28 @@ struct rawfb_context {
|
||||
#endif
|
||||
|
||||
static unsigned int
|
||||
nk_rawfb_color2int(const struct nk_color c, rawfb_pl pl)
|
||||
nk_rawfb_color2int(const struct nk_color c, const struct rawfb_pl pl)
|
||||
{
|
||||
unsigned int res = 0;
|
||||
|
||||
switch (pl) {
|
||||
case PIXEL_LAYOUT_RGBX_8888:
|
||||
res |= c.r << 24;
|
||||
res |= c.g << 16;
|
||||
res |= c.b << 8;
|
||||
res |= c.a;
|
||||
break;
|
||||
case PIXEL_LAYOUT_XRGB_8888:
|
||||
res |= c.a << 24;
|
||||
res |= c.r << 16;
|
||||
res |= c.g << 8;
|
||||
res |= c.b;
|
||||
break;
|
||||
res |= (c.r >> pl.rloss) << pl.rshift;
|
||||
res |= (c.g >> pl.gloss) << pl.gshift;
|
||||
res |= (c.b >> pl.bloss) << pl.bshift;
|
||||
res |= (c.a >> pl.aloss) << pl.ashift;
|
||||
|
||||
default:
|
||||
perror("nk_rawfb_color2int(): Unsupported pixel layout.\n");
|
||||
break;
|
||||
}
|
||||
return (res);
|
||||
}
|
||||
|
||||
static struct nk_color
|
||||
nk_rawfb_int2color(const unsigned int i, rawfb_pl pl)
|
||||
nk_rawfb_int2color(const unsigned int i, const struct rawfb_pl pl)
|
||||
{
|
||||
struct nk_color col = {0,0,0,0};
|
||||
|
||||
switch (pl) {
|
||||
case PIXEL_LAYOUT_RGBX_8888:
|
||||
col.r = (i >> 24) & 0xff;
|
||||
col.g = (i >> 16) & 0xff;
|
||||
col.b = (i >> 8) & 0xff;
|
||||
col.a = i & 0xff;
|
||||
break;
|
||||
case PIXEL_LAYOUT_XRGB_8888:
|
||||
col.a = (i >> 24) & 0xff;
|
||||
col.r = (i >> 16) & 0xff;
|
||||
col.g = (i >> 8) & 0xff;
|
||||
col.b = i & 0xff;
|
||||
break;
|
||||
col.r = (pl.rloss == 8) ? 0xff : ((i >> pl.rshift) << pl.rloss) & 0xff;
|
||||
col.g = (pl.gloss == 8) ? 0xff : ((i >> pl.gshift) << pl.gloss) & 0xff;
|
||||
col.b = (pl.bloss == 8) ? 0xff : ((i >> pl.bshift) << pl.bloss) & 0xff;
|
||||
col.a = (pl.aloss == 8) ? 0xff : ((i >> pl.ashift) << pl.aloss) & 0xff;
|
||||
|
||||
default:
|
||||
perror("nk_rawfb_int2color(): Unsupported pixel layout.\n");
|
||||
break;
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
@ -138,14 +111,20 @@ nk_rawfb_ctx_setpixel(const struct rawfb_context *rawfb,
|
||||
{
|
||||
unsigned int c = nk_rawfb_color2int(col, rawfb->fb.pl);
|
||||
unsigned char *pixels = rawfb->fb.pixels;
|
||||
unsigned int *ptr;
|
||||
|
||||
pixels += y0 * rawfb->fb.pitch;
|
||||
ptr = (unsigned int *)pixels + x0;
|
||||
|
||||
if (y0 < rawfb->scissors.h && y0 >= rawfb->scissors.y &&
|
||||
x0 >= rawfb->scissors.x && x0 < rawfb->scissors.w)
|
||||
*ptr = c;
|
||||
x0 >= rawfb->scissors.x && x0 < rawfb->scissors.w) {
|
||||
|
||||
if (rawfb->fb.pl.bytesPerPixel == sizeof(unsigned int)) {
|
||||
*((unsigned int *)pixels + x0) = c;
|
||||
} else if (rawfb->fb.pl.bytesPerPixel == sizeof(unsigned short)) {
|
||||
*((unsigned short *)pixels + x0) = c;
|
||||
} else {
|
||||
*((unsigned char *)pixels + x0) = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -156,22 +135,29 @@ nk_rawfb_line_horizontal(const struct rawfb_context *rawfb,
|
||||
* It does not check for scissors or image borders.
|
||||
* The caller has to make sure it does no exceed bounds. */
|
||||
unsigned int i, n;
|
||||
unsigned int c[16];
|
||||
unsigned char c[16 * 4];
|
||||
unsigned char *pixels = rawfb->fb.pixels;
|
||||
unsigned int *ptr;
|
||||
unsigned int bpp = rawfb->fb.pl.bytesPerPixel;
|
||||
|
||||
pixels += y * rawfb->fb.pitch;
|
||||
ptr = (unsigned int *)pixels + x0;
|
||||
pixels += (y * rawfb->fb.pitch) + (x0 * bpp);
|
||||
|
||||
n = x1 - x0;
|
||||
for (i = 0; i < sizeof(c) / sizeof(c[0]); i++)
|
||||
c[i] = nk_rawfb_color2int(col, rawfb->fb.pl);
|
||||
n = (x1 - x0) * bpp;
|
||||
if (bpp == sizeof(unsigned int)) {
|
||||
for (i = 0; i < sizeof(c) / bpp; i++)
|
||||
((unsigned int *)c)[i] = nk_rawfb_color2int(col, rawfb->fb.pl);
|
||||
} else if (bpp == sizeof(unsigned short)) {
|
||||
for (i = 0; i < sizeof(c) / bpp; i++)
|
||||
((unsigned short *)c)[i] = nk_rawfb_color2int(col, rawfb->fb.pl);
|
||||
} else {
|
||||
for (i = 0; i < sizeof(c) / bpp; i++)
|
||||
((unsigned char *)c)[i] = nk_rawfb_color2int(col, rawfb->fb.pl);
|
||||
}
|
||||
|
||||
while (n > 16) {
|
||||
memcpy((void *)ptr, c, sizeof(c));
|
||||
n -= 16; ptr += 16;
|
||||
while (n > sizeof(c)) {
|
||||
memcpy((void*)pixels, c, sizeof(c));
|
||||
n -= sizeof(c); pixels += sizeof(c);
|
||||
} for (i = 0; i < n; i++)
|
||||
ptr[i] = c[i];
|
||||
pixels[i] = c[i];
|
||||
}
|
||||
|
||||
static void
|
||||
@ -180,16 +166,16 @@ nk_rawfb_img_setpixel(const struct rawfb_image *img,
|
||||
{
|
||||
unsigned int c = nk_rawfb_color2int(col, img->pl);
|
||||
unsigned char *ptr;
|
||||
unsigned int *pixel;
|
||||
NK_ASSERT(img);
|
||||
if (y0 < img->h && y0 >= 0 && x0 >= 0 && x0 < img->w) {
|
||||
ptr = (unsigned char *)img->pixels + (img->pitch * y0);
|
||||
pixel = (unsigned int *)ptr;
|
||||
|
||||
if (img->format == NK_FONT_ATLAS_ALPHA8) {
|
||||
ptr[x0] = col.a;
|
||||
if (img->pl.bytesPerPixel == sizeof(unsigned int)) {
|
||||
((unsigned int *)ptr)[x0] = c;
|
||||
} else if (img->pl.bytesPerPixel == sizeof(unsigned short)) {
|
||||
((unsigned short *)ptr)[x0] = c;
|
||||
} else {
|
||||
pixel[x0] = c;
|
||||
((unsigned char *)ptr)[x0] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -204,12 +190,15 @@ nk_rawfb_img_getpixel(const struct rawfb_image *img, const int x0, const int y0)
|
||||
if (y0 < img->h && y0 >= 0 && x0 >= 0 && x0 < img->w) {
|
||||
ptr = (unsigned char *)img->pixels + (img->pitch * y0);
|
||||
|
||||
if (img->format == NK_FONT_ATLAS_ALPHA8) {
|
||||
col.a = ptr[x0];
|
||||
col.b = col.g = col.r = 0xff;
|
||||
} else {
|
||||
if (img->pl.bytesPerPixel == sizeof(unsigned int)) {
|
||||
pixel = ((unsigned int *)ptr)[x0];
|
||||
col = nk_rawfb_int2color(pixel, img->pl);
|
||||
} else if (img->pl.bytesPerPixel == sizeof(unsigned short)) {
|
||||
pixel = ((unsigned short *)ptr)[x0];
|
||||
col = nk_rawfb_int2color(pixel, img->pl);
|
||||
} else {
|
||||
pixel = ((unsigned char *)ptr)[x0];
|
||||
col = nk_rawfb_int2color(pixel, img->pl);
|
||||
}
|
||||
} return col;
|
||||
}
|
||||
@ -823,32 +812,33 @@ nk_rawfb_clear(const struct rawfb_context *rawfb, const struct nk_color col)
|
||||
|
||||
NK_API struct rawfb_context*
|
||||
nk_rawfb_init(void *fb, void *tex_mem, const unsigned int w, const unsigned int h,
|
||||
const unsigned int pitch, const rawfb_pl pl)
|
||||
const unsigned int pitch, const struct rawfb_pl pl)
|
||||
{
|
||||
const void *tex;
|
||||
struct rawfb_context *rawfb;
|
||||
|
||||
rawfb = malloc(sizeof(struct rawfb_context));
|
||||
if (!rawfb)
|
||||
return NULL;
|
||||
|
||||
memset(rawfb, 0, sizeof(struct rawfb_context));
|
||||
rawfb->font_tex.pixels = tex_mem;
|
||||
rawfb->font_tex.format = NK_FONT_ATLAS_ALPHA8;
|
||||
rawfb->font_tex.w = rawfb->font_tex.h = 0;
|
||||
rawfb->font_tex.pl.bytesPerPixel = 1;
|
||||
rawfb->font_tex.pl.rshift = 0;
|
||||
rawfb->font_tex.pl.gshift = 0;
|
||||
rawfb->font_tex.pl.bshift = 0;
|
||||
rawfb->font_tex.pl.ashift = 0;
|
||||
rawfb->font_tex.pl.rloss = 8;
|
||||
rawfb->font_tex.pl.gloss = 8;
|
||||
rawfb->font_tex.pl.bloss = 8;
|
||||
rawfb->font_tex.pl.aloss = 0;
|
||||
rawfb->font_tex.w = rawfb->font_tex.h = rawfb->font_tex.pitch = 0;
|
||||
|
||||
rawfb->fb.pixels = fb;
|
||||
rawfb->fb.w = w;
|
||||
rawfb->fb.h = h;
|
||||
rawfb->fb.pl = pl;
|
||||
|
||||
if (pl == PIXEL_LAYOUT_RGBX_8888 || pl == PIXEL_LAYOUT_XRGB_8888) {
|
||||
rawfb->fb.format = NK_FONT_ATLAS_RGBA32;
|
||||
rawfb->fb.pitch = pitch;
|
||||
} else {
|
||||
perror("nk_rawfb_init(): Unsupported pixel layout.\n");
|
||||
free(rawfb);
|
||||
return NULL;
|
||||
}
|
||||
rawfb->fb.pl = pl;
|
||||
|
||||
if (0 == nk_init_default(&rawfb->ctx, 0)) {
|
||||
free(rawfb);
|
||||
@ -857,21 +847,13 @@ nk_rawfb_init(void *fb, void *tex_mem, const unsigned int w, const unsigned int
|
||||
|
||||
nk_font_atlas_init_default(&rawfb->atlas);
|
||||
nk_font_atlas_begin(&rawfb->atlas);
|
||||
tex = nk_font_atlas_bake(&rawfb->atlas, &rawfb->font_tex.w, &rawfb->font_tex.h, rawfb->font_tex.format);
|
||||
tex = nk_font_atlas_bake(&rawfb->atlas, &rawfb->font_tex.w, &rawfb->font_tex.h, NK_FONT_ATLAS_ALPHA8);
|
||||
if (!tex) {
|
||||
free(rawfb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch(rawfb->font_tex.format) {
|
||||
case NK_FONT_ATLAS_ALPHA8:
|
||||
rawfb->font_tex.pitch = rawfb->font_tex.w * 1;
|
||||
break;
|
||||
case NK_FONT_ATLAS_RGBA32:
|
||||
rawfb->font_tex.pitch = rawfb->font_tex.w * 4;
|
||||
break;
|
||||
};
|
||||
/* Store the font texture in tex scratch memory */
|
||||
memcpy(rawfb->font_tex.pixels, tex, rawfb->font_tex.pitch * rawfb->font_tex.h);
|
||||
nk_font_atlas_end(&rawfb->atlas, nk_handle_ptr(NULL), NULL);
|
||||
if (rawfb->atlas.default_font)
|
||||
@ -1036,7 +1018,7 @@ nk_rawfb_resize_fb(struct rawfb_context *rawfb,
|
||||
const unsigned int w,
|
||||
const unsigned int h,
|
||||
const unsigned int pitch,
|
||||
const rawfb_pl pl)
|
||||
const struct rawfb_pl pl)
|
||||
{
|
||||
rawfb->fb.w = w;
|
||||
rawfb->fb.h = h;
|
||||
|
@ -2,7 +2,7 @@ CFLAGS=`sdl2-config --cflags --libs` -std=c89 -Wall -Wextra -pedantic -Wno-unu
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
demo: main.c nuklear_sdl_rawfb.h
|
||||
demo: main.c ../nuklear_rawfb.h
|
||||
$(CC) -o demo *.c $(CFLAGS) -lrt -lm
|
||||
|
||||
clean:
|
||||
|
@ -20,7 +20,7 @@
|
||||
#define NK_INCLUDE_SOFTWARE_FONT
|
||||
#include "../../../nuklear.h"
|
||||
#define NK_RAWFB_IMPLEMENTATION
|
||||
#include "nuklear_sdl_rawfb.h"
|
||||
#include "../nuklear_rawfb.h"
|
||||
|
||||
/* ===============================================================
|
||||
*
|
||||
@ -132,6 +132,8 @@ int main(int argc, char **argv)
|
||||
struct nk_vec2 vec;
|
||||
struct nk_rect bounds = {40,40,0,0};
|
||||
struct rawfb_context *context;
|
||||
struct rawfb_pl pl;
|
||||
unsigned char tex_scratch[512 * 512];
|
||||
|
||||
SDL_DisplayMode dm;
|
||||
SDL_Window *window;
|
||||
@ -164,8 +166,17 @@ int main(int argc, char **argv)
|
||||
|
||||
surface = SDL_CreateRGBSurfaceWithFormat(0, dm.w-200, dm.h-200, 32, SDL_PIXELFORMAT_ARGB8888);
|
||||
|
||||
pl.bytesPerPixel = surface->format->BytesPerPixel;
|
||||
pl.rshift = surface->format->Rshift;
|
||||
pl.gshift = surface->format->Gshift;
|
||||
pl.bshift = surface->format->Bshift;
|
||||
pl.ashift = surface->format->Ashift;
|
||||
pl.rloss = surface->format->Rloss;
|
||||
pl.gloss = surface->format->Gloss;
|
||||
pl.bloss = surface->format->Bloss;
|
||||
pl.aloss = surface->format->Aloss;
|
||||
|
||||
context = nk_rawfb_init(surface, 13.0f);
|
||||
context = nk_rawfb_init(surface->pixels, tex_scratch, surface->w, surface->h, surface->pitch, pl);
|
||||
|
||||
|
||||
while(1)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -450,6 +450,7 @@ int main ()
|
||||
struct nk_wayland nk_wayland_ctx;
|
||||
struct wl_registry *registry;
|
||||
int running = 1;
|
||||
struct rawfb_pl pl;
|
||||
|
||||
//1. Initialize display
|
||||
nk_wayland_ctx.display = wl_display_connect (NULL);
|
||||
@ -495,7 +496,17 @@ int main ()
|
||||
wl_surface_attach (nk_wayland_ctx.surface, nk_wayland_ctx.front_buffer, 0, 0);
|
||||
wl_surface_commit (nk_wayland_ctx.surface);
|
||||
|
||||
nk_rawfb_init(nk_wayland_ctx.data, nk_wayland_ctx.tex_scratch, WIDTH, HEIGHT, WIDTH*4, PIXEL_LAYOUT_XRGB_8888);
|
||||
pl.bytesPerPixel = 4;
|
||||
pl.ashift = 24;
|
||||
pl.rshift = 16;
|
||||
pl.gshift = 8;
|
||||
pl.bshift = 0;
|
||||
pl.aloss = 0;
|
||||
pl.rloss = 0;
|
||||
pl.gloss = 0;
|
||||
pl.bloss = 0;
|
||||
|
||||
nk_rawfb_init(nk_wayland_ctx.data, nk_wayland_ctx.tex_scratch, WIDTH, HEIGHT, WIDTH*4, pl);
|
||||
|
||||
|
||||
//4. rendering UI
|
||||
|
@ -156,7 +156,7 @@ main(void)
|
||||
XWindow xw;
|
||||
struct rawfb_context *rawfb;
|
||||
void *fb = NULL;
|
||||
rawfb_pl pl;
|
||||
struct rawfb_pl pl;
|
||||
unsigned char tex_scratch[512 * 512];
|
||||
|
||||
/* X11 */
|
||||
|
@ -35,7 +35,7 @@
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
NK_API int nk_xlib_init(Display *dpy, Visual *vis, int screen, Window root, unsigned int w, unsigned int h, void **fb, rawfb_pl *pl);
|
||||
NK_API int nk_xlib_init(Display *dpy, Visual *vis, int screen, Window root, unsigned int w, unsigned int h, void **fb, struct rawfb_pl *pl);
|
||||
NK_API int nk_xlib_handle_event(Display *dpy, int screen, Window win, XEvent *evt, struct rawfb_context *rawfb);
|
||||
NK_API void nk_xlib_render(Drawable screen);
|
||||
NK_API void nk_xlib_shutdown(void);
|
||||
@ -74,7 +74,7 @@ static struct {
|
||||
|
||||
NK_API int
|
||||
nk_xlib_init(Display *dpy, Visual *vis, int screen, Window root,
|
||||
unsigned int w, unsigned int h, void **fb, rawfb_pl *pl)
|
||||
unsigned int w, unsigned int h, void **fb, struct rawfb_pl *pl)
|
||||
{
|
||||
unsigned int depth = XDefaultDepth(dpy, screen);
|
||||
xlib.dpy = dpy;
|
||||
@ -138,22 +138,15 @@ nk_xlib_init(Display *dpy, Visual *vis, int screen, Window root,
|
||||
xlib.gc = XDefaultGC(dpy, screen);
|
||||
*fb = xlib.ximg->data;
|
||||
|
||||
if (xlib.ximg->red_mask == 0xff0000 &&
|
||||
xlib.ximg->green_mask == 0xff00 &&
|
||||
xlib.ximg->blue_mask == 0xff &&
|
||||
xlib.ximg->bits_per_pixel == 32) {
|
||||
*pl = PIXEL_LAYOUT_XRGB_8888;
|
||||
}
|
||||
else if (xlib.ximg->red_mask == 0xff000000 &&
|
||||
xlib.ximg->green_mask == 0xff0000 &&
|
||||
xlib.ximg->blue_mask == 0xff00 &&
|
||||
xlib.ximg->bits_per_pixel == 32) {
|
||||
*pl = PIXEL_LAYOUT_RGBX_8888;
|
||||
}
|
||||
else {
|
||||
perror("nk_xlib_init(): Unrecognized pixel layout.\n");
|
||||
return 0;
|
||||
}
|
||||
pl->bytesPerPixel = xlib.ximg->bits_per_pixel / 8;
|
||||
pl->rshift = __builtin_ctzl(xlib.ximg->red_mask);
|
||||
pl->gshift = __builtin_ctzl(xlib.ximg->green_mask);
|
||||
pl->bshift = __builtin_ctzl(xlib.ximg->blue_mask);
|
||||
pl->ashift = 0;
|
||||
pl->rloss = 8 - __builtin_popcount(xlib.ximg->red_mask);
|
||||
pl->gloss = 8 - __builtin_popcount(xlib.ximg->green_mask);
|
||||
pl->bloss = 8 - __builtin_popcount(xlib.ximg->blue_mask);
|
||||
pl->aloss = 8;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -257,7 +250,7 @@ nk_xlib_handle_event(Display *dpy, int screen, Window win, XEvent *evt, struct r
|
||||
} else if (evt->type == Expose || evt->type == ConfigureNotify) {
|
||||
/* Window resize handler */
|
||||
void *fb;
|
||||
rawfb_pl pl;
|
||||
struct rawfb_pl pl;
|
||||
unsigned int width, height;
|
||||
XWindowAttributes attr;
|
||||
XGetWindowAttributes(dpy, win, &attr);
|
||||
|
Loading…
Reference in New Issue
Block a user