fixed some rasters (again)

This commit is contained in:
aap 2020-07-29 22:42:52 +02:00
parent 90b624fc3a
commit 162c2d2035
6 changed files with 145 additions and 91 deletions

View File

@ -527,7 +527,9 @@ rasterSetFormat(Raster *raster)
natras->format = formatInfoRW[(raster->format >> 8) & 0xF].d3dformat; natras->format = formatInfoRW[(raster->format >> 8) & 0xF].d3dformat;
raster->depth = formatInfoRW[(raster->format >> 8) & 0xF].depth; raster->depth = formatInfoRW[(raster->format >> 8) & 0xF].depth;
} }
natras->bpp = raster->depth/8;
natras->hasAlpha = formatInfoRW[(raster->format >> 8) & 0xF].hasAlpha; natras->hasAlpha = formatInfoRW[(raster->format >> 8) & 0xF].hasAlpha;
raster->stride = raster->width*natras->bpp;
} }
static Raster* static Raster*
@ -684,8 +686,11 @@ imageFindRasterFormat(Image *img, int32 type,
assert((type&0xF) == Raster::TEXTURE); assert((type&0xF) == Raster::TEXTURE);
for(width = 1; width < img->width; width <<= 1); // for(width = 1; width < img->width; width <<= 1);
for(height = 1; height < img->height; height <<= 1); // for(height = 1; height < img->height; height <<= 1);
// Perhaps non-power-of-2 textures are acceptable?
width = img->width;
height = img->height;
depth = img->depth; depth = img->depth;
@ -734,6 +739,8 @@ rasterFromImage(Raster *raster, Image *image)
if((raster->type&0xF) != Raster::TEXTURE) if((raster->type&0xF) != Raster::TEXTURE)
return 0; return 0;
void (*conv)(uint8 *out, uint8 *in) = nil;
// Unpalettize image if necessary but don't change original // Unpalettize image if necessary but don't change original
Image *truecolimg = nil; Image *truecolimg = nil;
if(image->depth <= 8 && !isP8supported){ if(image->depth <= 8 && !isP8supported){
@ -748,22 +755,39 @@ rasterFromImage(Raster *raster, Image *image)
D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset); D3dRaster *natras = PLUGINOFFSET(D3dRaster, raster, nativeRasterOffset);
switch(image->depth){ switch(image->depth){
case 32: case 32:
if(raster->format != Raster::C8888 && if(raster->format == Raster::C8888)
raster->format != Raster::C888) conv = conv_BGRA8888_from_RGBA8888;
else if(raster->format == Raster::C888)
conv = conv_BGR888_from_RGB888;
else
goto err; goto err;
break; break;
case 24: case 24:
if(raster->format != Raster::C888) goto err; if(raster->format == Raster::C8888)
conv = conv_BGRA8888_from_RGB888;
else if(raster->format == Raster::C888)
conv = conv_BGR888_from_RGB888;
else
goto err;
break; break;
case 16: case 16:
if(raster->format != Raster::C1555) goto err; if(raster->format == Raster::C1555)
conv = conv_ARGB1555_from_ARGB1555;
else
goto err;
break; break;
case 8: case 8:
if(raster->format != (Raster::PAL8 | Raster::C8888)) goto err; if(raster->format == (Raster::PAL8 | Raster::C8888))
conv = conv_8_from_8;
else
goto err;
break; break;
case 4: case 4:
if(raster->format != (Raster::PAL4 | Raster::C8888)) goto err; if(raster->format == (Raster::PAL4 | Raster::C8888) ||
break; raster->format == (Raster::PAL8 | Raster::C8888))
conv = conv_8_from_8;
else
goto err;
default: default:
err: err:
RWERROR((ERR_INVRASTER)); RWERROR((ERR_INVRASTER));
@ -780,48 +804,30 @@ rasterFromImage(Raster *raster, Image *image)
in = image->palette; in = image->palette;
out = (uint8*)natras->palette; out = (uint8*)natras->palette;
for(int32 i = 0; i < pallength; i++){ for(int32 i = 0; i < pallength; i++){
out[0] = in[0]; conv_RGBA8888_from_RGBA8888(out, in);
out[1] = in[1];
out[2] = in[2];
out[3] = in[3];
in += 4; in += 4;
out += 4; out += 4;
} }
} }
int32 inc = image->bpp; uint8 *pixels = raster->lock(0, Raster::LOCKWRITE|Raster::LOCKNOFETCH);
in = image->pixels; assert(pixels);
out = raster->lock(0, Raster::LOCKWRITE|Raster::LOCKNOFETCH); uint8 *imgpixels = image->pixels;
if(pallength)
memcpy(out, in, raster->width*raster->height); int x, y;
else assert(image->width == raster->width);
// TODO: stride assert(image->height == raster->height);
for(int32 y = 0; y < image->height; y++) for(y = 0; y < image->height; y++){
for(int32 x = 0; x < image->width; x++) uint8 *imgrow = imgpixels;
switch(raster->format & 0xF00){ uint8 *rasrow = pixels;
case Raster::C8888: for(x = 0; x < image->width; x++){
out[0] = in[2]; conv(rasrow, imgrow);
out[1] = in[1]; imgrow += image->bpp;
out[2] = in[0]; rasrow += natras->bpp;
out[3] = in[3]; }
in += inc; imgpixels += image->stride;
out += 4; pixels += raster->stride;
break; }
case Raster::C888:
out[0] = in[2];
out[1] = in[1];
out[2] = in[0];
out[3] = 0xFF;
in += inc;
out += 4;
break;
case Raster::C1555:
out[0] = in[0];
out[1] = in[1];
in += inc;
out += 2;
break;
}
raster->unlock(0); raster->unlock(0);
if(truecolimg) if(truecolimg)
@ -860,18 +866,24 @@ rasterToImage(Raster *raster)
raster->unlock(0); raster->unlock(0);
return image; return image;
} }
void (*conv)(uint8 *out, uint8 *in) = nil;
switch(raster->format & 0xF00){ switch(raster->format & 0xF00){
case Raster::C1555: case Raster::C1555:
depth = 16; depth = 16;
conv = conv_ARGB1555_from_ARGB1555;
break; break;
case Raster::C8888: case Raster::C8888:
depth = 32; depth = 32;
conv = conv_RGBA8888_from_BGRA8888;
break; break;
case Raster::C888: case Raster::C888:
depth = 24; depth = 24;
conv = conv_RGB888_from_BGR888;
break; break;
case Raster::C555: case Raster::C555:
depth = 16; depth = 16;
conv = conv_ARGB1555_from_RGB555;
break; break;
default: default:
@ -898,52 +910,28 @@ rasterToImage(Raster *raster)
out = image->palette; out = image->palette;
in = (uint8*)natras->palette; in = (uint8*)natras->palette;
for(int32 i = 0; i < pallength; i++){ for(int32 i = 0; i < pallength; i++){
out[0] = in[0]; conv_RGBA8888_from_RGBA8888(out, in);
out[1] = in[1];
out[2] = in[2];
out[3] = in[3];
in += 4; in += 4;
out += 4; out += 4;
} }
} }
uint8 *dst = image->pixels; uint8 *imgpixels = image->pixels;
in = raster->lock(0, Raster::LOCKREAD); uint8 *pixels = raster->lock(0, Raster::LOCKREAD);
if(pallength)
memcpy(dst, in, raster->width*raster->height); int x, y;
else{ assert(image->width == raster->width);
for(int32 y = 0; y < image->height; y++){ assert(image->height == raster->height);
out = dst; for(y = 0; y < image->height; y++){
for(int32 x = 0; x < image->width; x++){ uint8 *imgrow = imgpixels;
switch(raster->format & 0xF00){ uint8 *rasrow = pixels;
case Raster::C8888: for(x = 0; x < image->width; x++){
out[0] = in[2]; conv(imgrow, rasrow);
out[1] = in[1]; imgrow += image->bpp;
out[2] = in[0]; rasrow += natras->bpp;
out[3] = in[3];
in += 4;
break;
case Raster::C888:
out[0] = in[2];
out[1] = in[1];
out[2] = in[0];
in += 4;
break;
case Raster::C1555:
out[0] = in[0];
out[1] = in[1];
in += 2;
break;
case Raster::C555:
out[0] = in[0];
out[1] = in[1] | 0x80;
in += 2;
break;
}
out += image->bpp;
}
dst += image->stride;
} }
imgpixels += image->stride;
pixels += raster->stride;
} }
raster->unlock(0); raster->unlock(0);

View File

@ -162,6 +162,7 @@ struct D3dRaster
void *texture; void *texture;
void *palette; void *palette;
uint32 format; uint32 format;
uint32 bpp; // bytes per pixel
bool32 hasAlpha; bool32 hasAlpha;
bool32 customFormat; bool32 customFormat;
}; };

View File

@ -315,8 +315,11 @@ imageFindRasterFormat(Image *img, int32 type,
assert((type&0xF) == Raster::TEXTURE); assert((type&0xF) == Raster::TEXTURE);
for(width = 1; width < img->width; width <<= 1); // for(width = 1; width < img->width; width <<= 1);
for(height = 1; height < img->height; height <<= 1); // for(height = 1; height < img->height; height <<= 1);
// Perhaps non-power-of-2 textures are acceptable?
width = img->width;
height = img->height;
depth = img->depth; depth = img->depth;
@ -440,8 +443,11 @@ rasterFromImage(Raster *raster, Image *image)
imgpixels -= image->stride; imgpixels -= image->stride;
pixels += raster->stride; pixels += raster->stride;
} }
raster->unlock(0); raster->unlock(0);
if(truecolimg)
truecolimg->destroy();
return 1; return 1;
} }

View File

@ -230,6 +230,15 @@ conv_RGBA8888_from_RGBA8888(uint8 *out, uint8 *in)
out[3] = in[3]; out[3] = in[3];
} }
void
conv_BGRA8888_from_RGBA8888(uint8 *out, uint8 *in)
{
out[2] = in[0];
out[1] = in[1];
out[0] = in[2];
out[3] = in[3];
}
void void
conv_RGBA8888_from_RGB888(uint8 *out, uint8 *in) conv_RGBA8888_from_RGB888(uint8 *out, uint8 *in)
{ {
@ -239,6 +248,15 @@ conv_RGBA8888_from_RGB888(uint8 *out, uint8 *in)
out[3] = 0xFF; out[3] = 0xFF;
} }
void
conv_BGRA8888_from_RGB888(uint8 *out, uint8 *in)
{
out[2] = in[0];
out[1] = in[1];
out[0] = in[2];
out[3] = 0xFF;
}
void void
conv_RGB888_from_RGB888(uint8 *out, uint8 *in) conv_RGB888_from_RGB888(uint8 *out, uint8 *in)
{ {
@ -247,6 +265,28 @@ conv_RGB888_from_RGB888(uint8 *out, uint8 *in)
out[2] = in[2]; out[2] = in[2];
} }
void
conv_BGR888_from_RGB888(uint8 *out, uint8 *in)
{
out[2] = in[0];
out[1] = in[1];
out[0] = in[2];
}
void
conv_ARGB1555_from_ARGB1555(uint8 *out, uint8 *in)
{
out[0] = in[0];
out[1] = in[1];
}
void
conv_ARGB1555_from_RGB555(uint8 *out, uint8 *in)
{
out[0] = in[0];
out[1] = in[1] | 0x80;
}
void void
conv_RGBA5551_from_ARGB1555(uint8 *out, uint8 *in) conv_RGBA5551_from_ARGB1555(uint8 *out, uint8 *in)
{ {

View File

@ -74,6 +74,16 @@ typedef uint32 uint;
#define nelem(A) (sizeof(A) / sizeof A[0]) #define nelem(A) (sizeof(A) / sizeof A[0])
#ifdef __GNUC__
#define RWALIGN(n) __attribute__ ((aligned (n)))
#else
#ifdef _MSC_VER
#define RWALIGN(n) __declspec(align(n))
#else
#define RWALIGN(n) // unknown compiler...ignore
#endif
#endif
// Lists // Lists
struct LLLink struct LLLink
@ -286,7 +296,7 @@ inline V3d rotate(const V3d &v, const Quat &q) { return mult(mult(q, makeQuat(0.
Quat lerp(const Quat &q, const Quat &p, float32 r); Quat lerp(const Quat &q, const Quat &p, float32 r);
Quat slerp(const Quat &q, const Quat &p, float32 a); Quat slerp(const Quat &q, const Quat &p, float32 a);
struct RawMatrix struct RWALIGN(16) RawMatrix
{ {
V3d right; V3d right;
float32 rightw; float32 rightw;
@ -302,7 +312,7 @@ struct RawMatrix
static void setIdentity(RawMatrix *dst); static void setIdentity(RawMatrix *dst);
}; };
struct Matrix struct RWALIGN(16) Matrix
{ {
enum Type { enum Type {
TYPENORMAL = 1, TYPENORMAL = 1,

View File

@ -306,11 +306,20 @@ struct Raster
}; };
void conv_RGBA8888_from_RGBA8888(uint8 *out, uint8 *in); void conv_RGBA8888_from_RGBA8888(uint8 *out, uint8 *in);
void conv_BGRA8888_from_RGBA8888(uint8 *out, uint8 *in);
void conv_RGBA8888_from_RGB888(uint8 *out, uint8 *in); void conv_RGBA8888_from_RGB888(uint8 *out, uint8 *in);
void conv_BGRA8888_from_RGB888(uint8 *out, uint8 *in);
void conv_RGB888_from_RGB888(uint8 *out, uint8 *in); void conv_RGB888_from_RGB888(uint8 *out, uint8 *in);
void conv_BGR888_from_RGB888(uint8 *out, uint8 *in);
void conv_ARGB1555_from_ARGB1555(uint8 *out, uint8 *in);
void conv_ARGB1555_from_RGB555(uint8 *out, uint8 *in);
void conv_RGBA5551_from_ARGB1555(uint8 *out, uint8 *in); void conv_RGBA5551_from_ARGB1555(uint8 *out, uint8 *in);
void conv_RGBA8888_from_ARGB1555(uint8 *out, uint8 *in); void conv_RGBA8888_from_ARGB1555(uint8 *out, uint8 *in);
void conv_ABGR1555_from_ARGB1555(uint8 *out, uint8 *in); void conv_ABGR1555_from_ARGB1555(uint8 *out, uint8 *in);
inline void conv_8_from_8(uint8 *out, uint8 *in) { *out = *in; }
// some swaps are the same, so these are just more descriptive names
inline void conv_RGBA8888_from_BGRA8888(uint8 *out, uint8 *in) { conv_BGRA8888_from_RGBA8888(out, in); }
inline void conv_RGB888_from_BGR888(uint8 *out, uint8 *in) { conv_BGR888_from_RGB888(out, in); }
inline void conv_ARGB1555_from_ABGR1555(uint8 *out, uint8 *in) { conv_ABGR1555_from_ARGB1555(out, in); } inline void conv_ARGB1555_from_ABGR1555(uint8 *out, uint8 *in) { conv_ABGR1555_from_ARGB1555(out, in); }
void expandPal4(uint8 *dst, uint32 dststride, uint8 *src, uint32 srcstride, int32 w, int32 h); void expandPal4(uint8 *dst, uint32 dststride, uint8 *src, uint32 srcstride, int32 w, int32 h);