mirror of
https://github.com/aap/librw.git
synced 2025-02-17 17:55:58 +00:00
image masks and raster fixes
This commit is contained in:
parent
853fa44982
commit
4883b03f2b
@ -741,7 +741,7 @@ rasterFromImage(Raster *raster, Image *image)
|
|||||||
truecolimg->pixels = image->pixels;
|
truecolimg->pixels = image->pixels;
|
||||||
truecolimg->stride = image->stride;
|
truecolimg->stride = image->stride;
|
||||||
truecolimg->palette = image->palette;
|
truecolimg->palette = image->palette;
|
||||||
truecolimg->unindex();
|
truecolimg->unpalettize();
|
||||||
image = truecolimg;
|
image = truecolimg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,7 +371,7 @@ rasterFromImage(Raster *raster, Image *image)
|
|||||||
truecolimg->pixels = image->pixels;
|
truecolimg->pixels = image->pixels;
|
||||||
truecolimg->stride = image->stride;
|
truecolimg->stride = image->stride;
|
||||||
truecolimg->palette = image->palette;
|
truecolimg->palette = image->palette;
|
||||||
truecolimg->unindex();
|
truecolimg->unpalettize();
|
||||||
image = truecolimg;
|
image = truecolimg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,34 +379,34 @@ rasterFromImage(Raster *raster, Image *image)
|
|||||||
switch(image->depth){
|
switch(image->depth){
|
||||||
case 32:
|
case 32:
|
||||||
#ifdef RW_GLES
|
#ifdef RW_GLES
|
||||||
conv = conv_RGBA8888_to_RGBA8888;
|
conv = conv_RGBA8888_from_RGBA8888;
|
||||||
#else
|
#else
|
||||||
if(raster->format == Raster::C8888)
|
if(raster->format == Raster::C8888)
|
||||||
conv = conv_RGBA8888_to_RGBA8888;
|
conv = conv_RGBA8888_from_RGBA8888;
|
||||||
else if(raster->format == Raster::C888)
|
else if(raster->format == Raster::C888)
|
||||||
conv = conv_RGB888_to_RGB888;
|
conv = conv_RGB888_from_RGB888;
|
||||||
else
|
else
|
||||||
goto err;
|
goto err;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case 24:
|
case 24:
|
||||||
#ifdef RW_GLES
|
#ifdef RW_GLES
|
||||||
conv = conv_RGB888_to_RGBA8888;
|
conv = conv_RGB888_from_RGBA8888;
|
||||||
#else
|
#else
|
||||||
if(raster->format == Raster::C8888)
|
if(raster->format == Raster::C8888)
|
||||||
conv = conv_RGB888_to_RGBA8888;
|
conv = conv_RGBA8888_from_RGB888;
|
||||||
else if(raster->format == Raster::C888)
|
else if(raster->format == Raster::C888)
|
||||||
conv = conv_RGB888_to_RGB888;
|
conv = conv_RGB888_from_RGB888;
|
||||||
else
|
else
|
||||||
goto err;
|
goto err;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
#ifdef RW_GLES
|
#ifdef RW_GLES
|
||||||
conv = conv_RGBA1555_to_RGBA8888;
|
conv = conv_RGBA8888_from_ARGB1555;
|
||||||
#else
|
#else
|
||||||
if(raster->format == Raster::C1555)
|
if(raster->format == Raster::C1555)
|
||||||
conv = conv_RGBA1555_to_RGBA5551;
|
conv = conv_RGBA5551_from_ARGB1555;
|
||||||
else
|
else
|
||||||
goto err;
|
goto err;
|
||||||
#endif
|
#endif
|
||||||
|
@ -80,7 +80,7 @@ Shader *currentShader;
|
|||||||
static void
|
static void
|
||||||
printShaderSource(const char **src)
|
printShaderSource(const char **src)
|
||||||
{
|
{
|
||||||
int f, l;
|
int f;
|
||||||
const char *file;
|
const char *file;
|
||||||
bool printline;
|
bool printline;
|
||||||
int line = 1;
|
int line = 1;
|
||||||
|
458
src/image.cpp
458
src/image.cpp
@ -85,7 +85,7 @@ Image::allocate(void)
|
|||||||
}
|
}
|
||||||
if(this->palette == nil){
|
if(this->palette == nil){
|
||||||
if(this->depth == 4 || this->depth == 8)
|
if(this->depth == 4 || this->depth == 8)
|
||||||
this->palette = rwNewT(uint8, (this->depth==4? 16 : 256)*4, MEMDUR_EVENT | ID_IMAGE);
|
this->palette = rwNewT(uint8, (1 << this->depth)*4, MEMDUR_EVENT | ID_IMAGE);
|
||||||
this->flags |= 2;
|
this->flags |= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,6 +101,7 @@ Image::free(void)
|
|||||||
rwFree(this->palette);
|
rwFree(this->palette);
|
||||||
this->palette = nil;
|
this->palette = nil;
|
||||||
}
|
}
|
||||||
|
this->flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -350,8 +351,6 @@ Image::hasAlpha(void)
|
|||||||
{
|
{
|
||||||
uint8 ret = 0xFF;
|
uint8 ret = 0xFF;
|
||||||
uint8 *pixels = this->pixels;
|
uint8 *pixels = this->pixels;
|
||||||
if(this->depth == 24)
|
|
||||||
return 0;
|
|
||||||
if(this->depth == 32){
|
if(this->depth == 32){
|
||||||
for(int y = 0; y < this->height; y++){
|
for(int y = 0; y < this->height; y++){
|
||||||
uint8 *line = pixels;
|
uint8 *line = pixels;
|
||||||
@ -361,6 +360,18 @@ Image::hasAlpha(void)
|
|||||||
}
|
}
|
||||||
pixels += this->stride;
|
pixels += this->stride;
|
||||||
}
|
}
|
||||||
|
}else if(this->depth == 24){
|
||||||
|
return 0;
|
||||||
|
}else if(this->depth == 16){
|
||||||
|
for(int y = 0; y < this->height; y++){
|
||||||
|
uint8 *line = pixels;
|
||||||
|
for(int x = 0; x < this->width; x++){
|
||||||
|
ret &= line[1] & 0x80;
|
||||||
|
line += 2;
|
||||||
|
}
|
||||||
|
pixels += this->stride;
|
||||||
|
}
|
||||||
|
return ret != 0x80;
|
||||||
}else if(this->depth <= 8){
|
}else if(this->depth <= 8){
|
||||||
for(int y = 0; y < this->height; y++){
|
for(int y = 0; y < this->height; y++){
|
||||||
uint8 *line = pixels;
|
uint8 *line = pixels;
|
||||||
@ -375,14 +386,92 @@ Image::hasAlpha(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Image::unindex(void)
|
Image::convertTo32(void)
|
||||||
|
{
|
||||||
|
assert(this->pixels);
|
||||||
|
uint8 *pixels = this->pixels;
|
||||||
|
int32 newstride = this->width*4;
|
||||||
|
uint8 *newpixels;
|
||||||
|
|
||||||
|
void (*fun)(uint8 *out, uint8 *in) = nil;
|
||||||
|
switch(this->depth){
|
||||||
|
case 4:
|
||||||
|
case 8:
|
||||||
|
assert(this->palette);
|
||||||
|
this->unpalettize(true);
|
||||||
|
return;
|
||||||
|
case 16:
|
||||||
|
fun = conv_RGBA8888_from_ARGB1555;
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
fun = conv_RGBA8888_from_RGB888;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
newpixels = rwNewT(uint8, newstride*this->height, MEMDUR_EVENT | ID_IMAGE);
|
||||||
|
for(int y = 0; y < this->height; y++){
|
||||||
|
uint8 *line = pixels;
|
||||||
|
uint8 *newline = newpixels;
|
||||||
|
for(int x = 0; x < this->width; x++){
|
||||||
|
fun(newline, line);
|
||||||
|
line += this->bpp;
|
||||||
|
newline += 4;
|
||||||
|
}
|
||||||
|
pixels += this->stride;
|
||||||
|
newpixels += newstride;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->free();
|
||||||
|
this->depth = 32;
|
||||||
|
this->bpp = 4;
|
||||||
|
this->stride = newstride;
|
||||||
|
this->pixels = nil;
|
||||||
|
this->palette = nil;
|
||||||
|
this->setPixels(newpixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Image::palettize(int32 depth)
|
||||||
|
{
|
||||||
|
RGBA colors[256];
|
||||||
|
ColorQuant quant;
|
||||||
|
uint8 *newpixels;
|
||||||
|
uint32 newstride;
|
||||||
|
|
||||||
|
quant.init();
|
||||||
|
quant.addImage(this);
|
||||||
|
assert(depth <= 8);
|
||||||
|
quant.makePalette(1<<depth, colors);
|
||||||
|
|
||||||
|
newstride = this->width;
|
||||||
|
newpixels = rwNewT(uint8, newstride*this->height, MEMDUR_EVENT | ID_IMAGE);
|
||||||
|
// TODO: maybe do floyd-steinberg dithering?
|
||||||
|
quant.matchImage(newpixels, newstride, this);
|
||||||
|
|
||||||
|
this->free();
|
||||||
|
this->depth = depth;
|
||||||
|
this->bpp = depth < 8 ? 1 : depth/8;
|
||||||
|
this->stride = newstride;
|
||||||
|
this->pixels = nil;
|
||||||
|
this->palette = nil;
|
||||||
|
this->setPixels(newpixels);
|
||||||
|
this->allocate();
|
||||||
|
memcpy(this->palette, colors, 4*(1<<depth));
|
||||||
|
|
||||||
|
quant.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Image::unpalettize(bool forceAlpha)
|
||||||
{
|
{
|
||||||
if(this->depth > 8)
|
if(this->depth > 8)
|
||||||
return;
|
return;
|
||||||
assert(this->pixels);
|
assert(this->pixels);
|
||||||
assert(this->palette);
|
assert(this->palette);
|
||||||
|
|
||||||
int32 ndepth = this->hasAlpha() ? 32 : 24;
|
int32 ndepth = (forceAlpha || this->hasAlpha()) ? 32 : 24;
|
||||||
int32 nstride = this->width*ndepth/8;
|
int32 nstride = this->width*ndepth/8;
|
||||||
uint8 *npixels = rwNewT(uint8, nstride*this->height, MEMDUR_EVENT | ID_IMAGE);
|
uint8 *npixels = rwNewT(uint8, nstride*this->height, MEMDUR_EVENT | ID_IMAGE);
|
||||||
|
|
||||||
@ -411,14 +500,89 @@ Image::unindex(void)
|
|||||||
this->setPixels(npixels);
|
this->setPixels(npixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy the biggest channel value to alpha
|
||||||
|
void
|
||||||
|
Image::makeMask(void)
|
||||||
|
{
|
||||||
|
int32 maxcol;
|
||||||
|
switch(this->depth){
|
||||||
|
case 4:
|
||||||
|
case 8: {
|
||||||
|
assert(this->palette);
|
||||||
|
int32 pallen = 1 << this->depth;
|
||||||
|
for(int32 i = 0; i < pallen; i++){
|
||||||
|
maxcol = this->palette[i*4+0];
|
||||||
|
if(this->palette[i*4+1] > maxcol) maxcol = this->palette[i*4+1];
|
||||||
|
if(this->palette[i*4+2] > maxcol) maxcol = this->palette[i*4+2];
|
||||||
|
this->palette[i*4+3] = maxcol;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 16:
|
||||||
|
case 24:
|
||||||
|
this->convertTo32();
|
||||||
|
// fallthrough
|
||||||
|
|
||||||
|
case 32: {
|
||||||
|
assert(this->pixels);
|
||||||
|
uint8 *line = this->pixels;
|
||||||
|
uint8 *p;
|
||||||
|
for(int32 y = 0; y < this->height; y++){
|
||||||
|
p = line;
|
||||||
|
for(int32 x = 0; x < this->width; x++){
|
||||||
|
maxcol = p[0];
|
||||||
|
if(p[1] > maxcol) maxcol = p[1];
|
||||||
|
if(p[2] > maxcol) maxcol = p[2];
|
||||||
|
p[3] = maxcol;
|
||||||
|
p += this->bpp;
|
||||||
|
}
|
||||||
|
line += this->stride;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Image::applyMask(Image *mask)
|
||||||
|
{
|
||||||
|
if(this->width != mask->width || this->height != mask->height)
|
||||||
|
return; // TODO: set an error
|
||||||
|
// we could use alpha with 16 bits but what's the point?
|
||||||
|
if(mask->depth == 16 || mask->depth == 24)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this->convertTo32();
|
||||||
|
assert(this->depth == 32);
|
||||||
|
|
||||||
|
uint8 *line = this->pixels;
|
||||||
|
uint8 *mline = mask->pixels;
|
||||||
|
uint8 *p, *m;
|
||||||
|
for(int32 y = 0; y < this->height; y++){
|
||||||
|
p = line;
|
||||||
|
m = mline;
|
||||||
|
for(int32 x = 0; x < this->width; x++){
|
||||||
|
if(mask->depth == 32)
|
||||||
|
p[3] = m[3];
|
||||||
|
else if(mask->depth <= 8)
|
||||||
|
p[3] = mask->palette[m[0]*4+3];
|
||||||
|
p += this->bpp;
|
||||||
|
m += mask->bpp;
|
||||||
|
}
|
||||||
|
line += this->stride;
|
||||||
|
mline += mask->stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Image::removeMask(void)
|
Image::removeMask(void)
|
||||||
{
|
{
|
||||||
if(this->depth <= 8){
|
if(this->depth <= 8){
|
||||||
assert(this->palette);
|
assert(this->palette);
|
||||||
int32 pallen = 4*(this->depth == 4 ? 16 : 256);
|
int32 pallen = 4*(1 << this->depth);
|
||||||
for(int32 i = 0; i < pallen; i += 4)
|
for(int32 i = 0; i < pallen; i += 4)
|
||||||
this->palette[i] = 0xFF;
|
this->palette[i+3] = 0xFF;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(this->depth == 24)
|
if(this->depth == 24)
|
||||||
@ -576,6 +740,28 @@ Image::getFilename(const char *name)
|
|||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Image*
|
||||||
|
Image::readMasked(const char *imageName, const char *maskName)
|
||||||
|
{
|
||||||
|
Image *img, *mask;
|
||||||
|
|
||||||
|
img = read(imageName);
|
||||||
|
if(img == nil)
|
||||||
|
return nil;
|
||||||
|
if(maskName && maskName[0]){
|
||||||
|
mask = read(maskName);
|
||||||
|
if(mask == nil)
|
||||||
|
return img;
|
||||||
|
mask->makeMask();
|
||||||
|
int32 origDepth = img->depth;
|
||||||
|
img->applyMask(mask);
|
||||||
|
mask->destroy();
|
||||||
|
if(origDepth <= 8 && img->depth != origDepth)
|
||||||
|
img->palettize(origDepth);
|
||||||
|
}
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
Image*
|
Image*
|
||||||
Image::read(const char *imageName)
|
Image::read(const char *imageName)
|
||||||
{
|
{
|
||||||
@ -583,7 +769,7 @@ Image::read(const char *imageName)
|
|||||||
char *filename, *ext, *found;
|
char *filename, *ext, *found;
|
||||||
Image *img;
|
Image *img;
|
||||||
|
|
||||||
filename = rwNewT(char, strlen(imageName) + 20, MEMDUR_FUNCTION | ID_TEXTURE);
|
filename = rwNewT(char, strlen(imageName) + 20, MEMDUR_FUNCTION | ID_IMAGE);
|
||||||
strcpy(filename, imageName);
|
strcpy(filename, imageName);
|
||||||
ext = filename + strlen(filename);
|
ext = filename + strlen(filename);
|
||||||
*ext++ = '.';
|
*ext++ = '.';
|
||||||
@ -652,4 +838,260 @@ Image::registerModule(void)
|
|||||||
Engine::registerPlugin(sizeof(ImageGlobals), ID_IMAGEMODULE, imageOpen, imageClose);
|
Engine::registerPlugin(sizeof(ImageGlobals), ID_IMAGEMODULE, imageOpen, imageClose);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Color Quantization
|
||||||
|
*/
|
||||||
|
|
||||||
|
// An address for a single level is 4 bits.
|
||||||
|
// Since we have 8 bpp that is 32 bits to address any tree node.
|
||||||
|
// The lower bits address the higher level tree nodes.
|
||||||
|
// This is essentially a bit reverse and swizzle.
|
||||||
|
static uint32
|
||||||
|
makeTreeAddr(RGBA color)
|
||||||
|
{
|
||||||
|
int32 i;
|
||||||
|
uint32 addr = 0;
|
||||||
|
uint32 r = 1;
|
||||||
|
uint32 g = 2;
|
||||||
|
uint32 b = 4;
|
||||||
|
uint32 a = 8;
|
||||||
|
for(i = 0; i < 8; i++){
|
||||||
|
uint32 mask = 0x80>>i;
|
||||||
|
if(color.red & mask) addr |= r;
|
||||||
|
if(color.green & mask) addr |= g;
|
||||||
|
if(color.blue & mask) addr |= b;
|
||||||
|
if(color.alpha & mask) addr |= a;
|
||||||
|
r <<= 4;
|
||||||
|
g <<= 4;
|
||||||
|
b <<= 4;
|
||||||
|
a <<= 4;
|
||||||
|
}
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ColorQuant::Node::destroy(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < 16; i++)
|
||||||
|
if(this->children[i])
|
||||||
|
this->children[i]->destroy();
|
||||||
|
if(this->link.next)
|
||||||
|
this->link.remove();
|
||||||
|
rwFree(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorQuant::Node*
|
||||||
|
ColorQuant::createNode(int32 level)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
ColorQuant::Node *node = rwNewT(ColorQuant::Node, 1, MEMDUR_EVENT | ID_IMAGE);
|
||||||
|
node->parent = nil;
|
||||||
|
for(i = 0; i < 16; i++)
|
||||||
|
node->children[i] = nil;
|
||||||
|
node->r = 0;
|
||||||
|
node->g = 0;
|
||||||
|
node->b = 0;
|
||||||
|
node->a = 0;
|
||||||
|
node->numPixels = 0;
|
||||||
|
node->link.init();
|
||||||
|
|
||||||
|
if(level == 0)
|
||||||
|
this->leaves.append(&node->link);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorQuant::Node*
|
||||||
|
ColorQuant::getNode(ColorQuant::Node *root, uint32 addr, int32 level)
|
||||||
|
{
|
||||||
|
if(level == 0)
|
||||||
|
return root;
|
||||||
|
|
||||||
|
uint32 a = addr & 0xF;
|
||||||
|
if(root->children[a] == nil){
|
||||||
|
root->children[a] = this->createNode(level-1);
|
||||||
|
root->children[a]->parent = root;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this->getNode(root->children[a], addr>>4, level-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorQuant::Node*
|
||||||
|
ColorQuant::findNode(ColorQuant::Node *root, uint32 addr, int32 level)
|
||||||
|
{
|
||||||
|
if(level == 0)
|
||||||
|
return root;
|
||||||
|
|
||||||
|
uint32 a = addr & 0xF;
|
||||||
|
if(root->children[a] == nil)
|
||||||
|
return root;
|
||||||
|
|
||||||
|
return this->findNode(root->children[a], addr>>4, level-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ColorQuant::reduceNode(Node *node)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
assert(node->numPixels == 0);
|
||||||
|
for(i = 0; i < 16; i++)
|
||||||
|
if(node->children[i]){
|
||||||
|
node->r += node->children[i]->r;
|
||||||
|
node->g += node->children[i]->g;
|
||||||
|
node->b += node->children[i]->b;
|
||||||
|
node->a += node->children[i]->a;
|
||||||
|
node->numPixels += node->children[i]->numPixels;
|
||||||
|
node->children[i]->destroy();
|
||||||
|
node->children[i] = nil;
|
||||||
|
}
|
||||||
|
assert(node->link.next == nil);
|
||||||
|
assert(node->link.prev == nil);
|
||||||
|
this->leaves.append(&node->link);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ColorQuant::Node::addColor(RGBA color)
|
||||||
|
{
|
||||||
|
this->r += color.red;
|
||||||
|
this->g += color.green;
|
||||||
|
this->b += color.blue;
|
||||||
|
this->a += color.alpha;
|
||||||
|
this->numPixels++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ColorQuant::init(void)
|
||||||
|
{
|
||||||
|
this->leaves.init();
|
||||||
|
this->root = this->createNode(QUANTDEPTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ColorQuant::destroy(void)
|
||||||
|
{
|
||||||
|
this->root->destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ColorQuant::addColor(RGBA color)
|
||||||
|
{
|
||||||
|
uint32 addr = makeTreeAddr(color);
|
||||||
|
ColorQuant::Node *node = this->getNode(root, addr, QUANTDEPTH);
|
||||||
|
node->addColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8
|
||||||
|
ColorQuant::findColor(RGBA color)
|
||||||
|
{
|
||||||
|
uint32 addr = makeTreeAddr(color);
|
||||||
|
ColorQuant::Node *node = this->findNode(root, addr, QUANTDEPTH);
|
||||||
|
return node->numPixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ColorQuant::addImage(Image *img)
|
||||||
|
{
|
||||||
|
RGBA col;
|
||||||
|
uint8 rgba[4];
|
||||||
|
uint8 *pixels = img->pixels;
|
||||||
|
for(int y = 0; y < img->height; y++){
|
||||||
|
uint8 *line = pixels;
|
||||||
|
for(int x = 0; x < img->width; x++){
|
||||||
|
uint8 *p = line;
|
||||||
|
switch(img->depth){
|
||||||
|
case 4: case 8:
|
||||||
|
conv_RGBA8888_from_RGBA8888(rgba, &img->palette[p[0]*4]);
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
conv_RGBA8888_from_RGBA8888(rgba, p);
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
conv_RGBA8888_from_RGB888(rgba, p);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
conv_RGBA8888_from_ARGB1555(rgba, p);
|
||||||
|
break;
|
||||||
|
default: assert(0 && "invalid depth");
|
||||||
|
}
|
||||||
|
col.red = rgba[0];
|
||||||
|
col.green = rgba[1];
|
||||||
|
col.blue = rgba[2];
|
||||||
|
col.alpha = rgba[3];
|
||||||
|
this->addColor(col);
|
||||||
|
line += img->bpp;
|
||||||
|
}
|
||||||
|
pixels += img->stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ColorQuant::makePalette(int32 numColors, RGBA *colors)
|
||||||
|
{
|
||||||
|
while(this->leaves.count() > numColors){
|
||||||
|
Node *n = LLLinkGetData(this->leaves.link.next, Node, link);
|
||||||
|
this->reduceNode(n->parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
FORLIST(lnk, this->leaves){
|
||||||
|
Node *n = LLLinkGetData(lnk, Node, link);
|
||||||
|
n->r /= n->numPixels;
|
||||||
|
n->g /= n->numPixels;
|
||||||
|
n->b /= n->numPixels;
|
||||||
|
n->a /= n->numPixels;
|
||||||
|
colors[i].red = n->r;
|
||||||
|
colors[i].green = n->g;
|
||||||
|
colors[i].blue = n->b;
|
||||||
|
colors[i].alpha = n->a;
|
||||||
|
n->numPixels = i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ColorQuant::matchImage(uint8 *dstPixels, uint32 dstStride, Image *img)
|
||||||
|
{
|
||||||
|
RGBA col;
|
||||||
|
uint8 rgba[4];
|
||||||
|
uint8 *pixels = img->pixels;
|
||||||
|
for(int y = 0; y < img->height; y++){
|
||||||
|
uint8 *line = pixels;
|
||||||
|
uint8 *dline = dstPixels;
|
||||||
|
for(int x = 0; x < img->width; x++){
|
||||||
|
uint8 *p = line;
|
||||||
|
uint8 *d = dline;
|
||||||
|
switch(img->depth){
|
||||||
|
case 4: case 8:
|
||||||
|
conv_RGBA8888_from_RGBA8888(rgba, &img->palette[p[0]*4]);
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
conv_RGBA8888_from_RGBA8888(rgba, p);
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
conv_RGBA8888_from_RGB888(rgba, p);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
conv_RGBA8888_from_ARGB1555(rgba, p);
|
||||||
|
break;
|
||||||
|
default: assert(0 && "invalid depth");
|
||||||
|
}
|
||||||
|
|
||||||
|
col.red = rgba[0];
|
||||||
|
col.green = rgba[1];
|
||||||
|
col.blue = rgba[2];
|
||||||
|
col.alpha = rgba[3];
|
||||||
|
*d = this->findColor(col);
|
||||||
|
|
||||||
|
line += img->bpp;
|
||||||
|
dline++;
|
||||||
|
}
|
||||||
|
pixels += img->stride;
|
||||||
|
dstPixels += dstStride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1566,31 +1566,31 @@ rasterUnlockPalette(Raster *raster)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
expandPSMT4(uint8 *dst, uint8 *src, int32 w, int32 h, int32 srcw)
|
expandPSMT4(uint8 *dst, uint32 dststride, uint8 *src, uint32 srcstride, int32 w, int32 h)
|
||||||
{
|
{
|
||||||
int32 x, y;
|
int32 x, y;
|
||||||
for(y = 0; y < h; y++)
|
for(y = 0; y < h; y++)
|
||||||
for(x = 0; x < w/2; x++){
|
for(x = 0; x < w/2; x++){
|
||||||
dst[y*w + x*2 + 0] = src[y*srcw/2 + x] & 0xF;
|
dst[y*dststride + x*2 + 0] = src[y*srcstride + x] & 0xF;
|
||||||
dst[y*w + x*2 + 1] = src[y*srcw/2 + x] >> 4;
|
dst[y*dststride + x*2 + 1] = src[y*srcstride + x] >> 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
compressPSMT4(uint8 *dst, uint8 *src, int32 w, int32 h, int32 srcw)
|
compressPSMT4(uint8 *dst, uint32 dststride, uint8 *src, uint32 srcstride, int32 w, int32 h)
|
||||||
{
|
{
|
||||||
int32 x, y;
|
int32 x, y;
|
||||||
for(y = 0; y < h; y++)
|
for(y = 0; y < h; y++)
|
||||||
for(x = 0; x < w/2; x++)
|
for(x = 0; x < w/2; x++)
|
||||||
dst[y*srcw/2 + x] = src[y*w + x*2 + 0] | src[y*w + x*2 + 1] << 4;
|
dst[y*dststride + x] = src[y*srcstride + x*2 + 0] | src[y*srcstride + x*2 + 1] << 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
copyPSMT8(uint8 *dst, uint8 *src, int32 w, int32 h, int32 srcw)
|
copyPSMT8(uint8 *dst, uint32 dststride, uint8 *src, uint32 srcstride, int32 w, int32 h)
|
||||||
{
|
{
|
||||||
int32 x, y;
|
int32 x, y;
|
||||||
for(y = 0; y < h; y++)
|
for(y = 0; y < h; y++)
|
||||||
for(x = 0; x < w; x++)
|
for(x = 0; x < w; x++)
|
||||||
dst[y*w + x] = src[y*srcw + x];
|
dst[y*dststride + x] = src[y*srcstride + x];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Almost the same as d3d9 and gl3 function
|
// Almost the same as d3d9 and gl3 function
|
||||||
@ -1691,23 +1691,22 @@ rasterFromImage(Raster *raster, Image *image)
|
|||||||
int tw;
|
int tw;
|
||||||
transferMinSize(image->depth == 4 ? PSMT4 : PSMT8, natras->flags, &minw, &minh);
|
transferMinSize(image->depth == 4 ? PSMT4 : PSMT8, natras->flags, &minw, &minh);
|
||||||
tw = max(image->width, minw);
|
tw = max(image->width, minw);
|
||||||
in = image->pixels;
|
uint8 *src = image->pixels;
|
||||||
out = raster->lock(0, Raster::LOCKWRITE|Raster::LOCKNOFETCH);
|
out = raster->lock(0, Raster::LOCKWRITE|Raster::LOCKNOFETCH);
|
||||||
if(image->depth == 4){
|
if(image->depth == 4){
|
||||||
compressPSMT4(out, in, image->width, image->height, tw);
|
compressPSMT4(out, tw/2, src, image->stride, image->width, image->height);
|
||||||
}else if(image->depth == 8){
|
}else if(image->depth == 8){
|
||||||
copyPSMT8(out, in, image->width, image->height, tw);
|
copyPSMT8(out, tw, src, image->stride, image->width, image->height);
|
||||||
}else{
|
}else{
|
||||||
// TODO: stride
|
for(int32 y = 0; y < image->height; y++){
|
||||||
for(int32 y = 0; y < image->height; y++)
|
in = src;
|
||||||
for(int32 x = 0; x < image->width; x++)
|
for(int32 x = 0; x < image->width; x++){
|
||||||
switch(raster->format & 0xF00){
|
switch(raster->format & 0xF00){
|
||||||
case Raster::C8888:
|
case Raster::C8888:
|
||||||
out[0] = in[0];
|
out[0] = in[0];
|
||||||
out[1] = in[1];
|
out[1] = in[1];
|
||||||
out[2] = in[2];
|
out[2] = in[2];
|
||||||
out[3] = in[3]*128/255;
|
out[3] = in[3]*128/255;
|
||||||
in += 4;
|
|
||||||
out += 4;
|
out += 4;
|
||||||
break;
|
break;
|
||||||
case Raster::C888:
|
case Raster::C888:
|
||||||
@ -1715,19 +1714,20 @@ rasterFromImage(Raster *raster, Image *image)
|
|||||||
out[1] = in[1];
|
out[1] = in[1];
|
||||||
out[2] = in[2];
|
out[2] = in[2];
|
||||||
out[3] = 0x80;
|
out[3] = 0x80;
|
||||||
in += 3;
|
|
||||||
out += 4;
|
out += 4;
|
||||||
break;
|
break;
|
||||||
case Raster::C1555:
|
case Raster::C1555:
|
||||||
out[0] = in[0];
|
conv_ARGB1555_from_ABGR1555(out, in);
|
||||||
out[1] = in[1];
|
|
||||||
in += 2;
|
|
||||||
out += 2;
|
out += 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0 && "unknown ps2 raster format");
|
assert(0 && "unknown ps2 raster format");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
in += image->bpp;
|
||||||
|
}
|
||||||
|
src += image->stride;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
raster->unlock(0);
|
raster->unlock(0);
|
||||||
return 1;
|
return 1;
|
||||||
@ -1792,16 +1792,16 @@ rasterToImage(Raster *raster)
|
|||||||
int tw;
|
int tw;
|
||||||
transferMinSize(depth == 4 ? PSMT4 : PSMT8, natras->flags, &minw, &minh);
|
transferMinSize(depth == 4 ? PSMT4 : PSMT8, natras->flags, &minw, &minh);
|
||||||
tw = max(raster->width, minw);
|
tw = max(raster->width, minw);
|
||||||
out = image->pixels;
|
uint8 *dst = image->pixels;
|
||||||
in = raster->lock(0, Raster::LOCKREAD);
|
in = raster->lock(0, Raster::LOCKREAD);
|
||||||
if(depth == 4){
|
if(depth == 4){
|
||||||
expandPSMT4(out, in, raster->width, raster->height, tw);
|
expandPSMT4(dst, image->stride, in, tw/2, raster->width, raster->height);
|
||||||
}else if(depth == 8){
|
}else if(depth == 8){
|
||||||
copyPSMT8(out, in, raster->width, raster->height, tw);
|
copyPSMT8(dst, image->stride, in, tw, raster->width, raster->height);
|
||||||
}else
|
}else{
|
||||||
// TODO: stride
|
for(int32 y = 0; y < image->height; y++){
|
||||||
for(int32 y = 0; y < image->height; y++)
|
out = dst;
|
||||||
for(int32 x = 0; x < image->width; x++)
|
for(int32 x = 0; x < image->width; x++){
|
||||||
switch(raster->format & 0xF00){
|
switch(raster->format & 0xF00){
|
||||||
case Raster::C8888:
|
case Raster::C8888:
|
||||||
out[0] = in[0];
|
out[0] = in[0];
|
||||||
@ -1809,31 +1809,31 @@ rasterToImage(Raster *raster)
|
|||||||
out[2] = in[2];
|
out[2] = in[2];
|
||||||
out[3] = in[3]*255/128;
|
out[3] = in[3]*255/128;
|
||||||
in += 4;
|
in += 4;
|
||||||
out += 4;
|
|
||||||
break;
|
break;
|
||||||
case Raster::C888:
|
case Raster::C888:
|
||||||
out[0] = in[0];
|
out[0] = in[0];
|
||||||
out[1] = in[1];
|
out[1] = in[1];
|
||||||
out[2] = in[2];
|
out[2] = in[2];
|
||||||
in += 4;
|
in += 4;
|
||||||
out += 3;
|
|
||||||
break;
|
break;
|
||||||
case Raster::C1555:
|
case Raster::C1555:
|
||||||
out[0] = in[0];
|
conv_ARGB1555_from_ABGR1555(out, in);
|
||||||
out[1] = in[1];
|
|
||||||
in += 2;
|
in += 2;
|
||||||
out += 2;
|
|
||||||
break;
|
break;
|
||||||
case Raster::C555:
|
case Raster::C555:
|
||||||
out[0] = in[0];
|
conv_ARGB1555_from_ABGR1555(out, in);
|
||||||
out[1] = in[1] | 0x80;
|
out[1] |= 0x80;
|
||||||
in += 2;
|
in += 2;
|
||||||
out += 2;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0 && "unknown ps2 raster format");
|
assert(0 && "unknown ps2 raster format");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
out += image->bpp;
|
||||||
|
}
|
||||||
|
dst += image->stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
raster->unlock(0);
|
raster->unlock(0);
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
|
@ -223,8 +223,9 @@ Texture *readNativeTexture(Stream *stream);
|
|||||||
void writeNativeTexture(Texture *tex, Stream *stream);
|
void writeNativeTexture(Texture *tex, Stream *stream);
|
||||||
uint32 getSizeNativeTexture(Texture *tex);
|
uint32 getSizeNativeTexture(Texture *tex);
|
||||||
|
|
||||||
void expandPSMT4(uint8 *dst, uint8 *src, int32 w, int32 h, int32 srcw);
|
void expandPSMT4(uint8 *dst, uint32 dststride, uint8 *src, uint32 srcstride, int32 w, int32 h);
|
||||||
void copyPSMT8(uint8 *dst, uint8 *src, int32 w, int32 h, int32 srcw);
|
void compressPSMT4(uint8 *dst, uint32 dststride, uint8 *src, uint32 srcstride, int32 w, int32 h);
|
||||||
|
void copyPSMT8(uint8 *dst, uint32 dststride, uint8 *src, uint32 srcstride, int32 w, int32 h);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,7 +222,7 @@ Raster::renderFast(int32 x, int32 y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
conv_RGBA8888_to_RGBA8888(uint8 *out, uint8 *in)
|
conv_RGBA8888_from_RGBA8888(uint8 *out, uint8 *in)
|
||||||
{
|
{
|
||||||
out[0] = in[0];
|
out[0] = in[0];
|
||||||
out[1] = in[1];
|
out[1] = in[1];
|
||||||
@ -231,7 +231,7 @@ conv_RGBA8888_to_RGBA8888(uint8 *out, uint8 *in)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
conv_RGB888_to_RGBA8888(uint8 *out, uint8 *in)
|
conv_RGBA8888_from_RGB888(uint8 *out, uint8 *in)
|
||||||
{
|
{
|
||||||
out[0] = in[0];
|
out[0] = in[0];
|
||||||
out[1] = in[1];
|
out[1] = in[1];
|
||||||
@ -240,7 +240,7 @@ conv_RGB888_to_RGBA8888(uint8 *out, uint8 *in)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
conv_RGB888_to_RGB888(uint8 *out, uint8 *in)
|
conv_RGB888_from_RGB888(uint8 *out, uint8 *in)
|
||||||
{
|
{
|
||||||
out[0] = in[0];
|
out[0] = in[0];
|
||||||
out[1] = in[1];
|
out[1] = in[1];
|
||||||
@ -248,7 +248,7 @@ conv_RGB888_to_RGB888(uint8 *out, uint8 *in)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
conv_RGBA1555_to_RGBA5551(uint8 *out, uint8 *in)
|
conv_RGBA5551_from_ARGB1555(uint8 *out, uint8 *in)
|
||||||
{
|
{
|
||||||
uint32 r, g, b, a;
|
uint32 r, g, b, a;
|
||||||
a = (in[1]>>7) & 1;
|
a = (in[1]>>7) & 1;
|
||||||
@ -260,7 +260,7 @@ conv_RGBA1555_to_RGBA5551(uint8 *out, uint8 *in)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
conv_RGBA1555_to_RGBA8888(uint8 *out, uint8 *in)
|
conv_RGBA8888_from_ARGB1555(uint8 *out, uint8 *in)
|
||||||
{
|
{
|
||||||
uint32 r, g, b, a;
|
uint32 r, g, b, a;
|
||||||
a = (in[1]>>7) & 1;
|
a = (in[1]>>7) & 1;
|
||||||
@ -273,4 +273,14 @@ conv_RGBA1555_to_RGBA8888(uint8 *out, uint8 *in)
|
|||||||
out[3] = a*0xFF;
|
out[3] = a*0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
conv_ABGR1555_from_ARGB1555(uint8 *out, uint8 *in)
|
||||||
|
{
|
||||||
|
uint32 r, b;
|
||||||
|
r = (in[1]>>2) & 0x1F;
|
||||||
|
b = in[0] & 0x1F;
|
||||||
|
out[1] = in[1]&0x83 | b<<2;
|
||||||
|
out[0] = in[0]&0xE0 | r;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,11 @@ struct Image
|
|||||||
void setPixelsDXT(int32 type, uint8 *pixels);
|
void setPixelsDXT(int32 type, uint8 *pixels);
|
||||||
void setPalette(uint8 *palette);
|
void setPalette(uint8 *palette);
|
||||||
bool32 hasAlpha(void);
|
bool32 hasAlpha(void);
|
||||||
void unindex(void);
|
void convertTo32(void);
|
||||||
|
void palettize(int32 depth);
|
||||||
|
void unpalettize(bool forceAlpha = false);
|
||||||
|
void makeMask(void);
|
||||||
|
void applyMask(Image *mask);
|
||||||
void removeMask(void);
|
void removeMask(void);
|
||||||
Image *extractMask(void);
|
Image *extractMask(void);
|
||||||
|
|
||||||
@ -150,6 +154,7 @@ struct Image
|
|||||||
static void printSearchPath(void);
|
static void printSearchPath(void);
|
||||||
static char *getFilename(const char*);
|
static char *getFilename(const char*);
|
||||||
static Image *read(const char *imageName);
|
static Image *read(const char *imageName);
|
||||||
|
static Image *readMasked(const char *imageName, const char *maskName);
|
||||||
|
|
||||||
|
|
||||||
typedef Image *(*fileRead)(const char *afilename);
|
typedef Image *(*fileRead)(const char *afilename);
|
||||||
@ -166,6 +171,38 @@ void writeTGA(Image *image, const char *filename);
|
|||||||
Image *readBMP(const char *filename);
|
Image *readBMP(const char *filename);
|
||||||
void writeBMP(Image *image, const char *filename);
|
void writeBMP(Image *image, const char *filename);
|
||||||
|
|
||||||
|
enum { QUANTDEPTH = 8 };
|
||||||
|
|
||||||
|
struct ColorQuant
|
||||||
|
{
|
||||||
|
struct Node {
|
||||||
|
uint32 r, g, b, a;
|
||||||
|
int32 numPixels;
|
||||||
|
Node *parent;
|
||||||
|
Node *children[16];
|
||||||
|
LLLink link;
|
||||||
|
|
||||||
|
void destroy(void);
|
||||||
|
void addColor(RGBA color);
|
||||||
|
bool isLeaf(void) { for(int32 i = 0; i < 16; i++) if(this->children[i]) return false; return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
Node *root;
|
||||||
|
LinkList leaves;
|
||||||
|
|
||||||
|
void init(void);
|
||||||
|
void destroy(void);
|
||||||
|
Node *createNode(int32 level);
|
||||||
|
Node *getNode(Node *root, uint32 addr, int32 level);
|
||||||
|
Node *findNode(Node *root, uint32 addr, int32 level);
|
||||||
|
void reduceNode(Node *node);
|
||||||
|
void addColor(RGBA color);
|
||||||
|
uint8 findColor(RGBA color);
|
||||||
|
void addImage(Image *img);
|
||||||
|
void makePalette(int32 numColors, RGBA *colors);
|
||||||
|
void matchImage(uint8 *dstPixels, uint32 dstStride, Image *src);
|
||||||
|
};
|
||||||
|
|
||||||
// used to emulate d3d and xbox textures
|
// used to emulate d3d and xbox textures
|
||||||
struct RasterLevels
|
struct RasterLevels
|
||||||
{
|
{
|
||||||
@ -265,11 +302,13 @@ struct Raster
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
void conv_RGBA8888_to_RGBA8888(uint8 *out, uint8 *in);
|
void conv_RGBA8888_from_RGBA8888(uint8 *out, uint8 *in);
|
||||||
void conv_RGB888_to_RGBA8888(uint8 *out, uint8 *in);
|
void conv_RGBA8888_from_RGB888(uint8 *out, uint8 *in);
|
||||||
void conv_RGB888_to_RGB888(uint8 *out, uint8 *in);
|
void conv_RGB888_from_RGB888(uint8 *out, uint8 *in);
|
||||||
void conv_RGBA1555_to_RGBA5551(uint8 *out, uint8 *in);
|
void conv_RGBA5551_from_ARGB1555(uint8 *out, uint8 *in);
|
||||||
void conv_RGBA1555_to_RGBA8888(uint8 *out, uint8 *in);
|
void conv_RGBA8888_from_ARGB1555(uint8 *out, uint8 *in);
|
||||||
|
void conv_ABGR1555_from_ARGB1555(uint8 *out, uint8 *in);
|
||||||
|
inline void conv_ARGB1555_from_ABGR1555(uint8 *out, uint8 *in) { conv_ABGR1555_from_ARGB1555(out, in); }
|
||||||
|
|
||||||
|
|
||||||
#define IGNORERASTERIMP 0
|
#define IGNORERASTERIMP 0
|
||||||
|
@ -299,14 +299,13 @@ defaultFindCB(const char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: actually read the mask!
|
|
||||||
static Texture*
|
static Texture*
|
||||||
defaultReadCB(const char *name, const char *mask)
|
defaultReadCB(const char *name, const char *mask)
|
||||||
{
|
{
|
||||||
Texture *tex;
|
Texture *tex;
|
||||||
Image *img;
|
Image *img;
|
||||||
|
|
||||||
img = Image::read(name);
|
img = Image::readMasked(name, mask);
|
||||||
if(img){
|
if(img){
|
||||||
tex = Texture::create(Raster::createFromImage(img));
|
tex = Texture::create(Raster::createFromImage(img));
|
||||||
strncpy(tex->name, name, 32);
|
strncpy(tex->name, name, 32);
|
||||||
|
@ -27,6 +27,9 @@ void genIm3DEnd(void);
|
|||||||
void initFont(void);
|
void initFont(void);
|
||||||
void printScreen(const char *s, float x, float y);
|
void printScreen(const char *s, float x, float y);
|
||||||
|
|
||||||
|
void initsplines(void);
|
||||||
|
void rendersplines(void);
|
||||||
|
|
||||||
rw::Charset *testfont;
|
rw::Charset *testfont;
|
||||||
|
|
||||||
//#include <Windows.h>
|
//#include <Windows.h>
|
||||||
@ -236,7 +239,7 @@ InitRW(void)
|
|||||||
Scene.camera = sk::CameraCreate(sk::globals.width, sk::globals.height, 1);
|
Scene.camera = sk::CameraCreate(sk::globals.width, sk::globals.height, 1);
|
||||||
camera->m_rwcam = Scene.camera;
|
camera->m_rwcam = Scene.camera;
|
||||||
camera->m_aspectRatio = 640.0f/448.0f;
|
camera->m_aspectRatio = 640.0f/448.0f;
|
||||||
camera->m_near = 5.0f;
|
camera->m_near = 0.5f;
|
||||||
// camera->m_far = 450.0f;
|
// camera->m_far = 450.0f;
|
||||||
camera->m_far = 15.0f;
|
camera->m_far = 15.0f;
|
||||||
camera->m_target.set(0.0f, 0.0f, 0.0f);
|
camera->m_target.set(0.0f, 0.0f, 0.0f);
|
||||||
@ -248,6 +251,8 @@ InitRW(void)
|
|||||||
|
|
||||||
Scene.world->addCamera(camera->m_rwcam);
|
Scene.world->addCamera(camera->m_rwcam);
|
||||||
|
|
||||||
|
initsplines();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,7 +387,7 @@ Draw(float timeDelta)
|
|||||||
{
|
{
|
||||||
getFrontBuffer();
|
getFrontBuffer();
|
||||||
|
|
||||||
static rw::RGBA clearcol = { 0x60, 0x60, 0x60, 0xFF };
|
static rw::RGBA clearcol = { 161, 161, 161, 0xFF };
|
||||||
camera->m_rwcam->clear(&clearcol, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ);
|
camera->m_rwcam->clear(&clearcol, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ);
|
||||||
camera->update();
|
camera->update();
|
||||||
camera->m_rwcam->beginUpdate();
|
camera->m_rwcam->beginUpdate();
|
||||||
@ -401,10 +406,12 @@ extern void endSoftras(void);
|
|||||||
// im2dtest();
|
// im2dtest();
|
||||||
|
|
||||||
// Scene.clump->render();
|
// Scene.clump->render();
|
||||||
im3dtest();
|
// im3dtest();
|
||||||
// printScreen("Hello, World!", 10, 10);
|
// printScreen("Hello, World!", 10, 10);
|
||||||
|
|
||||||
testfont->print("foo ABC", 200, 200, true);
|
// testfont->print("foo ABC", 200, 200, true);
|
||||||
|
|
||||||
|
rendersplines();
|
||||||
|
|
||||||
camera->m_rwcam->endUpdate();
|
camera->m_rwcam->endUpdate();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user