bool PrepareTriangle(uint32_t dwV0, uint32_t dwV1, uint32_t dwV2)
{
   SP_Timing(SP_Each_Triangle);

   bool textureFlag = (CRender::g_pRender->IsTextureEnabled() || gRSP.ucode == 6 );

   InitVertex(dwV0, gRSP.numVertices, textureFlag);
   InitVertex(dwV1, gRSP.numVertices+1, textureFlag);
   InitVertex(dwV2, gRSP.numVertices+2, textureFlag);

        if(gRSP.numVertices == 0 && g_curRomInfo.bEnableTxtLOD && gRDP.otherMode.text_lod)
        {
            if( CRender::g_pRender->IsTexel1Enable() && CRender::g_pRender->m_pColorCombiner->m_pDecodedMux->IsUsed(MUX_LODFRAC, MUX_MASK) )
            {
                ComputeLOD();
            }
            else
            {
                gRDP.LODFrac = 0;
            }
        }

   gRSP.numVertices += 3;
   status.dwNumTrisRendered++;

   return true;
}
Esempio n. 2
0
void CEngineSurface :: drawTexturedRect( int x0, int y0, int x1, int y1 )
{
	vpoint_t rect[2];
	vpoint_t clippedRect[2];

	InitVertex( rect[0], x0, y0, 0, 0 );
	InitVertex( rect[1], x1, y1, 1, 1 );

	// fully clipped?
	if( !ClipRect( rect[0], rect[1], &clippedRect[0], &clippedRect[1] ))
		return;	

	VGUI_SetupDrawingImage( _drawColor );	
	VGUI_DrawQuad( &clippedRect[0], &clippedRect[1] );
}
Esempio n. 3
0
void CEngineSurface :: drawFilledRect( int x0, int y0, int x1, int y1 )
{
	vpoint_t rect[2];
	vpoint_t clippedRect[2];

	if( _drawColor[3] >= 255 ) return;

	InitVertex( rect[0], x0, y0, 0, 0 );
	InitVertex( rect[1], x1, y1, 0, 0 );

	// fully clipped?
	if( !ClipRect( rect[0], rect[1], &clippedRect[0], &clippedRect[1] ))
		return;	

	VGUI_SetupDrawingRect( _drawColor );	
	VGUI_EnableTexture( false );
	VGUI_DrawQuad( &clippedRect[0], &clippedRect[1] );
	VGUI_EnableTexture( true );
}
/*
================
Model::ImportMD5
================
*/
Model *Model::ImportMD5( const char *filename, const char *filenameAnim ) {
    Lexer lexer(LEXER_NO_BOM_WARNING);
    if ( !lexer.LoadFile( filename ) )
        return NULL;

    Model *model = new Model(true);
    int numJoints = -1;
    try {

        // MD5Version must be the first keyword
        lexer.ExpectToken( "MD5Version" );
        int fileVersion = lexer.ReadInt();
        if ( fileVersion != MD5_VERSION_DOOM3 && fileVersion != MD5_VERSION_QUAKEWARS )
            lexer.Error( Format( "MD5Version is $*, should be $* or $*") << fileVersion << MD5_VERSION_DOOM3 << MD5_VERSION_QUAKEWARS );

        const Token *token;
        String key;

        const char *p;

        bool inJointGroup = false;
        bool inMeshGroup = false;
        bool readMeshVerts = false;
        bool readMeshTris = false;

        int numMeshes = -1;
        int numVerts, vertIndex;
        int triCounter, indexCounter;
        int numWeights;
        MeshAnimated *mesh = NULL;

        int i, j, num;
        Vec3 vTemp;

        bool noAnimate = false;
        bool readVertexColor = false;
        Color vertexColor;

        ListEx<MD5Vertex> vertexList;
        ListEx<MD5Weight> weightList;

        while ( (token = lexer.ReadToken()) != NULL ) {
            p = token->GetString();
            if ( !p || !*p )
                continue;

            if ( inJointGroup ) {
                if ( *p == '}' ) {
                    inJointGroup = false;
                    continue;
                }
                lexer.ReadInt(); // unused
                ParseVector( lexer, &vTemp.x, 3 );
                ParseVector( lexer, &vTemp.x, 3 );
            } else if ( inMeshGroup ) {
                lexer.UnreadToken();
                if ( readMeshVerts ) {
                    if ( lexer.CheckToken( "numtris" ) ) {
                        if ( numVerts != vertexList.Num() )
                            lexer.Error( Format("numVerts don't match: $*") << vertexList.Num() );
                        InitIndices( mesh, lexer.ReadInt() * 3 ); // numtris * 3
                        triCounter = 0;
                        indexCounter = 0;
                        readMeshVerts = false;
                        readMeshTris = true;
                        continue;
                    }
                    lexer.ExpectToken( "vert" );

                    vertIndex = lexer.ReadInt();
                    if ( vertIndex != vertexList.Num() )
                        lexer.Error( Format("Bad Vert Index, should be $*") << vertexList.Num() );

                    MD5Vertex &vertex = vertexList.Alloc();
                    ParseVector( lexer, &vertex.texCoord.x, 2 );
                    vertex.firstWeight = lexer.ReadInt();
                    vertex.lastWeight = lexer.ReadInt() + vertex.firstWeight - 1;

                    if ( readVertexColor ) {
                        // Currently we don't have use for vertex color..
                        // I haven't seen md5meshes with other values than ( 1 1 1 1 ) for vertexColor anyway..
                        ParseVector( lexer, &vertexColor.r, 4 );
                    }
                } else if ( readMeshTris ) {
                    if ( lexer.CheckToken( "numweights" ) ) {
                        numWeights = lexer.ReadInt();
                        weightList.CheckSize( numWeights );
                        readMeshTris = false;
                        continue;
                    }
                    lexer.ExpectToken( "tri" );

                    if ( lexer.ReadInt() != triCounter )
                        lexer.Error( Format("Bad Tri Index, should be $*") << triCounter );

                    mesh->indices[indexCounter++] = lexer.ReadInt();
                    mesh->indices[indexCounter++] = lexer.ReadInt();
                    mesh->indices[indexCounter++] = lexer.ReadInt();
                    triCounter++;
                } else {
                    if ( lexer.CheckToken( "}" ) ) {
                        if ( numWeights != weightList.Num() )
                            lexer.Error( Format("numWeights doesn't match $*") << weightList.Num() );

                        // Convert vertices:
                        num = vertexList.Num();
                        for( i=0; i<num; i++ ) {
                            if ( i >= vertexList.Num() )
                                lexer.Error( "Vertex index out of range" );

                            const MD5Vertex &md5Vert = vertexList[i];

                            mesh->texCoords[i] = md5Vert.texCoord;

                            Vertex &vInfo = mesh->vertices[i];
                            InitVertex( &vInfo, 1 + md5Vert.lastWeight - md5Vert.firstWeight );
                            vInfo.numWeights = 0;

                            for ( j=md5Vert.firstWeight; j<=md5Vert.lastWeight; j++ ) {
                                if ( j >= weightList.Num() )
                                    lexer.Error( "Weight index out of range" );
                                const MD5Weight &md5Weight = weightList[j];

                                if ( md5Weight.jointIndex >= numJoints )
                                    lexer.Error( "Weight joint index out of range" );

                                if ( md5Weight.bias == 0.0f )
                                    continue;

                                VertexWeight &weight = vInfo.weights[vInfo.numWeights++];
                                weight.boneId = md5Weight.jointIndex;
                                weight.origin = md5Weight.origin;
                                //weight.normal = md5Weight.normal; //! @todo	calculate normal
                                weight.influence = md5Weight.bias;
                            }
                        }
                        inMeshGroup = false;
                        continue;
                    }
                    lexer.ExpectToken( "weight" );

                    if ( lexer.ReadInt() != weightList.Num() )
                        lexer.Error( Format("Bad VertexWeight Index, should be $*") << weightList.Num() );

                    MD5Weight &weight = weightList.Alloc();
                    weight.jointIndex = lexer.ReadInt();
                    weight.bias = lexer.ReadFloat();
                    ParseVector( lexer, &weight.origin.x, 3 );
                    weight.origin *= MD5_MODEL_SCALE;
                }
            } else {
                if ( String::Icmp( p, "commandline" ) == 0 ) {
                    // Skip value, we don't need it
                    lexer.ReadToken();
                } else if ( String::Icmp( p, "numJoints" ) == 0 ) {
                    numJoints = lexer.ReadInt();
                    if ( numJoints > 0 ) {
                        model->bones.SetGranularity( numJoints );
                        model->bones.CheckSize( numJoints );
                    }
                } else if ( String::Icmp( p, "numMeshes" ) == 0 ) {
                    numMeshes = lexer.ReadInt();
                    if ( numMeshes <= 0 )
                        lexer.Error("Zero meshes");
                    model->meshes.SetGranularity( numMeshes );
                    model->meshes.CheckSize( numMeshes );
                } else if ( String::Icmp( p, "joints" ) == 0 ) {
                    if ( numJoints == -1 )
                        lexer.Error( "numJoins not set!" );

                    lexer.ExpectToken( "{" );
                    inJointGroup = true;
                } else if ( String::Icmp( p, "mesh" ) == 0 ) {
                    if ( numMeshes == -1 )
                        lexer.Error( "numMeshes not set!" );

                    lexer.ExpectToken( "{" );

                    mesh = new MeshAnimated;
                    model->meshes.Append(mesh);

                    if ( fileVersion != MD5_VERSION_QUAKEWARS )
                        mesh->name = Format("mesh $*") << model->meshes.Num();
                    else {
                        lexer.ExpectToken( "name" );
                        mesh->name = lexer.ReadString();
                    }

                    lexer.ExpectToken( "shader" );
                    mesh->material = lexer.ReadString();

                    noAnimate = false;
                    readVertexColor = false;
                    if ( fileVersion == MD5_VERSION_QUAKEWARS ) {
                        lexer.ExpectToken( "flags" );
                        lexer.ExpectToken( "{" );
                        while( !lexer.CheckToken("}") ) {
                            if ( lexer.CheckToken("noAnimate") )
                                noAnimate = true;
                            else if ( lexer.CheckToken("vertexColor") )
                                readVertexColor = true;
                            else
                                lexer.Error( Format("Unknown flag: '$*'") << lexer.ReadString() );
                        }
                    }
                    lexer.ExpectToken( "numverts" );

                    numVerts = lexer.ReadInt();

                    vertexList.Clear();
                    vertexList.CheckSize( numVerts );
                    weightList.Clear();
                    InitVertices( mesh, numVerts );
                    inMeshGroup = true;
                    readMeshVerts = true;
                } else {
                    lexer.Error( Format("Unexpected '$*'") << p );
                }
            }
        }
        if ( inJointGroup || inMeshGroup || numJoints == -1 || numMeshes == -1 )
            throw LexerError( LexerError::END_OF_FILE );
    }
    catch( LexerError err ) {
        delete model;
        String errStr;
        err.ToString( errStr );
        User::Error( ERR_LEXER_FAILURE, errStr.c_str(), filename );
        return NULL;
    }

    if ( !ImportMD5AnimBaseFrame( filenameAnim, model ) )
        return NULL;

    if ( numJoints != model->bones.Num() ) {
        delete model;
        User::Error( ERR_FILE_CORRUPT, "Number of Joints do not match", filename );
        return NULL;
    }
    return model;
}
/*
================
Model::ImportSKM
================
*/
Model *Model::ImportSKM( const char *filename, const char *filenameAnim ) {
	if ( modelFS == NULL )
		return NULL;

	File *file = modelFS->OpenRead( filename );
	if( !file )
		return NULL;

	Model *model = new Model(true);

	// Bones are all stored in skp files!
	if ( !ReadBonesFromSKP( filenameAnim, model ) )
		return NULL;

	try {
		// Read header
		char header_id[4];
		file->Read( header_id, 4 );
		if ( String::Icmpn( header_id, SKMHEADER, String::Length(SKMHEADER) ) != 0 )
			throw FileReadWriteError( "Not a skm file" );
		uInt type = file->ReadUint();
		uInt filesize = file->ReadUint();
		uInt numbones = file->ReadUint();
		uInt nummeshes = file->ReadUint();
		uInt ofs_meshes = file->ReadUint();

		if( type != SKM_MODELTYPE )
			throw FileReadWriteError( Format("File has wrong type number ($* should be $*)" ) << type << SKM_MODELTYPE );
		if( filesize > SKM_MAX_FILESIZE )
			throw FileReadWriteError( Format("File has has wrong filesize ($* should be less than $*)" ) << filesize << SKM_MAX_FILESIZE );

		if( nummeshes <= 0 )
			throw FileReadWriteError("File has no meshes");
		else if( nummeshes > SKM_MAX_MESHES )
			throw FileReadWriteError("File has too many meshes");

		if( numbones <= 0 )
			throw FileReadWriteError("File has no bones");
		else if( numbones > SKM_MAX_BONES )
			throw FileReadWriteError("File has too many bones");

		file->Seek( ofs_meshes, SEEK_SET );

		if ( numbones != model->bones.Num() )
			throw FileReadWriteError( Format("NumBones do not match : (SKP: $*, SKM: $*)\n" ) << model->bones.Num() << numbones );

		mskmesh_t skm_mesh;
		uInt ofs_verts, ofs_texcoords, ofs_indices, ofs_references;

		long lastPos;
		for( int i=0; i<nummeshes; i++ ) {
			// Read Mesh Header
			file->Read( skm_mesh.shadername, SKM_MAX_NAME);
			file->Read( skm_mesh.name, SKM_MAX_NAME);
			skm_mesh.numverts = file->ReadUint();
			skm_mesh.numtris = file->ReadUint();
			skm_mesh.numreferences = file->ReadUint();
			ofs_verts = file->ReadUint();	
			ofs_texcoords = file->ReadUint();
			ofs_indices = file->ReadUint();
			ofs_references = file->ReadUint();

			lastPos = file->Tell();

			// Print out some warnings
			if( skm_mesh.numverts <= 0 )
				throw FileReadWriteError( Format("mesh $* has no vertexes" ) << i );
			else if( skm_mesh.numverts > SKM_MAX_VERTS )
				throw FileReadWriteError( Format("mesh $* has too many vertexes" ) << i );

			if( skm_mesh.numtris <= 0 )
				throw FileReadWriteError( Format("mesh $* has no indices" ) << i );
			else if( skm_mesh.numtris > SKM_MAX_TRIS )
				throw FileReadWriteError( Format("mesh $* has too many indices" ) << i );

			if( skm_mesh.numreferences <= 0 )
				throw FileReadWriteError( Format("mesh $* has no bone references" ) << i );
			else if( skm_mesh.numreferences > SKM_MAX_BONES )
				throw FileReadWriteError( Format("mesh $* has too many bone references" ) << i );

			// Read Vertex Information
			file->Seek( ofs_verts, SEEK_SET );

			MeshAnimated *mesh = new MeshAnimated;
			model->meshes.Append(mesh);
			mesh->name = skm_mesh.name;
			mesh->material = skm_mesh.shadername;
			InitVertices( mesh, skm_mesh.numverts );
			for( int j = 0; j < skm_mesh.numverts; j++ ) {
				Vertex &vInfo = mesh->vertices[j];
				InitVertex( &vInfo, file->ReadUint() );

				for( int l = 0; l < vInfo.numWeights; l++ ) {
					VertexWeight &weight = vInfo.weights[l];
					file->ReadFloatArray( &weight.origin.x, 3 );
					weight.influence = file->ReadFloat();
					file->ReadFloatArray( &weight.normal.x, 3 );
					weight.boneId = file->ReadInt();
					weight.origin *= SKM_MODEL_SCALE;
				}
			}

			file->Seek( ofs_texcoords, SEEK_SET );

			file->ReadFloatArray( &mesh->texCoords[0].x, 2 * skm_mesh.numverts );

			file->Seek( ofs_indices, SEEK_SET );

			int num = skm_mesh.numtris * 3;
			InitIndices( mesh, num );
			file->ReadIntArray( mesh->indices, num );

			file->Seek( lastPos, SEEK_SET );
		}

		file->Close();
		return model;
	}
	catch( FileReadWriteError &err ) {
		file->Close();
		delete model;
		User::Error( ERR_FILE_CORRUPT, Format("SKM: $*" ) << err.ToString(), filename );
		return NULL;
	}
}
Esempio n. 6
0
//==================================
//  函数:InitD3D( HWND )
//  目的:初始化Direct3D设备对象
//
bool InitD3D()
{
	//创建Direct3D对象    [用于获取硬件信息]
	g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
	if(g_pD3D==NULL) return false;

	//检查是否支持硬件顶点处理
	D3DCAPS9 caps;
	g_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&caps);
	int vp=0;
	if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
		vp=D3DCREATE_HARDWARE_VERTEXPROCESSING;  //硬件处理
	else
		vp=D3DCREATE_SOFTWARE_VERTEXPROCESSING;  //软件处理

	//检查硬件支持的shader的版本
/*	if(caps.VertexShaderVersion < D3DVS_VERSION(2,0))
		deviceType = D3DDEVTYPE_REF;
	else
		deviceType = D3DDEVTYPE_HAL;*/

	//设置D3DPRESENT_PARAMETERS结构
	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp,sizeof(d3dpp));
	d3dpp.Windowed = TRUE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
//	d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;  //实时模式,默认是根据屏幕刷新频率

	//创建Direct3D设备对象     [用于渲染图形]
	if( FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,vp,&d3dpp,&g_pd3dD)) )
		return false;

	//设置观察和投影矩阵
	setupViewAndProjMat();

	//设置线性过滤
	g_pd3dD->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
	g_pd3dD->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
	g_pd3dD->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
	g_pd3dD->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);

	//设置纹理寻址模式
	g_pd3dD->SetSamplerState(0, D3DSAMP_BORDERCOLOR, 0x00000000);
	g_pd3dD->SetSamplerState(0, D3DSAMP_ADDRESSU,    D3DTADDRESS_BORDER);
	g_pd3dD->SetSamplerState(0, D3DSAMP_ADDRESSV,    D3DTADDRESS_BORDER);
	g_pd3dD->SetSamplerState(1, D3DSAMP_BORDERCOLOR, 0x00000000);
	g_pd3dD->SetSamplerState(1, D3DSAMP_ADDRESSU,    D3DTADDRESS_BORDER);
	g_pd3dD->SetSamplerState(1, D3DSAMP_ADDRESSV,    D3DTADDRESS_BORDER);
	g_pd3dD->SetSamplerState(2, D3DSAMP_BORDERCOLOR, 0x00000000);
	g_pd3dD->SetSamplerState(2, D3DSAMP_ADDRESSU,    D3DTADDRESS_BORDER);
	g_pd3dD->SetSamplerState(2, D3DSAMP_ADDRESSV,    D3DTADDRESS_BORDER);

	//正反面都绘制
	g_pd3dD->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
    //关闭光照
	g_pd3dD->SetRenderState( D3DRS_LIGHTING, FALSE );

	//激活alpha混合
	g_pd3dD->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	g_pd3dD->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
	g_pd3dD->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	g_pd3dD->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);


	InitVertex();      //初始化顶点缓存,用于装载贴图

	return true;
}