Orange: more float buffer support;

- Image textures use float colors now, when present. Works for mipmap too,
  and for AO skycolor (probes)
- Backbuffer option uses float buffers too. Note that rendering OSA will
  resample the backbuffer, filtering it... will need to be solved with the
  new composit stage
- LMB sampling in image window now shows float color too

+ bugfix in imbuf, filtering for float buffers had an error.
This commit is contained in:
2006-01-11 18:39:19 +00:00
parent ebe728d8b5
commit b92fa41516
7 changed files with 186 additions and 136 deletions

View File

@@ -67,20 +67,19 @@ static void filtrow(unsigned char *point, int x)
static void filtrowf(float *point, int x)
{
float c1,c2,c3,error;
float c1,c2,c3;
if (x>1){
c1 = c2 = *point;
error = 2;
for(x--;x>0;x--){
c3 = point[4];
c1 += (c2 * 2) + c3 + error;
*point = c1 / 4.0;
c1 += (c2 * 2) + c3;
*point = 0.25f*c1;
point += 4;
c1=c2;
c2=c3;
}
*point = (c1 + (c2 * 2) + c2 + error) / 4.0;
*point = 0.25f*(c1 + (c2 * 2) + c2);
}
}
@@ -111,22 +110,21 @@ static void filtcolum(unsigned char *point, int y, int skip)
static void filtcolumf(float *point, int y, int skip)
{
float c1,c2,c3,error, *point2;
float c1,c2,c3, *point2;
if (y>1){
c1 = c2 = *point;
point2 = point;
error = 2;
for(y--;y>0;y--){
point2 += skip;
c3 = *point2;
c1 += (c2 * 2) + c3 +error;
*point = c1 / 4;
c1 += (c2 * 2) + c3;
*point = 0.25f*c1;
point=point2;
c1=c2;
c2=c3;
}
*point = (c1 + (c2 * 2) + c2 + error) / 4;
*point = 0.25f*(c1 + (c2 * 2) + c2);
}
}

View File

@@ -49,6 +49,7 @@
/* ------------------------------------------------------------------------- */
/* localized texture result data */
/* note; tr tg tb ta has to remain in this order */
typedef struct TexResult {
float tin, tr, tg, tb, ta;
int talpha;

View File

@@ -73,7 +73,6 @@ void shadeSkyPixel(RE_COLBUFTYPE *collector, float fx, float fy, float *rco);
void shadeSkyPixelFloat(float *colf, float *rco, float *view, float *dxyview);
void renderSpotHaloPixel(float x, float y, float *target);
void fillBackgroundImage(RE_COLBUFTYPE *collector, float x, float y);
void fillBackgroundImageChar(char *col, float x, float y);
/* ------------------------------------------------------------------------- */

View File

@@ -72,13 +72,30 @@ int imaprepeat, imapextend;
/* *********** IMAGEWRAPPING ****************** */
/* x and y have to be checked for image size */
static void ibuf_get_color(float *col, struct ImBuf *ibuf, int x, int y)
{
int ofs = y * ibuf->x + x;
if(ibuf->rect_float) {
float *fp= ibuf->rect_float + 4*ofs;
QUATCOPY(col, fp);
}
else {
char *rect = (char *)( ibuf->rect+ ofs);
col[0] = ((float)rect[0])/255.0f;
col[1] = ((float)rect[1])/255.0f;
col[2] = ((float)rect[2])/255.0f;
col[3] = ((float)rect[3])/255.0f;
}
}
int imagewrap(Tex *tex, Image *ima, float *texvec, TexResult *texres)
{
struct ImBuf *ibuf;
float fx, fy, val1, val2, val3;
int ofs, x, y;
char *rect;
int x, y;
texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0;
@@ -164,8 +181,7 @@ int imagewrap(Tex *tex, Image *ima, float *texvec, TexResult *texres)
ibuf->rect+= (ibuf->x*ibuf->y);
}
ofs = y * ibuf->x + x;
rect = (char *)( ibuf->rect+ ofs);
ibuf_get_color(&texres->tr, ibuf, x, y);
if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
ibuf->rect-= (ibuf->x*ibuf->y);
@@ -176,10 +192,6 @@ int imagewrap(Tex *tex, Image *ima, float *texvec, TexResult *texres)
else texres->talpha= 1;
}
texres->tr = ((float)rect[0])/255.0f;
texres->tg = ((float)rect[1])/255.0f;
texres->tb = ((float)rect[2])/255.0f;
if(texres->nor) {
if(tex->imaflag & TEX_NORMALMAP) {
texres->nor[0]= 0.5-texres->tr;
@@ -191,15 +203,16 @@ int imagewrap(Tex *tex, Image *ima, float *texvec, TexResult *texres)
val1= texres->tr+texres->tg+texres->tb;
if(x<ibuf->x-1) {
rect+=4;
val2= ((float)(rect[0]+rect[1]+rect[2]))/255.0f;
rect-=4;
float col[4];
ibuf_get_color(col, ibuf, x+1, y);
val2= (col[0]+col[1]+col[2]);
}
else val2= val1;
if(y<ibuf->y-1) {
rect+= 4*ibuf->x;
val3= ((float)(rect[0]+rect[1]+rect[2]))/255.0f;
float col[4];
ibuf_get_color(col, ibuf, x, y+1);
val3= (col[0]+col[1]+col[2]);
}
else val3= val1;
@@ -211,7 +224,7 @@ int imagewrap(Tex *tex, Image *ima, float *texvec, TexResult *texres)
BRICONTRGB;
if(texres->talpha) texres->ta= texres->tin= ((float)rect[3])/255.0f;
if(texres->talpha) texres->tin= texres->ta;
else if(tex->imaflag & TEX_CALCALPHA) {
texres->ta= texres->tin= MAX3(texres->tr, texres->tg, texres->tb);
}
@@ -390,10 +403,8 @@ static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres)
/* sample box, is clipped already, and minx etc. have been set at ibuf size.
Enlarge with antialiased edges of the pixels */
float muly,mulx,div;
int ofs;
float muly, mulx, div, col[4];
int x, y, startx, endx, starty, endy;
char *rect;
startx= (int)floor(rf->xmin);
endx= (int)floor(rf->xmax);
@@ -406,22 +417,11 @@ static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres)
if(endy>=ibuf->y) endy= ibuf->y-1;
if(starty==endy && startx==endx) {
ofs = starty*ibuf->x + startx;
rect = (char *)(ibuf->rect +ofs);
texres->tr= ((float)rect[0])/255.0f;
texres->tg= ((float)rect[1])/255.0f;
texres->tb= ((float)rect[2])/255.0f;
/* alpha has been set in function imagewraposa() */
if(texres->talpha) {
texres->ta= ((float)rect[3])/255.0f;
}
ibuf_get_color(&texres->tr, ibuf, startx, starty);
}
else {
div= texres->tr= texres->tg= texres->tb= texres->ta= 0.0;
for(y=starty; y<=endy; y++) {
ofs = y*ibuf->x +startx;
rect = (char *)(ibuf->rect+ofs);
muly= 1.0;
@@ -430,12 +430,16 @@ static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres)
if(y==starty) muly= 1.0f-(rf->ymin - y);
if(y==endy) muly= (rf->ymax - y);
}
if(startx==endx) {
mulx= muly;
if(texres->talpha) texres->ta+= mulx*rect[3];
texres->tr+= mulx*rect[0];
texres->tg+= mulx*rect[1];
texres->tb+= mulx*rect[2];
ibuf_get_color(col, ibuf, startx, y);
texres->ta+= mulx*col[3];
texres->tr+= mulx*col[0];
texres->tg+= mulx*col[1];
texres->tb+= mulx*col[2];
div+= mulx;
}
else {
@@ -444,35 +448,34 @@ static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres)
if(x==startx) mulx*= 1.0f-(rf->xmin - x);
if(x==endx) mulx*= (rf->xmax - x);
ibuf_get_color(col, ibuf, x, y);
if(mulx==1.0) {
if(texres->talpha) texres->ta+= rect[3];
texres->tr+= rect[0];
texres->tg+= rect[1];
texres->tb+= rect[2];
texres->ta+= col[3];
texres->tr+= col[0];
texres->tg+= col[1];
texres->tb+= col[2];
div+= 1.0;
}
else {
if(texres->talpha) texres->ta+= mulx*rect[3];
texres->tr+= mulx*rect[0];
texres->tg+= mulx*rect[1];
texres->tb+= mulx*rect[2];
texres->ta+= mulx*col[3];
texres->tr+= mulx*col[0];
texres->tg+= mulx*col[1];
texres->tb+= mulx*col[2];
div+= mulx;
}
rect+=4;
}
}
}
if(div!=0.0) {
div*= 255.0;
texres->tb/= div;
texres->tg/= div;
texres->tr/= div;
if(texres->talpha) texres->ta/= div;
div= 1.0f/div;
texres->tb*= div;
texres->tg*= div;
texres->tr*= div;
texres->ta*= div;
}
else {
texres->tr= texres->tg= texres->tb= texres->ta= 0.0;
texres->tr= texres->tg= texres->tb= texres->ta= 0.0f;
}
}
}

View File

@@ -579,6 +579,117 @@ void renderSkyPixelFloat(RE_COLBUFTYPE *collector, float x, float y, float *rco)
/*
Render pixel (x,y) from the backbuffer into the collector
backbuf is type Image, backbuf->ibuf is an ImBuf. ibuf->rect is the
rgba data (32 bit total), in ibuf->x by ibuf->y pixels. Copying
should be really easy. I hope I understand the way ImBuf works
correctly. (nzc)
*/
void fillBackgroundImageChar(char *col, float x, float y)
{
struct ImBuf *ibuf;
int iy, ix;
unsigned int* imBufPtr;
/* check to be sure... */
if (R.backbuf==NULL || R.backbuf->ok==0) {
/* bail out */
col[0] = 0;
col[1] = 0;
col[2] = 0;
col[3] = 255;
return;
}
/* load image if not already done?*/
if(R.backbuf->ibuf==0) {
R.backbuf->ok= 0;
return;
}
ibuf= R.backbuf->ibuf;
/* Now for the real extraction: */
/* Get the y-coordinate of the scanline? */
ix= (int) (0.5f + ( ((x+R.afmx+R.xstart)/(float)R.r.xsch))*(float)ibuf->x);
iy= (int) (0.5f + ( ((y+R.afmy+R.ystart)/(float)R.r.ysch))*(float)ibuf->y);
/* correct in case of fields rendering: */
if(R.flag & R_SEC_FIELD) {
if((R.r.mode & R_ODDFIELD)==0) {
if( iy<ibuf->y) iy++;
}
else {
if( iy>0) iy--;
}
}
/* Offset into the buffer: start of scanline y: */
imBufPtr = ibuf->rect
+ (iy * ibuf->x)
+ ix;
*( (int *)col) = *imBufPtr;
}
static void fillBackgroundImage(float *col, float x, float y)
{
struct ImBuf *ibuf;
int iy, ix;
/* check to be sure... */
if (R.backbuf==NULL || R.backbuf->ok==0) {
/* bail out */
col[0] = 0;
col[1] = 0;
col[2] = 0;
col[3] = 255;
return;
}
/* load image if not already done?*/
if(R.backbuf->ibuf==NULL) {
R.backbuf->ok= 0;
return;
}
ibuf= R.backbuf->ibuf;
/* Now for the real extraction: */
/* Get the y-coordinate of the scanline? */
ix= (int) (( ((x+R.afmx+R.xstart)/(float)R.r.xsch))*(float)ibuf->x);
iy= (int) (( ((y+R.afmy+R.ystart)/(float)R.r.ysch))*(float)ibuf->y);
/* correct in case of fields rendering: */
if(R.flag & R_SEC_FIELD) {
if((R.r.mode & R_ODDFIELD)==0) {
if( iy<ibuf->y) iy++;
}
else {
if( iy>0) iy--;
}
}
CLAMP(ix, 0, ibuf->x-1);
CLAMP(iy, 0, ibuf->y-1);
/* Offset into the buffer: start of scanline y: */
if(ibuf->rect_float) {
float *fp = ibuf->rect_float + 4*(iy * ibuf->x + ix);
QUATCOPY(col, fp);
}
else {
char *cp = (char *)(ibuf->rect + (iy * ibuf->x) + ix);
col[0]= (1.0f/255.0f) * (float)cp[0];
col[1]= (1.0f/255.0f) * (float)cp[1];
col[2]= (1.0f/255.0f) * (float)cp[2];
col[3]= (1.0f/255.0f) * (float)cp[3];
}
}
/*
Stuff the sky colour into the collector.
*/
@@ -721,68 +832,4 @@ void shadeSkyPixelFloat(float *colf, float *rco, float *view, float *dxyview)
}
/*
Render pixel (x,y) from the backbuffer into the collector
backbuf is type Image, backbuf->ibuf is an ImBuf. ibuf->rect is the
rgba data (32 bit total), in ibuf->x by ibuf->y pixels. Copying
should be really easy. I hope I understand the way ImBuf works
correctly. (nzc)
*/
void fillBackgroundImageChar(char *col, float x, float y)
{
int iy, ix;
unsigned int* imBufPtr;
/* check to be sure... */
if (R.backbuf==NULL || R.backbuf->ok==0) {
/* bail out */
col[0] = 0;
col[1] = 0;
col[2] = 0;
col[3] = 255;
return;
}
/* load image if not already done?*/
if(R.backbuf->ibuf==0) {
R.backbuf->ok= 0;
return;
}
tag_image_time(R.backbuf);
/* Now for the real extraction: */
/* Get the y-coordinate of the scanline? */
iy= (int) ((y+R.afmy+R.ystart)*R.backbuf->ibuf->y)/(2*R.afmy);
ix= (int) ((x+R.afmx+R.xstart)*R.backbuf->ibuf->x)/(2*R.afmx);
/* correct in case of fields rendering: */
if(R.flag & R_SEC_FIELD) {
if((R.r.mode & R_ODDFIELD)==0) {
if( iy<R.backbuf->ibuf->y) iy++;
}
else {
if( iy>0) iy--;
}
}
/* Offset into the buffer: start of scanline y: */
imBufPtr = R.backbuf->ibuf->rect
+ (iy * R.backbuf->ibuf->x)
+ ix;
*( (int *)col) = *imBufPtr;
}
void fillBackgroundImage(RE_COLBUFTYPE *collector, float x, float y)
{
char col[4];
fillBackgroundImageChar(col, x, y);
cpCharColV2FloatColV(col, collector);
}
/* eof */

View File

@@ -1101,7 +1101,6 @@ static void sima_draw_alpha_backdrop(SpaceImage *sima, float x1, float y1, float
static void sima_draw_alpha_pixels(float x1, float y1, int rectx, int recty, unsigned int *recti)
{
char *rect= (char *)recti;
/* swap bytes, so alpha is most significant one, then just draw it as luminance int */
glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);

View File

@@ -361,20 +361,23 @@ static void renderwin_draw(RenderWin *rw, int just_clear)
static void renderwin_mouse_moved(RenderWin *rw)
{
if (rw->flags & RW_FLAGS_PIXEL_EXAMINING) {
int imgco[2];
char buf[64];
int imgco[2], ofs;
char buf[128];
int *pxlz; // zbuffer is signed
char *pxl;
if (R.rectot && renderwin_win_to_image_co(rw, rw->lmouse, imgco)) {
pxl= (char*) &R.rectot[R.rectx*imgco[1] + imgco[0]];
ofs= sprintf(buf, "R: %d G: %d B: %d A: %d", pxl[0], pxl[1], pxl[2], pxl[3]);
if (R.rectftot) {
float *pxlf= R.rectftot + 4*(R.rectx*imgco[1] + imgco[0]);
ofs+= sprintf(buf+ofs, " | R: %.3f G: %.3f B: %.3f A: %.3f ", pxlf[0], pxlf[1], pxlf[2], pxlf[3]);
}
if (R.rectz) {
pxlz= &R.rectz[R.rectx*imgco[1] + imgco[0]];
sprintf(buf, "R: %d, G: %d, B: %d, A: %d, Z: %f", pxl[0], pxl[1], pxl[2], pxl[3], 0.5+0.5*( ((float)*pxlz)/(float)INT_MAX) );
}
else {
sprintf(buf, "R: %d, G: %d, B: %d, A: %d", pxl[0], pxl[1], pxl[2], pxl[3]);
sprintf(buf+ofs, "| Z: %f", 0.5+0.5*( ((float)*pxlz)/(float)INT_MAX) );
}
renderwin_set_infotext(rw, buf);