mirror of
https://github.com/aap/librw.git
synced 2024-11-25 05:05:42 +00:00
Implemented basic TexDictionary.
This commit is contained in:
parent
fb78a7a7b9
commit
62c6fe006e
@ -430,90 +430,4 @@ RegisterMaterialRightsPlugin(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Texture
|
|
||||||
//
|
|
||||||
|
|
||||||
Texture::Texture(void)
|
|
||||||
{
|
|
||||||
memset(this->name, 0, 32);
|
|
||||||
memset(this->mask, 0, 32);
|
|
||||||
this->filterAddressing = (WRAP << 12) | (WRAP << 8) | NEAREST;
|
|
||||||
this->raster = NULL;
|
|
||||||
this->refCount = 1;
|
|
||||||
this->constructPlugins();
|
|
||||||
}
|
|
||||||
|
|
||||||
Texture::~Texture(void)
|
|
||||||
{
|
|
||||||
this->destructPlugins();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Texture::decRef(void)
|
|
||||||
{
|
|
||||||
this->refCount--;
|
|
||||||
if(this->refCount)
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Texture*
|
|
||||||
Texture::streamRead(Stream *stream)
|
|
||||||
{
|
|
||||||
uint32 length;
|
|
||||||
assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
|
|
||||||
Texture *tex = new Texture;
|
|
||||||
tex->filterAddressing = stream->readU16();
|
|
||||||
// TODO: what is this? (mipmap? i think)
|
|
||||||
stream->seek(2);
|
|
||||||
|
|
||||||
assert(FindChunk(stream, ID_STRING, &length, NULL));
|
|
||||||
stream->read(tex->name, length);
|
|
||||||
|
|
||||||
assert(FindChunk(stream, ID_STRING, &length, NULL));
|
|
||||||
stream->read(tex->mask, length);
|
|
||||||
|
|
||||||
tex->raster = Raster::read(tex->name, tex->mask);
|
|
||||||
if(tex->raster == NULL)
|
|
||||||
printf("didn't find texture %s\n", tex->name);
|
|
||||||
|
|
||||||
tex->streamReadPlugins(stream);
|
|
||||||
|
|
||||||
return tex;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Texture::streamWrite(Stream *stream)
|
|
||||||
{
|
|
||||||
int size;
|
|
||||||
WriteChunkHeader(stream, ID_TEXTURE, this->streamGetSize());
|
|
||||||
WriteChunkHeader(stream, ID_STRUCT, 4);
|
|
||||||
stream->writeU32(this->filterAddressing);
|
|
||||||
|
|
||||||
// TODO: length can't be > 32
|
|
||||||
size = strlen(this->name)+4 & ~3;
|
|
||||||
WriteChunkHeader(stream, ID_STRING, size);
|
|
||||||
stream->write(this->name, size);
|
|
||||||
|
|
||||||
size = strlen(this->mask)+4 & ~3;
|
|
||||||
WriteChunkHeader(stream, ID_STRING, size);
|
|
||||||
stream->write(this->mask, size);
|
|
||||||
|
|
||||||
this->streamWritePlugins(stream);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32
|
|
||||||
Texture::streamGetSize(void)
|
|
||||||
{
|
|
||||||
uint32 size = 0;
|
|
||||||
int strsize;
|
|
||||||
size += 12 + 4;
|
|
||||||
size += 12 + 12;
|
|
||||||
size += strlen(this->name)+4 & ~3;
|
|
||||||
size += strlen(this->mask)+4 & ~3;
|
|
||||||
size += 12 + this->streamGetPluginSize();
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
159
src/image.cpp
159
src/image.cpp
@ -29,6 +29,147 @@ writeUInt8(uint8 tmp, ostream &rw)
|
|||||||
return sizeof(uint8);
|
return sizeof(uint8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// TexDictionary
|
||||||
|
//
|
||||||
|
|
||||||
|
TexDictionary *CurrentTexDictionary;
|
||||||
|
|
||||||
|
TexDictionary::TexDictionary(void)
|
||||||
|
{
|
||||||
|
this->first = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TexDictionary::add(Texture *tex)
|
||||||
|
{
|
||||||
|
tex->next = this->first;
|
||||||
|
this->first = tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture*
|
||||||
|
TexDictionary::find(const char *name)
|
||||||
|
{
|
||||||
|
for(Texture *tex = this->first; tex; tex = tex->next)
|
||||||
|
if(strncmp(tex->name, name, 32) == 0)
|
||||||
|
return tex;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Texture
|
||||||
|
//
|
||||||
|
|
||||||
|
Texture::Texture(void)
|
||||||
|
{
|
||||||
|
memset(this->name, 0, 32);
|
||||||
|
memset(this->mask, 0, 32);
|
||||||
|
this->filterAddressing = (WRAP << 12) | (WRAP << 8) | NEAREST;
|
||||||
|
this->raster = NULL;
|
||||||
|
this->refCount = 1;
|
||||||
|
this->next = NULL;
|
||||||
|
this->constructPlugins();
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture::~Texture(void)
|
||||||
|
{
|
||||||
|
this->destructPlugins();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Texture::decRef(void)
|
||||||
|
{
|
||||||
|
this->refCount--;
|
||||||
|
if(this->refCount)
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: do this properly, pretty ugly right now
|
||||||
|
Texture*
|
||||||
|
Texture::read(const char *name, const char *mask)
|
||||||
|
{
|
||||||
|
(void)mask;
|
||||||
|
Raster *raster = NULL;
|
||||||
|
Texture *tex;
|
||||||
|
|
||||||
|
if((tex = CurrentTexDictionary->find(name)))
|
||||||
|
return tex;
|
||||||
|
tex = new Texture;
|
||||||
|
strncpy(tex->name, name, 32);
|
||||||
|
strncpy(tex->mask, mask, 32);
|
||||||
|
char *n = (char*)malloc(strlen(name) + 5);
|
||||||
|
strcpy(n, name);
|
||||||
|
strcat(n, ".tga");
|
||||||
|
Image *img = readTGA(n);
|
||||||
|
free(n);
|
||||||
|
if(img){
|
||||||
|
raster = Raster::createFromImage(img);
|
||||||
|
delete img;
|
||||||
|
}
|
||||||
|
tex->raster = raster;
|
||||||
|
CurrentTexDictionary->add(tex);
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture*
|
||||||
|
Texture::streamRead(Stream *stream)
|
||||||
|
{
|
||||||
|
uint32 length;
|
||||||
|
char name[32], mask[32];
|
||||||
|
assert(FindChunk(stream, ID_STRUCT, NULL, NULL));
|
||||||
|
uint32 filterAddressing = stream->readU16();
|
||||||
|
// TODO: what is this? (mipmap? i think)
|
||||||
|
stream->seek(2);
|
||||||
|
|
||||||
|
assert(FindChunk(stream, ID_STRING, &length, NULL));
|
||||||
|
stream->read(name, length);
|
||||||
|
|
||||||
|
assert(FindChunk(stream, ID_STRING, &length, NULL));
|
||||||
|
stream->read(mask, length);
|
||||||
|
|
||||||
|
Texture *tex = Texture::read(name, mask);
|
||||||
|
tex->refCount++;
|
||||||
|
tex->filterAddressing = filterAddressing;
|
||||||
|
|
||||||
|
tex->streamReadPlugins(stream);
|
||||||
|
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Texture::streamWrite(Stream *stream)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
WriteChunkHeader(stream, ID_TEXTURE, this->streamGetSize());
|
||||||
|
WriteChunkHeader(stream, ID_STRUCT, 4);
|
||||||
|
stream->writeU32(this->filterAddressing);
|
||||||
|
|
||||||
|
// TODO: length can't be > 32
|
||||||
|
size = strlen(this->name)+4 & ~3;
|
||||||
|
WriteChunkHeader(stream, ID_STRING, size);
|
||||||
|
stream->write(this->name, size);
|
||||||
|
|
||||||
|
size = strlen(this->mask)+4 & ~3;
|
||||||
|
WriteChunkHeader(stream, ID_STRING, size);
|
||||||
|
stream->write(this->mask, size);
|
||||||
|
|
||||||
|
this->streamWritePlugins(stream);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
Texture::streamGetSize(void)
|
||||||
|
{
|
||||||
|
uint32 size = 0;
|
||||||
|
int strsize;
|
||||||
|
size += 12 + 4;
|
||||||
|
size += 12 + 12;
|
||||||
|
size += strlen(this->name)+4 & ~3;
|
||||||
|
size += strlen(this->mask)+4 & ~3;
|
||||||
|
size += 12 + this->streamGetPluginSize();
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Image
|
// Image
|
||||||
//
|
//
|
||||||
@ -352,22 +493,4 @@ Raster::createFromImage(Image *image)
|
|||||||
return raster;
|
return raster;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: do this properly, only an ugly hack right now
|
|
||||||
Raster*
|
|
||||||
Raster::read(const char *name, const char *mask)
|
|
||||||
{
|
|
||||||
(void)mask;
|
|
||||||
char *n = (char*)malloc(strlen(name) + 5);
|
|
||||||
strcpy(n, name);
|
|
||||||
strcat(n, ".tga");
|
|
||||||
Image *img = readTGA(n);
|
|
||||||
free(n);
|
|
||||||
if(img){
|
|
||||||
Raster *raster = Raster::createFromImage(img);
|
|
||||||
delete img;
|
|
||||||
return raster;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
61
src/ogl.cpp
61
src/ogl.cpp
@ -432,42 +432,69 @@ RegisterNativeRaster(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Raster::upload(void)
|
Texture::upload(void)
|
||||||
{
|
{
|
||||||
GLuint id;
|
GLuint id;
|
||||||
glGenTextures(1, &id);
|
glGenTextures(1, &id);
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
if(this->palette){
|
Raster *r = this->raster;
|
||||||
|
if(r->palette){
|
||||||
printf("can't upload paletted raster\n");
|
printf("can't upload paletted raster\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch(this->format & 0xF00){
|
|
||||||
case C8888:
|
static GLenum filter[] = {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
0, GL_NEAREST, GL_LINEAR,
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST,
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
};
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, 4, this->width, this->height,
|
static GLenum filternomip[] = {
|
||||||
0, GL_RGBA, GL_UNSIGNED_BYTE, this->texels);
|
0, GL_NEAREST, GL_LINEAR,
|
||||||
|
GL_NEAREST, GL_LINEAR,
|
||||||
|
GL_NEAREST, GL_LINEAR
|
||||||
|
};
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||||
|
filternomip[this->filterAddressing & 0xFF]);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||||
|
filternomip[this->filterAddressing & 0xFF]);
|
||||||
|
|
||||||
|
static GLenum wrap[] = {
|
||||||
|
0, GL_REPEAT, GL_MIRRORED_REPEAT,
|
||||||
|
GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER
|
||||||
|
};
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
|
||||||
|
wrap[(this->filterAddressing >> 8) & 0xF]);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
|
||||||
|
wrap[(this->filterAddressing >> 12) & 0xF]);
|
||||||
|
|
||||||
|
switch(r->format & 0xF00){
|
||||||
|
case Raster::C8888:
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, 4, r->width, r->height,
|
||||||
|
0, GL_RGBA, GL_UNSIGNED_BYTE, r->texels);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("unsupported raster format: %x\n", this->format);
|
printf("unsupported raster format: %x\n", r->format);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
GlRaster *glr = PLUGINOFFSET(GlRaster, this, NativeRasterOffset);
|
GlRaster *glr = PLUGINOFFSET(GlRaster, r, NativeRasterOffset);
|
||||||
glr->id = id;
|
glr->id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Raster::bind(int n)
|
Texture::bind(int n)
|
||||||
{
|
{
|
||||||
GlRaster *raster = PLUGINOFFSET(GlRaster, this, NativeRasterOffset);
|
Raster *r = this->raster;
|
||||||
if(raster->id == 0)
|
GlRaster *glr = PLUGINOFFSET(GlRaster, r, NativeRasterOffset);
|
||||||
this->upload();
|
|
||||||
glActiveTexture(GL_TEXTURE0+n);
|
glActiveTexture(GL_TEXTURE0+n);
|
||||||
glBindTexture(GL_TEXTURE_2D, raster->id);
|
if(r){
|
||||||
|
if(glr->id == 0)
|
||||||
|
this->upload();
|
||||||
|
glBindTexture(GL_TEXTURE_2D, glr->id);
|
||||||
|
}else
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -107,7 +107,6 @@ struct Raster : PluginBase<Raster>
|
|||||||
~Raster(void);
|
~Raster(void);
|
||||||
|
|
||||||
static Raster *createFromImage(Image *image);
|
static Raster *createFromImage(Image *image);
|
||||||
static Raster *read(const char *name, const char *mask);
|
|
||||||
|
|
||||||
enum Format {
|
enum Format {
|
||||||
DEFAULT = 0,
|
DEFAULT = 0,
|
||||||
@ -137,12 +136,16 @@ struct Texture : PluginBase<Texture>
|
|||||||
Raster *raster;
|
Raster *raster;
|
||||||
int32 refCount;
|
int32 refCount;
|
||||||
|
|
||||||
|
// temporary - pointer to next tex in dictionary
|
||||||
|
Texture *next;
|
||||||
|
|
||||||
Texture(void);
|
Texture(void);
|
||||||
~Texture(void);
|
~Texture(void);
|
||||||
void decRef(void);
|
void decRef(void);
|
||||||
static Texture *streamRead(Stream *stream);
|
static Texture *streamRead(Stream *stream);
|
||||||
bool streamWrite(Stream *stream);
|
bool streamWrite(Stream *stream);
|
||||||
uint32 streamGetSize(void);
|
uint32 streamGetSize(void);
|
||||||
|
static Texture *read(const char *name, const char *mask);
|
||||||
|
|
||||||
enum FilterMode {
|
enum FilterMode {
|
||||||
NEAREST = 1,
|
NEAREST = 1,
|
||||||
@ -390,4 +393,15 @@ private:
|
|||||||
void frameListStreamWrite(Stream *stream, Frame **flp, int32 nf);
|
void frameListStreamWrite(Stream *stream, Frame **flp, int32 nf);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TexDictionary
|
||||||
|
{
|
||||||
|
Texture *first;
|
||||||
|
|
||||||
|
TexDictionary(void);
|
||||||
|
void add(Texture *tex);
|
||||||
|
Texture *find(const char *name);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern TexDictionary *CurrentTexDictionary;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ int32 GetSizeNativeSkin(void *object, int32 offset);
|
|||||||
|
|
||||||
// Raster
|
// Raster
|
||||||
|
|
||||||
struct Raster : Rw::Raster
|
struct Texture : Rw::Texture
|
||||||
{
|
{
|
||||||
void upload(void);
|
void upload(void);
|
||||||
void bind(int n);
|
void bind(int n);
|
||||||
|
@ -49,14 +49,10 @@ renderAtomic(Rw::Atomic *atomic)
|
|||||||
color[3] = col[3] / 255.0f;
|
color[3] = col[3] / 255.0f;
|
||||||
glUniform4fv(glGetUniformLocation(program, "matColor"),
|
glUniform4fv(glGetUniformLocation(program, "matColor"),
|
||||||
1, color);
|
1, color);
|
||||||
Texture *tex = mesh->material->texture;
|
Rw::Gl::Texture *tex =(Rw::Gl::Texture*)mesh->material->texture;
|
||||||
if(tex){
|
if(tex)
|
||||||
Rw::Gl::Raster *raster = (Rw::Gl::Raster*)tex->raster;
|
tex->bind(0);
|
||||||
if(raster)
|
else
|
||||||
raster->bind(0);
|
|
||||||
else
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}else
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
glDrawElements(prim[meshHeader->flags], mesh->numIndices,
|
glDrawElements(prim[meshHeader->flags], mesh->numIndices,
|
||||||
GL_UNSIGNED_SHORT, (void*)offset);
|
GL_UNSIGNED_SHORT, (void*)offset);
|
||||||
@ -73,6 +69,7 @@ renderAtomic(Rw::Atomic *atomic)
|
|||||||
void
|
void
|
||||||
render(void)
|
render(void)
|
||||||
{
|
{
|
||||||
|
static Mat4 worldMat(1.0f);
|
||||||
glUseProgram(program);
|
glUseProgram(program);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
@ -81,6 +78,8 @@ render(void)
|
|||||||
1, GL_FALSE, camera->projMat.cr);
|
1, GL_FALSE, camera->projMat.cr);
|
||||||
glUniformMatrix4fv(glGetUniformLocation(program, "viewMat"),
|
glUniformMatrix4fv(glGetUniformLocation(program, "viewMat"),
|
||||||
1, GL_FALSE, camera->viewMat.cr);
|
1, GL_FALSE, camera->viewMat.cr);
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(program, "worldMat"),
|
||||||
|
1, GL_FALSE, worldMat.cr);
|
||||||
|
|
||||||
glVertexAttrib3f(2, -0.5f, 0.5f, 0.70710f);
|
glVertexAttrib3f(2, -0.5f, 0.5f, 0.70710f);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
@ -181,6 +180,7 @@ init(void)
|
|||||||
camera->setTarget(Vec3(0.0f, 0.0f, 0.0f));
|
camera->setTarget(Vec3(0.0f, 0.0f, 0.0f));
|
||||||
camera->setPosition(Vec3(0.0f, 5.0f, 0.0f));
|
camera->setPosition(Vec3(0.0f, 5.0f, 0.0f));
|
||||||
|
|
||||||
|
Rw::CurrentTexDictionary = new Rw::TexDictionary;
|
||||||
// Rw::Image::setSearchPath("/home/aap/gamedata/ps2/gtasa/models/gta3_archive/txd_extracted/");
|
// Rw::Image::setSearchPath("/home/aap/gamedata/ps2/gtasa/models/gta3_archive/txd_extracted/");
|
||||||
// Rw::Image::setSearchPath("/home/aap/gamedata/ps2/gtavc/MODELS/gta3_archive/txd_extracted/");
|
// Rw::Image::setSearchPath("/home/aap/gamedata/ps2/gtavc/MODELS/gta3_archive/txd_extracted/");
|
||||||
Rw::Image::setSearchPath("/home/aap/gamedata/ps2/gtavc/MODELS/gta3_archive/txd_extracted/;/home/aap/gamedata/ps2/gtasa/models/gta3_archive/txd_extracted/");
|
Rw::Image::setSearchPath("/home/aap/gamedata/ps2/gtavc/MODELS/gta3_archive/txd_extracted/;/home/aap/gamedata/ps2/gtasa/models/gta3_archive/txd_extracted/");
|
||||||
|
Loading…
Reference in New Issue
Block a user