summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fb.c295
-rw-r--r--graphics.h40
-rw-r--r--internal.h19
-rw-r--r--render.c63
-rw-r--r--util.c14
-rw-r--r--viewport.c22
6 files changed, 345 insertions, 108 deletions
diff --git a/fb.c b/fb.c
index 1c56c08..4193043 100644
--- a/fb.c
+++ b/fb.c
@@ -14,7 +14,7 @@
* see https://www.scale2x.it/algorithm
*/
static void
-scale2x_filter(ulong *dst, Framebuf *fb, Point sp)
+scale2x_filter(ulong *dst, Raster *fb, Point sp)
{
ulong B, D, E, F, H;
@@ -34,7 +34,7 @@ scale2x_filter(ulong *dst, Framebuf *fb, Point sp)
}
static void
-scale3x_filter(ulong *dst, Framebuf *fb, Point sp)
+scale3x_filter(ulong *dst, Raster *fb, Point sp)
{
ulong A, B, C, D, E, F, G, H, I;
@@ -93,153 +93,187 @@ scale3x_filter(ulong *dst, Framebuf *fb, Point sp)
//}
static void
-upscaledraw(Framebufctl *ctl, Image *dst, Point off, Point scale)
+fb_createraster(Framebuf *fb, char *name, ulong chan)
{
- void (*filter)(ulong*, Framebuf*, Point);
- Framebuf *fb;
+ Raster *r;
+
+ assert(name != nil);
+
+ /*
+ * TODO might be better to keep a tail so it's O(1)
+ *
+ * in practice though, most users won't ever create
+ * more than ten extra rasters.
+ */
+ r = fb->rasters;
+ while(r->next != nil)
+ r = r->next;
+ r->next = allocraster(name, fb->r, chan);
+}
+
+static Raster *
+fb_fetchraster(Framebuf *fb, char *name)
+{
+ Raster *r;
+
+ r = fb->rasters;
+ if(name == nil)
+ return r;
+
+ while((r = r->next) != nil)
+ if(strcmp(name, r->name) == 0)
+ return r;
+ return nil;
+
+}
+
+static void
+upscaledraw(Raster *fb, Image *dst, Point off, Point scale, uint filter)
+{
+ void (*filterfn)(ulong*, Raster*, Point);
Rectangle blkr;
Point sp, dp;
ulong *blk;
- filter = nil;
+ filterfn = nil;
blk = emalloc(scale.x*scale.y*4);
blkr = Rect(0,0,scale.x,scale.y);
- qlock(ctl);
- fb = ctl->getfb(ctl);
-
- switch(ctl->upfilter){
+ switch(filter){
case UFScale2x:
if(scale.x == scale.y && scale.y == 2)
- filter = scale2x_filter;
+ filterfn = scale2x_filter;
break;
case UFScale3x:
if(scale.x == scale.y && scale.y == 3)
- filter = scale3x_filter;
+ filterfn = scale3x_filter;
break;
}
for(sp.y = fb->r.min.y, dp.y = dst->r.min.y+off.y; sp.y < fb->r.max.y; sp.y++, dp.y += scale.y)
for(sp.x = fb->r.min.x, dp.x = dst->r.min.x+off.x; sp.x < fb->r.max.x; sp.x++, dp.x += scale.x){
- if(filter != nil)
- filter(blk, fb, sp);
+ if(filterfn != nil)
+ filterfn(blk, fb, sp);
else
memsetl(blk, getpixel(fb, sp), scale.x*scale.y);
loadimage(dst, rectaddpt(blkr, dp), (uchar*)blk, scale.x*scale.y*4);
}
- qunlock(ctl);
free(blk);
}
static void
-framebufctl_draw(Framebufctl *ctl, Image *dst, Point off, Point scale)
+framebufctl_draw(Framebufctl *ctl, Image *dst, char *name, Point off, Point scale)
{
Framebuf *fb;
+ Raster *r;
Rectangle sr, dr;
- int y;
+
+ qlock(ctl);
+ fb = ctl->getfb(ctl);
+
+ r = fb->rasters;
+ if(name != nil)
+ do r = r->next; while(r != nil && strcmp(name, r->name) != 0);
+ if(r == nil){
+ qunlock(ctl);
+ return;
+ }
if(scale.x > 1 || scale.y > 1){
- upscaledraw(ctl, dst, off, scale);
+ upscaledraw(r, dst, off, scale, ctl->upfilter);
+ qunlock(ctl);
return;
}
- qlock(ctl);
- fb = ctl->getfb(ctl);
sr = rectaddpt(fb->r, off);
dr = rectsubpt(dst->r, dst->r.min);
if(rectinrect(sr, dr))
- loadimage(dst, rectaddpt(sr, dst->r.min), (uchar*)fb->cb, Dx(fb->r)*Dy(fb->r)*4);
+ loadimage(dst, rectaddpt(sr, dst->r.min), (uchar*)r->data, Dx(fb->r)*Dy(r->r)*4);
else if(rectclip(&sr, dr)){
dr = sr;
dr.max.y = dr.min.y + 1;
/* remove offset to get the actual rect within the framebuffer */
sr = rectsubpt(sr, off);
- for(y = sr.min.y; y < sr.max.y; y++, dr.min.y++, dr.max.y++)
- loadimage(dst, rectaddpt(dr, dst->r.min), (uchar*)&fb->cb[y*Dx(fb->r) + sr.min.x], Dx(dr)*4);
+ for(; sr.min.y < sr.max.y; sr.min.y++, dr.min.y++, dr.max.y++)
+ loadimage(dst, rectaddpt(dr, dst->r.min), rasterbyteaddr(r, sr.min), Dx(dr)*4);
}
qunlock(ctl);
}
static void
-upscalememdraw(Framebufctl *ctl, Memimage *dst, Point off, Point scale)
+upscalememdraw(Raster *fb, Memimage *dst, Point off, Point scale, uint filter)
{
- void (*filter)(ulong*, Framebuf*, Point);
- Framebuf *fb;
+ void (*filterfn)(ulong*, Raster*, Point);
Rectangle blkr;
Point sp, dp;
ulong *blk;
- filter = nil;
+ filterfn = nil;
blk = emalloc(scale.x*scale.y*4);
blkr = Rect(0,0,scale.x,scale.y);
- qlock(ctl);
- fb = ctl->getfb(ctl);
-
- switch(ctl->upfilter){
+ switch(filter){
case UFScale2x:
if(scale.x == scale.y && scale.y == 2)
- filter = scale2x_filter;
+ filterfn = scale2x_filter;
break;
case UFScale3x:
if(scale.x == scale.y && scale.y == 3)
- filter = scale3x_filter;
+ filterfn = scale3x_filter;
break;
}
for(sp.y = fb->r.min.y, dp.y = dst->r.min.y+off.y; sp.y < fb->r.max.y; sp.y++, dp.y += scale.y)
for(sp.x = fb->r.min.x, dp.x = dst->r.min.x+off.x; sp.x < fb->r.max.x; sp.x++, dp.x += scale.x){
- if(filter != nil)
- filter(blk, fb, sp);
+ if(filterfn != nil)
+ filterfn(blk, fb, sp);
else
memsetl(blk, getpixel(fb, sp), scale.x*scale.y);
loadmemimage(dst, rectaddpt(blkr, dp), (uchar*)blk, scale.x*scale.y*4);
}
- qunlock(ctl);
free(blk);
}
static void
-framebufctl_memdraw(Framebufctl *ctl, Memimage *dst, Point off, Point scale)
+framebufctl_memdraw(Framebufctl *ctl, Memimage *dst, char *name, Point off, Point scale)
{
Framebuf *fb;
+ Raster *r;
Rectangle sr, dr;
- int y;
+
+ qlock(ctl);
+ fb = ctl->getfb(ctl);
+
+ r = fb->rasters;
+ if(name != nil)
+ do r = r->next; while(r != nil && strcmp(name, r->name) != 0);
+ if(r == nil){
+ qunlock(ctl);
+ return;
+ }
if(scale.x > 1 || scale.y > 1){
- upscalememdraw(ctl, dst, off, scale);
+ upscalememdraw(r, dst, off, scale, ctl->upfilter);
+ qunlock(ctl);
return;
}
- qlock(ctl);
- fb = ctl->getfb(ctl);
sr = rectaddpt(fb->r, off);
dr = rectsubpt(dst->r, dst->r.min);
if(rectinrect(sr, dr))
- loadmemimage(dst, rectaddpt(sr, dst->r.min), (uchar*)fb->cb, Dx(fb->r)*Dy(fb->r)*4);
+ loadmemimage(dst, rectaddpt(sr, dst->r.min), (uchar*)r->data, Dx(fb->r)*Dy(r->r)*4);
else if(rectclip(&sr, dr)){
dr = sr;
dr.max.y = dr.min.y + 1;
/* remove offset to get the actual rect within the framebuffer */
sr = rectsubpt(sr, off);
- for(y = sr.min.y; y < sr.max.y; y++, dr.min.y++, dr.max.y++)
- loadmemimage(dst, rectaddpt(dr, dst->r.min), (uchar*)&fb->cb[y*Dx(fb->r) + sr.min.x], Dx(dr)*4);
+ for(; sr.min.y < sr.max.y; sr.min.y++, dr.min.y++, dr.max.y++)
+ loadmemimage(dst, rectaddpt(dr, dst->r.min), rasterbyteaddr(r, sr.min), Dx(dr)*4);
}
qunlock(ctl);
}
static void
-framebufctl_drawnormals(Framebufctl *ctl, Image *dst)
-{
- Framebuf *fb;
-
- qlock(ctl);
- fb = ctl->getfb(ctl);
- loadimage(dst, rectaddpt(fb->r, dst->r.min), (uchar*)fb->nb, Dx(fb->r)*Dy(fb->r)*4);
- qunlock(ctl);
-}
-
-static void
framebufctl_swap(Framebufctl *ctl)
{
qlock(ctl);
@@ -261,13 +295,18 @@ static void
framebufctl_reset(Framebufctl *ctl, ulong clr)
{
Framebuf *fb;
+ Raster *r;
/* address the back buffer—resetting the front buffer is VERBOTEN */
fb = ctl->getbb(ctl);
resetAbuf(&fb->abuf);
- memsetl(fb->nb, 0, Dx(fb->r)*Dy(fb->r));
- memsetf(fb->zb, Inf(-1), Dx(fb->r)*Dy(fb->r));
- memsetl(fb->cb, rgba2xrgb(clr), Dx(fb->r)*Dy(fb->r));
+
+ r = fb->rasters; /* color buffer */
+ clearraster(r, rgba2xrgb(clr));
+ r = r->next; /* z-buffer */
+ fclearraster(r, Inf(-1));
+ while((r = r->next) != nil)
+ clearraster(r, 0); /* every other raster */
}
static Framebuf *
@@ -282,6 +321,126 @@ framebufctl_getbb(Framebufctl *ctl)
return ctl->fb[ctl->idx^1]; /* back buffer */
}
+static void
+framebufctl_createraster(Framebufctl *ctl, char *name, ulong chan)
+{
+ Framebuf *fb;
+ int i;
+
+ for(i = 0; i < 2; i++){
+ fb = ctl->fb[i];
+ fb->createraster(fb, name, chan);
+ }
+}
+
+static Raster *
+framebufctl_fetchraster(Framebufctl *ctl, char *name)
+{
+ Framebuf *fb;
+
+ fb = ctl->getfb(ctl);
+ return fb->fetchraster(fb, name);
+}
+
+Raster *
+allocraster(char *name, Rectangle rr, ulong chan)
+{
+ Raster *r;
+
+ assert(chan <= FLOAT32);
+
+ r = emalloc(sizeof *r);
+ memset(r, 0, sizeof *r);
+ if(name != nil && (r->name = strdup(name)) == nil)
+ sysfatal("strdup: %r");
+ r->chan = chan;
+ r->r = rr;
+ r->data = emalloc(Dx(rr)*Dy(rr)*sizeof(*r->data));
+ return r;
+}
+
+void
+clearraster(Raster *r, ulong v)
+{
+ memsetl(r->data, v, Dx(r->r)*Dy(r->r));
+}
+
+void
+fclearraster(Raster *r, float v)
+{
+ memsetf(r->data, v, Dx(r->r)*Dy(r->r));
+}
+
+uchar *
+rasterbyteaddr(Raster *r, Point p)
+{
+ return (uchar*)&r->data[p.y*Dx(r->r) + p.x];
+}
+
+void
+rasterput(Raster *r, Point p, void *v)
+{
+ switch(r->chan){
+ case COLOR32:
+ *(ulong*)rasterbyteaddr(r, p) = *(ulong*)v;
+ break;
+ case FLOAT32:
+ *(float*)rasterbyteaddr(r, p) = *(float*)v;
+ break;
+ }
+}
+
+void
+rasterget(Raster *r, Point p, void *v)
+{
+ switch(r->chan){
+ case COLOR32:
+ *(ulong*)v = *(ulong*)rasterbyteaddr(r, p);
+ break;
+ case FLOAT32:
+ *(float*)v = *(float*)rasterbyteaddr(r, p);
+ break;
+ }
+}
+
+void
+rasterputcolor(Raster *r, Point p, ulong c)
+{
+ rasterput(r, p, &c);
+}
+
+ulong
+rastergetcolor(Raster *r, Point p)
+{
+ ulong c;
+
+ rasterget(r, p, &c);
+ return c;
+}
+
+void
+rasterputfloat(Raster *r, Point p, float v)
+{
+ rasterput(r, p, &v);
+}
+
+float
+rastergetfloat(Raster *r, Point p)
+{
+ float v;
+
+ rasterget(r, p, &v);
+ return v;
+}
+
+void
+freeraster(Raster *r)
+{
+ free(r->data);
+ free(r->name);
+ free(r);
+}
+
Framebuf *
mkfb(Rectangle r)
{
@@ -289,20 +448,23 @@ mkfb(Rectangle r)
fb = emalloc(sizeof *fb);
memset(fb, 0, sizeof *fb);
- fb->cb = emalloc(Dx(r)*Dy(r)*4);
- fb->zb = emalloc(Dx(r)*Dy(r)*sizeof(*fb->zb));
- memsetf(fb->zb, Inf(-1), Dx(r)*Dy(r));
- fb->nb = emalloc(Dx(r)*Dy(r)*4);
+ fb->rasters = allocraster(nil, r, COLOR32);
+ fb->rasters->next = allocraster("z-buffer", r, FLOAT32);
fb->r = r;
+ fb->createraster = fb_createraster;
+ fb->fetchraster = fb_fetchraster;
return fb;
}
void
rmfb(Framebuf *fb)
{
- free(fb->nb);
- free(fb->zb);
- free(fb->cb);
+ Raster *r, *nr;
+
+ for(r = fb->rasters; r != nil; r = nr){
+ nr = r->next;
+ freeraster(r);
+ }
free(fb);
}
@@ -317,9 +479,10 @@ mkfbctl(Rectangle r)
fc->fb[1] = mkfb(r);
fc->draw = framebufctl_draw;
fc->memdraw = framebufctl_memdraw;
- fc->drawnormals = framebufctl_drawnormals;
fc->swap = framebufctl_swap;
fc->reset = framebufctl_reset;
+ fc->createraster = framebufctl_createraster;
+ fc->fetchraster = framebufctl_fetchraster;
fc->getfb = framebufctl_getfb;
fc->getbb = framebufctl_getbb;
return fc;
diff --git a/graphics.h b/graphics.h
index 96b3159..106f467 100644
--- a/graphics.h
+++ b/graphics.h
@@ -23,6 +23,10 @@ enum {
LightDirectional,
LightSpot,
+ /* raster formats */
+ COLOR32 = 0,
+ FLOAT32,
+
/* texture formats */
RAWTexture = 0, /* unmanaged */
sRGBTexture,
@@ -50,6 +54,7 @@ typedef struct Model Model;
typedef struct Entity Entity;
typedef struct Scene Scene;
typedef struct VSparams VSparams;
+typedef struct FSoutput FSoutput;
typedef struct FSparams FSparams;
typedef struct SUparams SUparams;
typedef struct Shadertab Shadertab;
@@ -59,6 +64,7 @@ typedef struct Renderjob Renderjob;
typedef struct Fragment Fragment;
typedef struct Astk Astk;
typedef struct Abuf Abuf;
+typedef struct Raster Raster;
typedef struct Framebuf Framebuf;
typedef struct Framebufctl Framebufctl;
typedef struct Viewport Viewport;
@@ -205,6 +211,8 @@ struct FSparams
SUparams *su;
Point p;
Vertex v; /* only for the attributes (varyings) */
+
+ void (*toraster)(FSparams*, char*, void*);
};
/* shader unit params */
@@ -278,13 +286,24 @@ struct Abuf
ulong nact;
};
+struct Raster
+{
+ Rectangle r;
+ char *name;
+ ulong chan;
+ ulong *data;
+
+ Raster *next;
+};
+
struct Framebuf
{
- ulong *cb; /* color buffer */
- float *zb; /* z/depth buffer */
- ulong *nb; /* normals buffer (DBG only) */
- Abuf abuf; /* A-buffer */
Rectangle r;
+ Raster *rasters; /* [0] color, [1] depth, [n] user-defined */
+ Abuf abuf; /* A-buffer */
+
+ void (*createraster)(Framebuf*, char*, ulong);
+ Raster *(*fetchraster)(Framebuf*, char*);
};
struct Framebufctl
@@ -294,11 +313,12 @@ struct Framebufctl
uint idx; /* front buffer index */
uint upfilter; /* upscaling filter */
- void (*draw)(Framebufctl*, Image*, Point, Point);
- void (*memdraw)(Framebufctl*, Memimage*, Point, Point);
- void (*drawnormals)(Framebufctl*, Image*);
+ void (*draw)(Framebufctl*, Image*, char*, Point, Point);
+ void (*memdraw)(Framebufctl*, Memimage*, char*, Point, Point);
void (*swap)(Framebufctl*);
void (*reset)(Framebufctl*, ulong);
+ void (*createraster)(Framebufctl*, char*, ulong);
+ Raster *(*fetchraster)(Framebufctl*, char*);
Framebuf *(*getfb)(Framebufctl*);
Framebuf *(*getbb)(Framebufctl*);
};
@@ -309,13 +329,15 @@ struct Viewport
Framebufctl *fbctl;
Rectangle r;
- void (*draw)(Viewport*, Image*);
- void (*memdraw)(Viewport*, Memimage*);
+ void (*draw)(Viewport*, Image*, char*);
+ void (*memdraw)(Viewport*, Memimage*, char*);
void (*setscale)(Viewport*, double, double);
void (*setscalefilter)(Viewport*, int);
Framebuf *(*getfb)(Viewport*);
int (*getwidth)(Viewport*);
int (*getheight)(Viewport*);
+ void (*createraster)(Viewport*, char*, ulong);
+ Raster *(*fetchraster)(Viewport*, char*);
};
struct Camera
diff --git a/internal.h b/internal.h
index 3190a19..c204d9a 100644
--- a/internal.h
+++ b/internal.h
@@ -38,6 +38,17 @@ void *erealloc(void*, ulong);
Memimage *eallocmemimage(Rectangle, ulong);
/* fb */
+Raster *allocraster(char*, Rectangle, ulong);
+void clearraster(Raster*, ulong);
+void fclearraster(Raster*, float);
+uchar *rasterbyteaddr(Raster*, Point);
+void rasterput(Raster*, Point, void*);
+void rasterget(Raster*, Point, void*);
+void rasterputcolor(Raster*, Point, ulong);
+ulong rastergetcolor(Raster*, Point);
+void rasterputfloat(Raster*, Point, float);
+float rastergetfloat(Raster*, Point);
+void freeraster(Raster*);
Framebuf *mkfb(Rectangle);
void rmfb(Framebuf*);
Framebufctl *mkfbctl(Rectangle);
@@ -61,10 +72,10 @@ void memsetl(void*, ulong, usize);
/* nanosec */
uvlong nanosec(void);
-/* ulong getpixel(Framebuf *fb, Point p) */
-#define getpixel(fb, p) (((fb)->cb)[Dx((fb)->r)*(p).y + (p).x])
-/* void putpixel(Framebuf *fb, Point p, ulong c) */
-#define putpixel(fb, p, c) (((fb)->cb)[Dx((fb)->r)*(p).y + (p).x] = (c))
+#define getpixel(fb, p) rastergetcolor(fb, p)
+#define putpixel(fb, p, c) rasterputcolor(fb, p, c)
+#define getdepth(fb, p) rastergetfloat(fb, p)
+#define putdepth(fb, p, z) rasterputfloat(fb, p, z)
/* void SWAP(type t, type *a, type *b) */
#define SWAP(t, a, b) {t tmp; tmp = *(a); *(a) = *(b); *(b) = tmp;}
diff --git a/render.c b/render.c
index 71edf99..7b1bbb8 100644
--- a/render.c
+++ b/render.c
@@ -35,7 +35,7 @@ ul2col(ulong l)
}
static void
-pixel(Framebuf *fb, Point p, Color c, int blend)
+pixel(Raster *fb, Point p, Color c, int blend)
{
Color dc;
@@ -50,13 +50,31 @@ pixel(Framebuf *fb, Point p, Color c, int blend)
}
static void
-pixeln(Framebuf *fb, Point p, Color c)
+fsparams_toraster(FSparams *sp, char *rname, void *v)
{
- ulong *dst;
-
- dst = fb->nb;
- c.a = 1;
- dst[Dx(fb->r)*p.y + p.x] = col2ul(c);
+ Framebuf *fb;
+ Raster *r;
+ ulong c, z;
+
+ /* keep the user away from the color buffer */
+ if(rname == nil || v == nil)
+ return;
+
+ fb = sp->su->fb;
+ r = fb->fetchraster(fb, rname);
+ if(r == nil)
+ return;
+
+ switch(r->chan){
+ case COLOR32:
+ c = col2ul(*(Color*)v);
+ rasterput(r, sp->p, &c);
+ break;
+ case FLOAT32:
+ z = *(float*)v;
+ rasterput(r, sp->p, &z);
+ break;
+ }
}
static int
@@ -117,16 +135,19 @@ squashAbuf(Framebuf *fb, int blend)
{
Abuf *buf;
Astk *stk;
+ Raster *cr, *zr;
int i, j;
buf = &fb->abuf;
+ cr = fb->rasters;
+ zr = cr->next;
for(i = 0; i < buf->nact; i++){
stk = buf->act[i];
j = stk->size;
while(j--)
- pixel(fb, stk->p, stk->items[j].c, blend);
+ pixel(cr, stk->p, stk->items[j].c, blend);
/* write to the depth buffer as well */
- fb->zb[stk->p.x + stk->p.y*Dx(fb->r)] = stk->items[0].z;
+ putdepth(zr, stk->p, stk->items[0].z);
}
}
@@ -149,6 +170,7 @@ static void
rasterize(Rastertask *task)
{
SUparams *params;
+ Raster *cr, *zr;
Primitive prim;
FSparams fsp;
Triangle2 t;
@@ -164,6 +186,10 @@ rasterize(Rastertask *task)
prim = task->p;
fsp.su = params;
memset(&fsp.v, 0, sizeof fsp.v);
+ fsp.toraster = fsparams_toraster;
+
+ cr = params->fb->rasters;
+ zr = cr->next;
switch(prim.type){
case PPoint:
@@ -171,9 +197,9 @@ rasterize(Rastertask *task)
z = fclamp(prim.v[0].p.z, 0, 1);
if(params->camera->enabledepth){
- if(z <= params->fb->zb[p.x + p.y*Dx(params->fb->r)])
+ if(z <= getdepth(zr, p))
break;
- params->fb->zb[p.x + p.y*Dx(params->fb->r)] = z;
+ putdepth(zr, p, z);
}
fsp.v = dupvertex(&prim.v[0]);
@@ -182,7 +208,7 @@ rasterize(Rastertask *task)
if(params->camera->enableAbuff)
pushtoAbuf(params->fb, p, c, z);
else
- pixel(params->fb, p, c, params->camera->enableblend);
+ pixel(cr, p, c, params->camera->enableblend);
delvattrs(&fsp.v);
break;
case PLine:
@@ -220,9 +246,9 @@ rasterize(Rastertask *task)
z = flerp(prim.v[0].p.z, prim.v[1].p.z, perc);
/* TODO get rid of the bounds check and make sure the clipping doesn't overflow */
if(params->camera->enabledepth){
- if(!ptinrect(p, params->fb->r) || z <= params->fb->zb[p.x + p.y*Dx(params->fb->r)])
+ if(!ptinrect(p, params->fb->r) || z <= getdepth(zr, p))
goto discard;
- params->fb->zb[p.x + p.y*Dx(params->fb->r)] = z;
+ putdepth(zr, p, z);
}
/* interpolate z⁻¹ and get actual z */
@@ -238,7 +264,7 @@ rasterize(Rastertask *task)
if(params->camera->enableAbuff)
pushtoAbuf(params->fb, p, c, z);
else
- pixel(params->fb, p, c, params->camera->enableblend);
+ pixel(cr, p, c, params->camera->enableblend);
delvattrs(&fsp.v);
discard:
if(steep) SWAP(int, &p.x, &p.y);
@@ -272,9 +298,9 @@ discard:
z = fberp(prim.v[0].p.z, prim.v[1].p.z, prim.v[2].p.z, bc);
if(params->camera->enabledepth){
- if(z <= params->fb->zb[p.x + p.y*Dx(params->fb->r)])
+ if(z <= getdepth(zr, p))
continue;
- params->fb->zb[p.x + p.y*Dx(params->fb->r)] = z;
+ putdepth(zr, p, z);
}
/* interpolate z⁻¹ and get actual z */
@@ -292,8 +318,7 @@ discard:
if(params->camera->enableAbuff)
pushtoAbuf(params->fb, p, c, z);
else
- pixel(params->fb, p, c, params->camera->enableblend);
- pixeln(params->fb, p, fsp.v.n);
+ pixel(cr, p, c, params->camera->enableblend);
delvattrs(&fsp.v);
}
break;
diff --git a/util.c b/util.c
index 4568eac..7335819 100644
--- a/util.c
+++ b/util.c
@@ -23,19 +23,21 @@ modulapt3(Point3 a, Point3 b)
void
memsetf(void *dp, float v, usize len)
{
- float *p, *ep;
+ float *p;
- for(p = dp, ep = p+len; p < ep; p++)
- *p = v;
+ p = dp;
+ while(len--)
+ *p++ = v;
}
void
memsetl(void *dp, ulong v, usize len)
{
- ulong *p, *ep;
+ ulong *p;
- for(p = dp, ep = p+len; p < ep; p++)
- *p = v;
+ p = dp;
+ while(len--)
+ *p++ = v;
}
Memimage *
diff --git a/viewport.c b/viewport.c
index 5214e53..02987e2 100644
--- a/viewport.c
+++ b/viewport.c
@@ -9,7 +9,7 @@
#include "internal.h"
static void
-viewport_draw(Viewport *v, Image *dst)
+viewport_draw(Viewport *v, Image *dst, char *rname)
{
Point off, scale;
@@ -18,11 +18,11 @@ viewport_draw(Viewport *v, Image *dst)
scale.x = max(v->bx.x, 1);
scale.y = max(v->by.y, 1);
- v->fbctl->draw(v->fbctl, dst, off, scale);
+ v->fbctl->draw(v->fbctl, dst, rname, off, scale);
}
static void
-viewport_memdraw(Viewport *v, Memimage *dst)
+viewport_memdraw(Viewport *v, Memimage *dst, char *rname)
{
Point off, scale;
@@ -31,7 +31,7 @@ viewport_memdraw(Viewport *v, Memimage *dst)
scale.x = max(v->bx.x, 1);
scale.y = max(v->by.y, 1);
- v->fbctl->memdraw(v->fbctl, dst, off, scale);
+ v->fbctl->memdraw(v->fbctl, dst, rname, off, scale);
}
static void
@@ -67,6 +67,18 @@ viewport_getheight(Viewport *v)
return Dy(v->r)*v->by.y;
}
+static void
+viewport_createraster(Viewport *v, char *name, ulong chan)
+{
+ v->fbctl->createraster(v->fbctl, name, chan);
+}
+
+static Raster *
+viewport_fetchraster(Viewport *v, char *name)
+{
+ return v->fbctl->fetchraster(v->fbctl, name);
+}
+
Viewport *
mkviewport(Rectangle r)
{
@@ -90,6 +102,8 @@ mkviewport(Rectangle r)
v->getfb = viewport_getfb;
v->getwidth = viewport_getwidth;
v->getheight = viewport_getheight;
+ v->createraster = viewport_createraster;
+ v->fetchraster = viewport_fetchraster;
return v;
}