程序员爱装B

写装A程序 做装C的事情

[搬家文] 第九课 动画-part 2

    //Reads the next four bytes as an integer, using little-endian form
    int readInt(ifstream &input) {
        char buffer[4];
        input.read(buffer, 4);
        return toInt(buffer);
    }
    
    //Reads the next two bytes as a short, using little-endian form
    short readShort(ifstream &input) {
        char buffer[2];
        input.read(buffer, 2);
        return toShort(buffer);
    }
    
    //Reads the next two bytes as an unsigned short, using little-endian form
    unsigned short readUShort(ifstream &input) {
        char buffer[2];
        input.read(buffer, 2);
        return toUShort(buffer);
    }
    
    //Reads the next four bytes as a float, using little-endian form
    float readFloat(ifstream &input) {
        char buffer[4];
        input.read(buffer, 4);
        return toFloat(buffer);
    }
    
    //Calls readFloat three times and returns the results as a Vec3f object
    Vec3f readVec3f(ifstream &input) {
        float x = readFloat(input);
        float y = readFloat(input);
        float z = readFloat(input);
        return Vec3f(x, y, z);
    }

    这些函数使得从一个文件中读取int, short, unsigned short, float, Ver3f数据比较的方便。

    //Makes the image into a texture, and returns the id of the texture
    GLuint loadTexture(Image *image) {
        //...
    }
}

    这是我们从纹理渲染那课学过的函数。

MD2Model::~MD2Model() {
    if (frames != NULL) {
        for(int i = 0; i < numFrames; i++) {
            delete[] frames[i].vertices;
        }
        delete[] frames;
    }
    
    if (texCoords != NULL) {
        delete[] texCoords;
    }
    if (triangles != NULL) {
        delete[] triangles;
    }
}

    这是类的析构函数,它释放所有申请的内存,包括顶点,帧,纹理,三角形。

MD2Model::MD2Model() {
    frames = NULL;
    texCoords = NULL;
    triangles = NULL;
    time = 0;
}

    构造函数初始化一些变量,但并没有做多少事情。初始化在load方法中。

//Loads the MD2 model
MD2Model* MD2Model::load(const char* filename) {
    ifstream input;
    input.open(filename, istream::binary);
    
    char buffer[64];
    input.read(buffer, 4); //Should be "IPD2", if this is an MD2 file
    if (buffer[0] != 'I' || buffer[1] != 'D' ||
        buffer[2] != 'P' || buffer[3] != '2') {
        return NULL;
    }
    if (readInt(input) != 8) { //The version number
        return NULL;
    }

    这是加载MD2文件的方法。首先,检验文件前四个字节是否是"IPD2",这是MD2文件标识。然后,检验接下来的4个字节,表示为整型,值为8,这是加载的MD2文件的对应版本数字。

    int textureWidth = readInt(input);   //The width of the textures
    int textureHeight = readInt(input);  //The height of the textures
    readInt(input);                      //The number of bytes per frame
    int numTextures = readInt(input);    //The number of textures
    if (numTextures != 1) {
        return NULL;
    }
    int numVertices = readInt(input);    //The number of vertices
    int numTexCoords = readInt(input);   //The number of texture coordinates
    int numTriangles = readInt(input);   //The number of triangles
    readInt(input);                      //The number of OpenGL commands
    int numFrames = readInt(input);      //The number of frames

    接下来MD2文件格式指明,必须要有包含了动画顺序的一些特定的信息。我们将这些信息保存在变量中。有一些信息我们用不到,就直接丢弃了。

    //Offsets (number of bytes after the beginning of the file to the beginning
    //of where certain data appear)
    int textureOffset = readInt(input);  //The offset to the textures
    int texCoordOffset = readInt(input); //The offset to the texture coordinates
    int triangleOffset = readInt(input); //The offset to the triangles
    int frameOffset = readInt(input);    //The offset to the frames
    readInt(input);                      //The offset to the OpenGL commands
    readInt(input);                      //The offset to the end of the file

     接下来MD2文件需要包含一些指明数据出现的位置的偏移量。

    //Load the texture
    input.seekg(textureOffset, ios_base::beg);
    input.read(buffer, 64);
    if (strlen(buffer) < 5 ||
        strcmp(buffer + strlen(buffer) - 4".bmp") != 0) {
        return NULL;
    }
    Image* image = loadBMP(buffer);
    GLuint textureId = loadTexture(image);
    delete image;
    MD2Model* model = new MD2Model();
    model->textureId = textureId;

    我们找到纹理存放的地方,并把接下来的64个字节作为字符串读入。这个字符串是用于模型的纹理的文件名。我们确保这个纹理是个bitmap,并载入。

posted on 2010-07-19 20:29 camel 阅读(115) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2010年7月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

统计

常用链接

留言簿

随笔档案

文章档案

搜索

最新评论

阅读排行榜

评论排行榜