⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mdl_utils.cpp.svn-base

📁 自己做的小游戏
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/***
*
*	Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
*	This product contains software technology licensed from Id
*	Software, Inc. ("Id Technology").  Id Technology (c) 1996 Id Software, Inc.
*	All Rights Reserved.
*
****/
// updates:
// 1-4-99	fixed file texture load and file read bug
// 2-8-99	fixed demand loaded sequence bug (thanks to Frans 'Otis' Bouma)
// 2008-5   modified by Liu Xinfeng

////////////////////////////////////////////////////////////////////////
#include <stdio.h>

#include <windows.h>

#include <gl\gl.h>
#include <gl\glu.h>

#include "mathlib.h"
#include "mdlformat.h"
#include "mdlmodel.h"

#pragma warning( disable : 4244 ) // double to float
#pragma warning( disable : 4996 )

////////////////////////////////////////////////////////////////////////

static int g_texnum = 1;

//加载额外的纹理,Chaos没用到
void MDLModel::UploadTexture(texture_t *ptexture, byte *data, byte *pal)
{
    // unsigned *in, int inwidth, int inheight, unsigned *out,  int outwidth, int outheight;
    int		i, j;
    int		row1[256], row2[256], col1[256], col2[256];
    byte	*pix1, *pix2, *pix3, *pix4;
    byte	*tex, *out;

    // convert texture to power of 2
    int outwidth;
    for (outwidth = 1; outwidth < ptexture->width; outwidth <<= 1)
        ;

    if (outwidth > 256)
        outwidth = 256;

    int outheight;
    for (outheight = 1; outheight < ptexture->height; outheight <<= 1)
        ;

    if (outheight > 256)
        outheight = 256;

    tex = out = (byte *)malloc( outwidth * outheight * 4);

    for (i = 0; i < outwidth; i++)
    {
        col1[i] = (i + 0.25) * (ptexture->width / (float)outwidth);
        col2[i] = (i + 0.75) * (ptexture->width / (float)outwidth);
    }

    for (i = 0; i < outheight; i++)
    {
        row1[i] = (int)((i + 0.25) * (ptexture->height / (float)outheight)) * ptexture->width;
        row2[i] = (int)((i + 0.75) * (ptexture->height / (float)outheight)) * ptexture->width;
    }

    // scale down and convert to 32bit RGB
    for (i=0 ; i<outheight ; i++)
    {
        for (j=0 ; j<outwidth ; j++, out += 4)
        {
            pix1 = &pal[data[row1[i] + col1[j]] * 3];
            pix2 = &pal[data[row1[i] + col2[j]] * 3];
            pix3 = &pal[data[row2[i] + col1[j]] * 3];
            pix4 = &pal[data[row2[i] + col2[j]] * 3];

            out[0] = (pix1[0] + pix2[0] + pix3[0] + pix4[0])>>2;
            out[1] = (pix1[1] + pix2[1] + pix3[1] + pix4[1])>>2;
            out[2] = (pix1[2] + pix2[2] + pix3[2] + pix4[2])>>2;
            out[3] = 0xFF;
        }
    }

    glBindTexture( GL_TEXTURE_2D, g_texnum );
    glTexImage2D( GL_TEXTURE_2D, 0, 3/*??*/, outwidth, outheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex );
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);


    // ptexture->width = outwidth;
    // ptexture->height = outheight;
    ptexture->index = g_texnum;

    g_texnum++;

    free( tex );
}

/*
读入MDL文件,返回model_header_t指针
*/
model_header_t *MDLModel::LoadModel( char *modelname )
{
    FILE *fp;
    long size;
    void *buffer;

    // load the model
    if ( (fp = fopen( modelname, "rb" )) == NULL)
    {
        printf("unable to open %s\n", modelname );
        exit(1);
    }

    fseek( fp, 0, SEEK_END );
    size = ftell( fp );
    fseek( fp, 0, SEEK_SET );
    buffer = malloc( size );
    fread( buffer, size, 1, fp );

    int					i;
    byte				*pin;
    model_header_t			*phdr;
    texture_t	*ptexture;

    pin = (byte *)buffer;
    phdr = (model_header_t *)pin;

    ptexture = (texture_t *)(pin + phdr->textureindex);
    if (phdr->textureindex != 0)
    {
        for (i = 0; i < phdr->numtextures; i++)
        {
            // strcpy( name, mod->name );
            // strcpy( name, ptexture[i].name );
            UploadTexture( &ptexture[i], pin + ptexture[i].index, pin + ptexture[i].width * ptexture[i].height + ptexture[i].index );
        }
    }

    // UNDONE: free texture memory

    fclose( fp );

    return (model_header_t *)buffer;
}


seq_header_t *MDLModel::LoadDemandSequences( char *modelname )
{
    FILE *fp;
    long size;
    void *buffer;

    // load the model
    if ( (fp = fopen( modelname, "rb" )) == NULL)
    {
        printf("unable to open %s\n", modelname );
        exit(1);
    }

    fseek( fp, 0, SEEK_END );
    size = ftell( fp );
    fseek( fp, 0, SEEK_SET );
    buffer = malloc( size );
    fread( buffer, size, 1, fp );

    fclose( fp );

    return (seq_header_t *)buffer;
}

//初始化对于多文件模型MDL加载纹理和各个动画序列组
void MDLModel::Init( char *modelname )
{
    m_pmodelhdr = LoadModel( modelname );

    // preload textures
    if (m_pmodelhdr->numtextures == 0)
    {
        char texturename[256];

        strcpy( texturename, modelname );
        strcpy( &texturename[strlen(texturename) - 4], "T.mdl" );

        m_ptexturehdr = LoadModel( texturename );
    }
    else
    {
        m_ptexturehdr = m_pmodelhdr;
    }

    // preload animations
    if (m_pmodelhdr->numseqgroups > 1)
    {
        for (int i = 1; i < m_pmodelhdr->numseqgroups; i++)
        {
            char seqgroupname[256];

            strcpy( seqgroupname, modelname );
            sprintf( &seqgroupname[strlen(seqgroupname) - 4], "%02d.mdl", i );

            m_panimhdr[i] = LoadDemandSequences( seqgroupname );
        }
    }
}


////////////////////////////////////////////////////////////////////////
//通过Index得到当前动画序列编号
int MDLModel::GetSequence( )
{
    return m_sequence;
}

/*增加的函数,用于通过sequence的名字来获取序列编号
  主要因为mdlviewer中只能看到sequence的编号,便于设置模型的动画
*/
int MDLModel::GetSequence(char* seqname)
{
    if (this->m_pmodelhdr)
    {
        for (int i=0; i<m_pmodelhdr->numseq; ++i)
        {
            sequence_t *pseqdescs = (sequence_t *) ((byte *) m_pmodelhdr + m_pmodelhdr->seqindex);
            if (strcmp(seqname, pseqdescs[i].label) == 0)
                return i;
        }
    }
    printf("sequence \"%s\" dosen't exist!\n", seqname);
    return -1;	//if not found return -1
}

//增加的函数,打印出模型所有的动画信息,辅助功能
void MDLModel::DumpSequences(void)
{
    if (this->m_pmodelhdr)
    {
        for (int i=0; i<m_pmodelhdr->numseq; ++i)
        {
            sequence_t *pseqdescs = (sequence_t *) ((byte *) m_pmodelhdr + m_pmodelhdr->seqindex);
            printf("%02d\t%s\n", i, pseqdescs[i].label);
        }
    }
}

//设置动画序列,参数为动画序列的编号
int MDLModel::SetSequence( int iSequence )
{
    if (iSequence > m_pmodelhdr->numseq)
        iSequence = 0;
    if (iSequence < 0)
        iSequence = m_pmodelhdr->numseq-1;

    m_sequence = iSequence;
    m_frame = 0;

    return m_sequence;
}

//增加的函数,通过序列名字设置动画
int MDLModel::SetSequence(char *seqname)
{
    int iSequence = GetSequence(seqname);
    if (iSequence)
        SetSequence(iSequence);
    else
        printf("sequence \"%s\" doesn't exit!\n", seqname);
    return iSequence;
}

/*
  增加的函数,通过模型的名字进行模糊匹配,由于动画名字太多各种状态都
  有很多种不同的动画通过模糊匹配来查找有用的动画序列
*/
int MDLModel::FuzzySearchSeq(char *seqname)
{
    if (this->m_pmodelhdr)
    {
        for (int i=0; i<m_pmodelhdr->numseq; ++i)
        {
            sequence_t *pseqdescs = (sequence_t *) ((byte *) m_pmodelhdr + m_pmodelhdr->seqindex);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -