From 14aebe2d3a5eb0c690ffea5377d52d8410cc3ab9 Mon Sep 17 00:00:00 2001 From: slack Date: Mon, 13 Oct 2008 05:00:18 +0200 Subject: [PATCH] Model & texture code improved (including new exporter format), new ship model+texture, WIP new texture format and GU_PSM_5650 conversion tool --- README | 4 + game.cc | 24 ++--- gfx.cc | 24 +++-- gfx.h | 3 + model.cc | 42 ++++++-- model.h | 15 +-- models/shipdawhip.lob | Bin 0 -> 57392 bytes models/shipdawhip.tga | Bin 0 -> 65554 bytes texture.cc | 220 +++++++++++++++++++++++++++++++++++--- texture.h | 14 ++- tools/blender_exporter.py | 88 ++++++++++++++- tools/tga2ltx.cc | 15 +++ 12 files changed, 378 insertions(+), 71 deletions(-) create mode 100644 README create mode 100644 models/shipdawhip.lob create mode 100644 models/shipdawhip.tga create mode 100644 tools/tga2ltx.cc diff --git a/README b/README new file mode 100644 index 0000000..fc7ee55 --- /dev/null +++ b/README @@ -0,0 +1,4 @@ +Ship models from: + +http://www.turbosquid.com/3d-models/3d-spaceship-ship-space-model/408426 + diff --git a/game.cc b/game.cc index 2bcfab7..9099a59 100644 --- a/game.cc +++ b/game.cc @@ -17,8 +17,8 @@ int game_main(int argc, char **argv) GFX.init(); //Model cube("colors-noUV.lob"); - Model cube("models/ship.lob"); - Texture texture("models/ship.tga"); + Model cube("models/shipdawhip.lob"); + Texture texture("models/shipdawhip.tga"); //sceKernelDcacheWritebackRange(cube.vertices, cube.num_vertices * sizeof(Vertex)); //sceKernelDcacheWritebackRange(cube.indices, cube.num_faces * sizeof(unsigned short)); //sceKernelDcacheWritebackRange(&cube, sizeof(cube)); @@ -26,10 +26,7 @@ int game_main(int argc, char **argv) GFX.perspective(75.0f, 16.0f/9.0f, 0.5f, 1000.0f); - ScePspFVector3 eye={0,0,-10}; - ScePspFVector3 center={0,0,0}; - ScePspFVector3 up={0,1,0}; - GFX.look_at(&eye, ¢er, &up); + GFX.look_at(0,0,-15, 0,0,0, 0,1,0); sceGumMatrixMode(GU_MODEL); int i=0; @@ -44,20 +41,11 @@ int game_main(int argc, char **argv) sceGumRotateY(0.001f*i); sceGumRotateZ(0.001f*i); sceGuColor(GU_COLOR(1.0f,1.0f,1.0f,0.0f)); - sceGuTexImage( 0, texture.width, texture.height, texture.width, texture.pixels ); - sceGumDrawArray(GU_TRIANGLES, - GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_NORMAL_32BITF | - GU_VERTEX_32BITF | GU_TRANSFORM_3D | GU_INDEX_16BIT, cube.num_faces*3, - cube.indices, cube.vertices); + texture.bind(); + sceGumDrawArray(GU_TRIANGLES, cube.vtype | GU_TRANSFORM_3D, + cube.num_faces*3, cube.indices, cube.vertices); - ScePspFVector3 move={4,0,0}; - sceGumLoadIdentity(); - sceGumRotateZ(0.001f*i); - sceGumTranslate(&move); - - sceGuColor(GU_COLOR(1.0f,0.0f,0.0f,0.0f)); - sceGumDrawArray(GU_TRIANGLES, GU_VERTEX_32BITF | GU_TRANSFORM_3D, 3, 0, triangle); sceGuFinish(); sceGuSync(0,0); diff --git a/gfx.cc b/gfx.cc index 6268c6c..c7f1b5d 100644 --- a/gfx.cc +++ b/gfx.cc @@ -38,18 +38,17 @@ void Gfx::init() sceGuDepthFunc( GU_GEQUAL ); sceGuEnable( GU_DEPTH_TEST ); sceGuShadeModel( GU_SMOOTH ); - sceGuFrontFace( GU_CW ); - //sceGuEnable( GU_CULL_FACE ); - //sceGuEnable( GU_CLIP_PLANES ); + sceGuFrontFace( GU_CCW ); + sceGuEnable( GU_CULL_FACE ); + sceGuEnable( GU_CLIP_PLANES ); // set clear color/depth - sceGuClearColor( GU_COLOR( 1.0f, 0.0f, 1.0f, 1.0f ) ); + sceGuClearColor( GU_COLOR( 0.0f, 0.0f, 0.0f, 1.0f ) ); sceGuClearDepth(0); // setup texture sceGuEnable(GU_TEXTURE_2D); //Enable Texture2D - sceGuTexMode( GU_PSM_8888, 0, 0, 0 ); // last 0 must be 1 if swizzled - sceGuTexFunc( GU_TFX_DECAL, GU_TCC_RGB ); + sceGuTexFunc( GU_TFX_MODULATE, GU_TCC_RGB ); sceGuTexFilter( GU_LINEAR, GU_LINEAR ); // Linear filtering (Good Quality) (NEW) sceGuTexScale( 1.0f, 1.0f ); // No scaling sceGuTexOffset( 0.0f, 0.0f ); @@ -69,6 +68,7 @@ void Gfx::init() void Gfx::cleanup() { sceGuTerm(); + free(display_list); } void Gfx::update_fps( void ) @@ -79,7 +79,8 @@ void Gfx::update_fps( void ) if( ((fps_tick_now - fps_tick_last)/((float)tick_resolution)) >= 1.0f ) { fps_tick_last = fps_tick_now; - sprintf( fps_display, "ticks=%f, FPS: %d", ((double)fps_tick_now/(double)tick_resolution), frames_drawn ); + //sprintf( fps_display, "ticks=%f, FPS: %d", ((double)fps_tick_now/(double)tick_resolution), frames_drawn ); + sprintf( fps_display, "FPS: %d", frames_drawn ); frames_drawn = 0; } pspDebugScreenSetOffset( (int)fbp0 ); @@ -101,11 +102,16 @@ void Gfx::perspective(float fov, float aspect, float znear, float zfar) sceGumPerspective(fov, aspect, znear, zfar); } -void Gfx::look_at(ScePspFVector3 *eye, ScePspFVector3 *center, ScePspFVector3 *up) +void Gfx::look_at(float eye_x, float eye_y, float eye_z, + float center_x, float center_y, float center_z, + float up_x, float up_y, float up_z) { sceGumMatrixMode(GU_VIEW); sceGumLoadIdentity(); - sceGumLookAt(eye, center, up); + ScePspFVector3 eye={eye_x, eye_y, eye_z}; + ScePspFVector3 center={center_x, center_y, center_z}; + ScePspFVector3 up={up_x, up_y, up_z}; + sceGumLookAt(&eye, ¢er, &up); } diff --git a/gfx.h b/gfx.h index 83eb2d4..7ef25e5 100644 --- a/gfx.h +++ b/gfx.h @@ -27,6 +27,9 @@ class Gfx: public Singleton void perspective(float fov, float aspect, float znear, float zfar); void look_at(ScePspFVector3 *eye, ScePspFVector3 *center, ScePspFVector3 *up); + void look_at(float eye_x, float eye_y, float eye_z, + float center_x, float center_y, float center_z, + float up_x, float up_y, float up_z); }; #define GFX Gfx::Instance() diff --git a/model.cc b/model.cc index 48820f9..eefc843 100644 --- a/model.cc +++ b/model.cc @@ -1,6 +1,7 @@ #include "model.h" #include #include +#include inline bool isnan(float x) { @@ -9,18 +10,42 @@ inline bool isnan(float x) struct ModelHeader { - char sig[8]; // "laz0rOBJ" + char sig[4]; // "lzrO" + int vtype; int num_vertices; int num_faces; }; +size_t Model::vertex_size() +{ + size_t result=0; + if ((vtype & GU_TEXTURE_BITS) == GU_TEXTURE_8BIT) { printf("GU_TEXTURE_8BIT\n"); result += 2; } + else if ((vtype & GU_TEXTURE_BITS) == GU_TEXTURE_16BIT) { printf("GU_TEXTURE_16BIT\n"); result +=4; } + else if ((vtype & GU_TEXTURE_BITS) == GU_TEXTURE_32BITF) { printf("GU_TEXTURE_32BITF\n"); result += 8; } + + if ((vtype & GU_COLOR_BITS) == GU_COLOR_5650) { printf("GU_COLOR_5650\n"); result += 2; } + else if ((vtype & GU_COLOR_BITS) == GU_COLOR_5551) { printf("GU_COLOR_5551\n"); result += 2; } + else if ((vtype & GU_COLOR_BITS) == GU_COLOR_4444) { printf("GU_COLOR_4444\n"); result += 2; } + else if ((vtype & GU_COLOR_BITS) == GU_COLOR_8888) { printf("GU_COLOR_8888\n"); result += 4; } + + if ((vtype & GU_NORMAL_BITS) == GU_NORMAL_8BIT) { printf("GU_NORMAL_8BIT\n"); result += 3; } + else if ((vtype & GU_NORMAL_BITS) == GU_NORMAL_16BIT) { printf("GU_NORMAL_16BIT\n"); result += 6; } + else if ((vtype & GU_NORMAL_BITS) == GU_NORMAL_32BITF) { printf("GU_NORMAL_32BITF\n"); result += 12; } + + if ((vtype & GU_VERTEX_BITS) == GU_VERTEX_8BIT) { printf("GU_VERTEX_8BIT\n"); result += 3; } + else if ((vtype & GU_VERTEX_BITS) == GU_VERTEX_16BIT) { printf("GU_VERTEX_16BIT\n"); result += 6; } + else if ((vtype & GU_VERTEX_BITS) == GU_VERTEX_32BITF) { printf("GU_VERTEX_32BITF\n"); result += 12; } + + return result; +} + Model::Model(const char *filename) { printf("Reading model %s\n", filename); FILE *f=fopen(filename, "r"); ModelHeader h; fread(&h, sizeof(ModelHeader), 1, f); - if (strncmp(h.sig, "laz0rOBJ", 8)) + if (strncmp(h.sig, "lzrO", 4)) { printf("Error, not a model file.\n"); num_vertices=0; @@ -28,22 +53,17 @@ Model::Model(const char *filename) return; } + vtype = h.vtype; num_vertices = h.num_vertices; num_faces = h.num_faces; - vertices = new Vertex[num_vertices]; + vertices = new unsigned char[num_vertices*vertex_size()]; indices = new unsigned short[num_faces*3]; - fread(vertices, sizeof(Vertex), num_vertices, f); + fread(vertices, vertex_size(), num_vertices, f); fread(indices, sizeof(unsigned short), 3*num_faces, f); fclose(f); - for (int i=0; i - -struct Vertex -{ - float u,v; - u32 color; - float nx,ny,nz; - float x,y,z; -}; +#include struct Model { + int vtype; int num_vertices; int num_faces; - Vertex *vertices; + unsigned char *vertices; unsigned short *indices; + size_t vertex_size(); + Model(const char *filename); ~Model(); }; diff --git a/models/shipdawhip.lob b/models/shipdawhip.lob new file mode 100644 index 0000000000000000000000000000000000000000..49975b041b92113a1d08fb5f6c762ef8e38ca544 GIT binary patch literal 57392 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 D%V`b- literal 0 HcmV?d00001 diff --git a/models/shipdawhip.tga b/models/shipdawhip.tga new file mode 100644 index 0000000000000000000000000000000000000000..491e0a9d995e921201ddd32c0c5dbb18fd9b181e GIT binary patch literal 65554 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 #include +#include +#include Texture::Texture(const char *filename) -{ - FILE *pFile = 0; - +{ + int len = strlen(filename); + if (!strcmp("tga", filename+len-3) || + !strcmp("TGA", filename+len-3)) + { + readTGA(filename); + } + else + { + readLTX(filename); + } +} + +// Returns number of bits per pixel based on texture type +unsigned int Texture::get_bpp() +{ + switch(mode) + { + case GU_PSM_5650: + case GU_PSM_5551: + case GU_PSM_4444: + return 16; + case GU_PSM_8888: + return 32; + default: + printf("Error: Unsupported texture type\n"); + } + return -1; +} + +// LTX == Laz0r TeXture ;) +struct LTXHeader +{ + char sig[4]; // "lzrT" + int mode; + int width; + int height; +}; + +// init the Texture from a LTX file +void Texture::readLTX(const char *filename) +{ + FILE *fp = fopen(filename, "rb"); + if(!fp) + { + printf("Error, couldn't open file\n"); + return; + } + + LTXHeader header; + + fread(&header, sizeof(LTXHeader), 1, fp); + if (strncmp("lzrT", header.sig, 4)) + { + printf("Error: not a LTX file\n"); + return; + } + + mode = header.mode; + width = header.width; + height = header.height; + swizzled = true; + + unsigned int size = width * height * (get_bpp()/8); + pixels = new unsigned char[size]; + + fread(pixels, sizeof(unsigned char), size, fp); + fclose(fp); + + printf("Read LTX texture %s (%ux%ux%u), size=%u\n", filename, width, height, get_bpp(), size); + +} + +// init the Texture from a TGA file +void Texture::readTGA(const char *filename) +{ // Variables to hold image info unsigned char tempColor; - unsigned char bitCount; int colorMode; long tgaSize; unsigned char unCompressHeader[12] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}; @@ -19,20 +93,22 @@ Texture::Texture(const char *filename) swizzled=false; // Open file - pFile = fopen( filename, "rb" ); + FILE *fp = fopen(filename, "rb"); - if( !pFile ) { - // if couldn't open, exit + if(!fp) + { + printf("Error, couldn't open file\n"); return; } // Read in BitmapHeader info into the structure - fread( &tgaHeader, 1, sizeof(tgaHeader), pFile ); + fread(&tgaHeader, sizeof(tgaHeader), 1, fp); // We only want to read uncompressed TGA's. Chech the // header if it is of an uncompressed one. - if( memcmp( unCompressHeader, tgaHeader, sizeof(unCompressHeader)) != 0 ) { - fclose( pFile ); + if(memcmp(unCompressHeader, tgaHeader, sizeof(unCompressHeader)) != 0) + { + fclose(fp); printf("Error, not an uncompressed TGA file\n"); width=0; height=0; @@ -41,32 +117,45 @@ Texture::Texture(const char *filename) } // Read Image info - fread( header, 1, sizeof(header), pFile ); + fread( header, 1, sizeof(header), fp ); // Calculate and save the Width & Height of Image width = header[1] * 256 + header[0]; height = header[3] * 256 + header[2]; - bitCount = header[4]; + unsigned int bpp = header[4]; + + if (bpp != 32) + { + printf("Error: only 32-bit uncompressed TGA is supported"); + return; + } + + mode = GU_PSM_8888; // Calculate color mode & image size - colorMode = bitCount / 8; + colorMode = bpp / 8; tgaSize = width * height * colorMode; printf("width=%hd, height=%hd, tgaSize=%ld\n", width, height, tgaSize); // Allocate memory for the image and load it pixels = new unsigned char[tgaSize]; - fread( pixels, sizeof(unsigned char), tgaSize, pFile ); + fread(pixels, sizeof(unsigned char), tgaSize, fp); // Convert from BGR to RGB format. - for(long index = 0; index < tgaSize; index += colorMode) { + for(long index = 0; index < tgaSize; index += colorMode) + { tempColor = pixels[index]; pixels[index] = pixels[index + 2]; pixels[index + 2] = tempColor; } // Close the file - fclose( pFile ); + fclose(fp); + + swizzle(); + swizzle(); + swizzle(); printf("Read TGA texture %s (%ux%u)\n", filename, width, height); @@ -78,11 +167,108 @@ Texture::~Texture() delete[] pixels; } -void swizzle() +void Texture::bind() { + sceGuTexMode(mode, 0, 0, swizzled? 1: 0); + sceGuTexImage(0, width, height, width, pixels); +} +void Texture::swizzle() +{ + unsigned int bytes_per_pixel = get_bpp()/8; + unsigned int i,j; + unsigned int rowblocks = (width * bytes_per_pixel / 16); + long size = width * height * long(bytes_per_pixel); + + unsigned char* out = new unsigned char[size]; + + for (j = 0; j < height; ++j) + { + for (i = 0; i < width*bytes_per_pixel; ++i) + { + unsigned int blockx = i / 16; + unsigned int blocky = j / 8; + + unsigned int x = (i - blockx*16); + unsigned int y = (j - blocky*8); + unsigned int block_index = blockx + ((blocky) * rowblocks); + unsigned int block_address = block_index * 16 * 8; + + out[block_address + x + y * 16] = pixels[i+j*width*bytes_per_pixel]; + } + } + memcpy(pixels, out, size ); + swizzled = !swizzled; + delete[] out; } +bool Texture::saveLTX(const char *filename, int dst_mode) +{ + // swizzling affects bytes, not pixels, so we unswizzle, convert + // the texture to the new pixel format, swizzle the new texture, + // save it and restore everything. + // + // FIXME: Swizzle != Unswizzle :( + + // Save current parameters + int src_mode = mode; + unsigned char *src_pixels = pixels; + bool src_swizzled = swizzled; + + // Undo swizzling, if any + if (src_swizzled) swizzle(); + if (mode != GU_PSM_8888) + { + printf("Error: Texture::saveLTX only supports GU_PSM_8888 as src mode\n"); + return false; + } + + mode = dst_mode; + printf("new_bpp=%u\n", get_bpp()); + pixels = new unsigned char[width * height * (get_bpp()/8)]; + + // convert pixel format + int dst_index=0; + for (int src_index=0; src_index < width*height*4; src_index+=4) + { + unsigned char r = src_pixels[src_index]; + unsigned char g = src_pixels[src_index+1]; + unsigned char b = src_pixels[src_index+2]; + unsigned char a = src_pixels[src_index+3]; + + switch(dst_mode) + { + case GU_PSM_5650: { + unsigned short val = ((r>>3) << 11) | ((g>>2) << 5) | (b>>3); + ((unsigned short *)pixels)[dst_index] = val; + dst_index++; + break; + } + default: + printf("Texture::saveLTX: Unsupported dst mode\n"); + return false; + } + + } + + // swizzle + swizzle(); + + FILE *fp=fopen(filename, "wb"); + LTXHeader header={{'l','z','r','T'}, dst_mode, width, height}; + fwrite(&header, sizeof(LTXHeader), 1, fp); + fwrite(pixels, width*height*(get_bpp()/8), 1, fp); + fclose(fp); + + delete[] pixels; + + // restore + pixels = src_pixels; + mode = src_mode; + if (src_swizzled) swizzle(); + + return true; +} diff --git a/texture.h b/texture.h index 21ef07c..9bd5f93 100644 --- a/texture.h +++ b/texture.h @@ -1,17 +1,27 @@ #if !defined(TEXTURE_H) #define TEXTURE_H +// NOTE: Only power of 2 textures are supported struct Texture { unsigned short width; unsigned short height; - unsigned char *pixels; + int mode; bool swizzled; + unsigned char *pixels; Texture(const char *filename); ~Texture(); - void swizzle(); + void bind(); + + bool saveLTX(const char *filename, int dst_mode); + + private: + void swizzle(); + unsigned int get_bpp(); + void readTGA(const char *filename); + void readLTX(const char *filename); }; #endif diff --git a/tools/blender_exporter.py b/tools/blender_exporter.py index 7f0bc2d..b5af93d 100644 --- a/tools/blender_exporter.py +++ b/tools/blender_exporter.py @@ -12,6 +12,75 @@ import Blender import bpy import struct +# vertex declarations from pspgu.h +def GU_TEXTURE_SHIFT(n): + return ((n)<<0) + +GU_TEXTURE_8BIT = GU_TEXTURE_SHIFT(1) +GU_TEXTURE_16BIT = GU_TEXTURE_SHIFT(2) +GU_TEXTURE_32BITF = GU_TEXTURE_SHIFT(3) +GU_TEXTURE_BITS = GU_TEXTURE_SHIFT(3) + +def GU_COLOR_SHIFT(n): + return ((n)<<2) + +GU_COLOR_5650 = GU_COLOR_SHIFT(4) +GU_COLOR_5551 = GU_COLOR_SHIFT(5) +GU_COLOR_4444 = GU_COLOR_SHIFT(6) +GU_COLOR_8888 = GU_COLOR_SHIFT(7) +GU_COLOR_BITS = GU_COLOR_SHIFT(7) + +def GU_NORMAL_SHIFT(n): + return ((n)<<5) + +GU_NORMAL_8BIT = GU_NORMAL_SHIFT(1) +GU_NORMAL_16BIT = GU_NORMAL_SHIFT(2) +GU_NORMAL_32BITF = GU_NORMAL_SHIFT(3) +GU_NORMAL_BITS = GU_NORMAL_SHIFT(3) + +def GU_VERTEX_SHIFT(n): + return ((n)<<7) + +GU_VERTEX_8BIT = GU_VERTEX_SHIFT(1) +GU_VERTEX_16BIT = GU_VERTEX_SHIFT(2) +GU_VERTEX_32BITF = GU_VERTEX_SHIFT(3) +GU_VERTEX_BITS = GU_VERTEX_SHIFT(3) + +def GU_WEIGHT_SHIFT(n): + return ((n)<<9) + +GU_WEIGHT_8BIT = GU_WEIGHT_SHIFT(1) +GU_WEIGHT_16BIT = GU_WEIGHT_SHIFT(2) +GU_WEIGHT_32BITF = GU_WEIGHT_SHIFT(3) +GU_WEIGHT_BITS = GU_WEIGHT_SHIFT(3) + +def GU_INDEX_SHIFT(n): + return ((n)<<11) + +GU_INDEX_8BIT = GU_INDEX_SHIFT(1) +GU_INDEX_16BIT = GU_INDEX_SHIFT(2) +GU_INDEX_BITS = GU_INDEX_SHIFT(3) + +def GU_WEIGHTS(n): + return ((((n)-1)&7)<<14) + +GU_WEIGHTS_BITS = GU_WEIGHTS(8) + +def GU_VERTICES(n): + return ((((n)-1)&7)<<18) + +GU_VERTICES_BITS = GU_VERTICES(8) + +def GU_TRANSFORM_SHIFT(n): + return ((n)<<23) + +GU_TRANSFORM_3D = GU_TRANSFORM_SHIFT(0) +GU_TRANSFORM_2D = GU_TRANSFORM_SHIFT(1) +GU_TRANSFORM_BITS = GU_TRANSFORM_SHIFT(1) + + + + def write(filename): vertex_list = [] # index --> {co=(x,y,z), no=(nx,ny,nz), uv=(u,v)} vertex_map = {} # (x,y,z) --> [index, index, ...] @@ -25,6 +94,14 @@ def write(filename): mesh = obj.getData(mesh=1) + # mesh flags + flags = GU_VERTEX_32BITF | GU_NORMAL_32BITF | GU_INDEX_16BIT + if mesh.faceUV: + flags |= GU_TEXTURE_32BITF + + if mesh.vertexColors: + flags |= GU_COLOR_8888 + # add every vertex for vert in mesh.verts: vx,vy,vz = vert.co @@ -92,16 +169,19 @@ def write(filename): # write header f = file(filename, "w") - f.write("laz0rOBJ") - f.write(struct.pack(" +#include +#include + +using namespace std; + +int main(int argc, char **argv) +{ + Texture t(argv[1]); + t.saveLTX(argv[2], GU_PSM_5650); +} + + -- 2.34.1