mirror of https://github.com/aap/librw.git
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);
|
||||
}
|
||||
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
@ -352,22 +493,4 @@ Raster::createFromImage(Image *image)
|
|||
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
|
||||
Raster::upload(void)
|
||||
Texture::upload(void)
|
||||
{
|
||||
GLuint id;
|
||||
glGenTextures(1, &id);
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
if(this->palette){
|
||||
Raster *r = this->raster;
|
||||
if(r->palette){
|
||||
printf("can't upload paletted raster\n");
|
||||
return;
|
||||
}
|
||||
switch(this->format & 0xF00){
|
||||
case C8888:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 4, this->width, this->height,
|
||||
0, GL_RGBA, GL_UNSIGNED_BYTE, this->texels);
|
||||
|
||||
static GLenum filter[] = {
|
||||
0, GL_NEAREST, GL_LINEAR,
|
||||
GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST,
|
||||
GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR
|
||||
};
|
||||
static GLenum filternomip[] = {
|
||||
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;
|
||||
default:
|
||||
printf("unsupported raster format: %x\n", this->format);
|
||||
printf("unsupported raster format: %x\n", r->format);
|
||||
break;
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
GlRaster *glr = PLUGINOFFSET(GlRaster, this, NativeRasterOffset);
|
||||
GlRaster *glr = PLUGINOFFSET(GlRaster, r, NativeRasterOffset);
|
||||
glr->id = id;
|
||||
}
|
||||
|
||||
void
|
||||
Raster::bind(int n)
|
||||
Texture::bind(int n)
|
||||
{
|
||||
GlRaster *raster = PLUGINOFFSET(GlRaster, this, NativeRasterOffset);
|
||||
if(raster->id == 0)
|
||||
this->upload();
|
||||
Raster *r = this->raster;
|
||||
GlRaster *glr = PLUGINOFFSET(GlRaster, r, NativeRasterOffset);
|
||||
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);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -107,7 +107,6 @@ struct Raster : PluginBase<Raster>
|
|||
~Raster(void);
|
||||
|
||||
static Raster *createFromImage(Image *image);
|
||||
static Raster *read(const char *name, const char *mask);
|
||||
|
||||
enum Format {
|
||||
DEFAULT = 0,
|
||||
|
@ -137,12 +136,16 @@ struct Texture : PluginBase<Texture>
|
|||
Raster *raster;
|
||||
int32 refCount;
|
||||
|
||||
// temporary - pointer to next tex in dictionary
|
||||
Texture *next;
|
||||
|
||||
Texture(void);
|
||||
~Texture(void);
|
||||
void decRef(void);
|
||||
static Texture *streamRead(Stream *stream);
|
||||
bool streamWrite(Stream *stream);
|
||||
uint32 streamGetSize(void);
|
||||
static Texture *read(const char *name, const char *mask);
|
||||
|
||||
enum FilterMode {
|
||||
NEAREST = 1,
|
||||
|
@ -390,4 +393,15 @@ private:
|
|||
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
|
||||
|
||||
struct Raster : Rw::Raster
|
||||
struct Texture : Rw::Texture
|
||||
{
|
||||
void upload(void);
|
||||
void bind(int n);
|
||||
|
|
|
@ -49,15 +49,11 @@ renderAtomic(Rw::Atomic *atomic)
|
|||
color[3] = col[3] / 255.0f;
|
||||
glUniform4fv(glGetUniformLocation(program, "matColor"),
|
||||
1, color);
|
||||
Texture *tex = mesh->material->texture;
|
||||
if(tex){
|
||||
Rw::Gl::Raster *raster = (Rw::Gl::Raster*)tex->raster;
|
||||
if(raster)
|
||||
raster->bind(0);
|
||||
Rw::Gl::Texture *tex =(Rw::Gl::Texture*)mesh->material->texture;
|
||||
if(tex)
|
||||
tex->bind(0);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}else
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDrawElements(prim[meshHeader->flags], mesh->numIndices,
|
||||
GL_UNSIGNED_SHORT, (void*)offset);
|
||||
offset += mesh->numIndices*2;
|
||||
|
@ -73,6 +69,7 @@ renderAtomic(Rw::Atomic *atomic)
|
|||
void
|
||||
render(void)
|
||||
{
|
||||
static Mat4 worldMat(1.0f);
|
||||
glUseProgram(program);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
|
@ -81,6 +78,8 @@ render(void)
|
|||
1, GL_FALSE, camera->projMat.cr);
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "viewMat"),
|
||||
1, GL_FALSE, camera->viewMat.cr);
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "worldMat"),
|
||||
1, GL_FALSE, worldMat.cr);
|
||||
|
||||
glVertexAttrib3f(2, -0.5f, 0.5f, 0.70710f);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
|
@ -181,6 +180,7 @@ init(void)
|
|||
camera->setTarget(Vec3(0.0f, 0.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/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/");
|
||||
|
|
Loading…
Reference in New Issue