Esempio n. 1
0
// ******************************************************************
// Laden aus echten Dateien
tbResult tbFont::Init(char* pcTGAFile,
					  char* pcTBFFile)
{
	tbVFile* pTGAFile;
	tbVFile* pTBFFile;


	// Parameter prüfen
	if(pcTGAFile == NULL) TB_ERROR_NULL_POINTER("pcTGAFile", TB_ERROR);
	if(pcTBFFile == NULL) TB_ERROR_NULL_POINTER("pcTBFFile", TB_ERROR);


	// Virtuelle Dateien erstellen
	pTGAFile = new tbVFile;	if(pTGAFile == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);
	pTBFFile = new tbVFile;	if(pTBFFile == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

	// Aus Datei laden
	if(pTGAFile->Init(pcTGAFile)) TB_ERROR("Fehler beim Erstellen der virtuellen Datei!", TB_ERROR);
	if(pTBFFile->Init(pcTBFFile)) TB_ERROR("Fehler beim Erstellen der virtuellen Datei!", TB_ERROR);

	// Die andere Methode aufrufen
	if(Init(pTGAFile, pTBFFile))
	{
		// Fehler!
		TB_ERROR("Fehler beim Laden der Schriftart!", TB_ERROR);
	}

	// Die virtuellen Dateien wieder freigeben
	TB_SAFE_DELETE(pTGAFile);
	TB_SAFE_DELETE(pTBFFile);

	return TB_OK;
}
Esempio n. 2
0
// ******************************************************************
// Initialisierung aus einer echten Datei
tbResult tbSound::Init(char* pcFilename,
					   DWORD dwFlags,			// = DSBCAPS_STATIC | DSBCAPS_LOCDEFER
					   GUID GUID3DAlgorithm,	// = GUID_NULL
					   DWORD dwNumBuffers)		// = 4
{
	tbVFile* pVFile;

	// Parameter prüfen
	if(pcFilename == NULL) TB_ERROR_NULL_POINTER("pcFilename", TB_ERROR);


	// Virtuelle Datei erstellen
	pVFile = new tbVFile;
	if(pVFile == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

	// Aus Datei laden
	if(pVFile->Init(pcFilename))
	{
		// Fehler!
		TB_ERROR("Fehler beim Erstellen der virtuellen Datei!", TB_ERROR);
	}

	// Die andere Methode aufrufen
	if(Init(pVFile, dwFlags, GUID3DAlgorithm, dwNumBuffers))
	{
		// Fehler!
		TB_ERROR("Fehler beim Erstellen des Sounds!", TB_ERROR);
	}

	// Die virtuelle Datei wieder freigeben
	TB_SAFE_DELETE(pVFile);

	return TB_OK;
}
Esempio n. 3
0
bool 
Server::cache_set(const string &key,const char *value,size_t valuelen)
{
    if(m_memcached_conn.number_of_hosts == 0){
        return false;
    }
    /*
    vector<char> vv;
    for(size_t i=0;i<valuelen;i++){
        vv.push_back(value[i]);
    }
    */
    pthread_mutex_lock(&m_cache_lock);
    string cachekey = cache_hash(key);
    memcached_return_t rc= memcached_set(&m_memcached_conn,
                                       cachekey.c_str(), cachekey.size(),
                                       value, valuelen,
                                       86400, 0); 
    pthread_mutex_unlock(&m_cache_lock);
    if(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED){
        TB_INFO("cache set ok: key="<<cachekey);
        return true;
    }else{
        TB_ERROR("cache set failed: error="<<memcached_strerror(NULL, rc)<<",key="<<cachekey<<", valuelen="<<valuelen);
        return false;    
    }
}
Esempio n. 4
0
// ******************************************************************
// Rendert die Sky-Box
tbResult tbSkyBox::Render(const tbVector3& vCameraPos)
{
	HRESULT hResult;

	// Weltmatrix erstellen, welche die Sky-Box auf die Position der Kamera bringt
	tbDirect3D::SetTransform(D3DTS_WORLD, tbMatrixTranslation(vCameraPos));

	// Vertex- und Index-Buffer als Datenquelle angeben und Vertexformat setzen
	tbDirect3D::GetDevice()->SetStreamSource(0, m_pVB->GetVB(), 0, sizeof(tbSkyBoxVertex));
	tbDirect3D::GetDevice()->SetIndices(m_pIB->GetIB());
	tbDirect3D::SetFVF(TB_SKYBOX_FVF);

	// Effekt starten
	int iNumPasses = m_pEffect->Begin();

	for(int iPass = 0; iPass < iNumPasses; iPass++)
	{
		m_pEffect->BeginPass(iPass);
	
		// Primitiven rendern
		hResult = tbDirect3D::GetDevice()->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);
		if(FAILED(hResult))
		{
			// Fehler!
			m_pEffect->End();
			TB_ERROR("Fehler beim Rendern der Sky-Box!", TB_ERROR);
		}
		m_pEffect->EndPass();
	}

	// Effekt beenden
	m_pEffect->End();

	return TB_OK;
}
Esempio n. 5
0
// ******************************************************************
// Aus Ressource initialisieren
tbResult tbOctree::Init(HMODULE hModule,
                        char* pcResourceName,
                        char* pcResourceType,
                        char* pcTexturePrefix,		// = ""
                        char* pcTexturePostfix,		// = ""
                        D3DPOOL VBPool,				// = D3DPOOL_DEFAULT
                        DWORD dwVBUsage,			// = D3DUSAGE_WRITEONLY
                        D3DPOOL IBPool,				// = D3DPOOL_DEFAULT
                        DWORD dwIBUsage,			// = D3DUSAGE_WRITEONLY
                        BOOL bGenerateExtraData)	// = TRUE
{
    tbVFile* pVFile;

    // Parameter prüfen
    if(hModule == NULL)			TB_ERROR_NULL_POINTER("hModule", TB_ERROR);
    if(pcResourceName == NULL)	TB_ERROR_NULL_POINTER("pcResourceName", TB_ERROR);
    if(pcResourceType == NULL)	TB_ERROR_NULL_POINTER("pcResourceType", TB_ERROR);


    // Virtuelle Datei erstellen
    pVFile = new tbVFile;
    if(pVFile == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

    // Aus Ressource laden
    if(pVFile->Init(hModule, pcResourceName, pcResourceType))
    {
        // Fehler!
        TB_ERROR("Fehler beim Erstellen der virtuellen Datei!", TB_ERROR);
    }

    // Die andere Methode aufrufen
    if(Init(pVFile, pcTexturePrefix, pcTexturePostfix, VBPool, dwVBUsage, IBPool, dwIBUsage,
            bGenerateExtraData))
    {
        // Fehler!
        TB_SAFE_DELETE(pVFile);
        TB_ERROR("Fehler beim Erstellen des Octrees!", TB_ERROR);
    }

    // Die virtuelle Datei wieder freigeben
    TB_SAFE_DELETE(pVFile);

    return TB_OK;
}
Esempio n. 6
0
// ******************************************************************
// Setzt die Position eines Sounds und berechnet die Geschwindigkeit
tbResult tbSound::SetPosition(const DWORD dwBuffer,
							  const tbVector3& vPosition,
							  const float fSpeedFactor)	// = 1.0f
{
	// Parameter prüfen
	if(dwBuffer >= m_dwNumBuffers) TB_ERROR_INVALID_VALUE("dwBuffer", TB_ERROR);

	// Prüfen, ob es überhaupt ein 3D-Sound ist
	if(!(m_dwFlags & DSBCAPS_CTRL3D)) TB_ERROR("Dies ist kein 3D-Sound!", TB_ERROR);
	LPDIRECTSOUND3DBUFFER pSoundBuffer(m_pp3DSoundBuffers[dwBuffer]);


	// Position setzen
	pSoundBuffer->SetPosition(vPosition.x, vPosition.y, vPosition.z, DS3D_DEFERRED);

	// Den Geschwindigkeitsvektor berechnen.
	// m_pllTimeStamps[dwBuffer] enthält den Zeitpunkt, zu dem SetListener das letzte
	// Mal aufgerufen wurde. Ist m_bJustStarted TRUE, dann ist das hier das erste Mal
	// und die Geschwindigkeit wird auf null gesetzt.
	if(m_bJustStarted)
	{
		pSoundBuffer->SetVelocity(m_pvStartVelocities[dwBuffer].x,
			                      m_pvStartVelocities[dwBuffer].y,
								  m_pvStartVelocities[dwBuffer].z,
								  DS3D_DEFERRED);

		// Aktuelle Zeit und aktuelle Position als ehemalige eintragen
		QueryPerformanceCounter((LARGE_INTEGER*)(&m_pllTimeStamps[dwBuffer]));
		m_pvOldPositions[dwBuffer] = vPosition;

		m_bJustStarted = FALSE;
	}
	else
	{
		LONGLONG llCurrentTime;

		// Differenz zwischen aktueller und alter Zeit berechnen
		QueryPerformanceCounter((LARGE_INTEGER*)(&llCurrentTime));
		double dNumSecsPassed = (double)(llCurrentTime - m_pllTimeStamps[dwBuffer]) / tb_g_dFrequency;

		// Wenn diese Zeit nur knapp von der Zeit seit dem letzten Frame abweicht,
		// wird dies als kleiner Fehler gewertet und die tatsächliche Zeit wird benutzt.
		if(fabs(dNumSecsPassed - tb_g_dNumSecsPassed) < 0.1) dNumSecsPassed = tb_g_dNumSecsPassed;

		// Zurückgelegte Strecke durch die Zeit teilen. Dadurch erhalten
		// wir die Geschwindigkeit.
		tbVector3 vVelocity(((vPosition - m_pvOldPositions[dwBuffer]) / (float)(dNumSecsPassed)) * fSpeedFactor);
		pSoundBuffer->SetVelocity(vVelocity.x, vVelocity.y, vVelocity.z, DS3D_DEFERRED);

		// Aktuelle Zeit und aktuelle Position als ehemalige eintragen
		m_pllTimeStamps[dwBuffer] = llCurrentTime;
		m_pvOldPositions[dwBuffer] = vPosition;
	}

	return TB_OK;
}
Esempio n. 7
0
// ******************************************************************
// Aus Speicherbereich initialisieren
tbResult tbOctree::Init(void* pMemory,
                        int iMemorySize,
                        char* pcTexturePrefix,		// = ""
                        char* pcTexturePostfix,		// = ""
                        D3DPOOL VBPool,				// = D3DPOOL_DEFAULT
                        DWORD dwVBUsage,			// = D3DUSAGE_WRITEONLY
                        D3DPOOL IBPool,				// = D3DPOOL_DEFAULT
                        DWORD dwIBUsage,			// = D3DUSAGE_WRITEONLY
                        BOOL bGenerateExtraData)	// = TRUE
{
    tbVFile* pVFile;

    // Parameter prüfen
    if(pMemory == NULL)		TB_ERROR_NULL_POINTER("pMemory", TB_ERROR);
    if(iMemorySize <= 0)	TB_ERROR_INVALID_VALUE("iMemorySize", TB_ERROR);


    // Virtuelle Datei erstellen
    pVFile = new tbVFile;
    if(pVFile == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

    // Aus Speicher laden
    if(pVFile->Init(pMemory, iMemorySize))
    {
        // Fehler!
        TB_ERROR("Fehler beim Erstellen der virtuellen Datei!", TB_ERROR);
    }

    // Die andere Methode aufrufen
    if(Init(pVFile, pcTexturePrefix, pcTexturePostfix, VBPool, dwVBUsage, IBPool, dwIBUsage,
            bGenerateExtraData))
    {
        // Fehler!
        TB_SAFE_DELETE(pVFile);
        TB_ERROR("Fehler beim Erstellen des Octrees!", TB_ERROR);
    }

    // Die virtuelle Datei wieder freigeben
    TB_SAFE_DELETE(pVFile);

    return TB_OK;
}
Esempio n. 8
0
// ******************************************************************
// Laden aus dem Speicher
tbResult tbFont::Init(void* pTGAFileMem,
					  int iTGAFileMemSize,
					  void* pTBFFileMem,
					  int iTBFFileMemSize)
{
	tbVFile* pTGAFile;
	tbVFile* pTBFFile;


	// Parameter prüfen
	if(pTGAFileMem == NULL)		TB_ERROR_NULL_POINTER("pTGAFileMem", TB_ERROR);
	if(iTGAFileMemSize <= 0)	TB_ERROR_INVALID_VALUE("iTGAFileMemSize", TB_ERROR);
	if(pTBFFileMem == NULL)		TB_ERROR_NULL_POINTER("pTBFFileMem", TB_ERROR);
	if(iTBFFileMemSize <= 0)	TB_ERROR_INVALID_VALUE("iTBFFileMemSize", TB_ERROR);


	// Virtuelle Dateien erstellen
	pTGAFile = new tbVFile; if(pTGAFile == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);
	if(pTGAFile->Init(pTGAFileMem, iTGAFileMemSize)) TB_ERROR("Fehler beim Erstellen der virtuellen TGA-Datei!", TB_ERROR);
	pTBFFile = new tbVFile; if(pTBFFile == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);
	if(pTBFFile->Init(pTBFFileMem, iTBFFileMemSize)) TB_ERROR("Fehler beim Erstellen der virtuellen TBF-Datei!", TB_ERROR);

	// Die andere Methode aufrufen
	if(Init(pTGAFile, pTBFFile))
	{
		// Fehler!
		TB_SAFE_DELETE(pTGAFile);
		TB_SAFE_DELETE(pTBFFile);
		TB_ERROR("Fehler beim Laden der Schriftart!", TB_ERROR);
	}

	// Die virtuellen Dateien freigeben
	TB_SAFE_DELETE(pTGAFile);
	TB_SAFE_DELETE(pTBFFile);

	return TB_OK;
}
Esempio n. 9
0
// ******************************************************************
// Setzt minimale und maximale Entfernung
tbResult tbSound::SetDistances(float fMinDistance,
							   float fMaxDistance)
{
	// Ist es überhaupt ein 3D-Sound?
	if(!(m_dwFlags & DSBCAPS_CTRL3D)) TB_ERROR("Dies ist kein 3D-Sound!", TB_ERROR);

	// Distanzen für alle 3D-Soundpuffer setzen
	for(DWORD dwBuffer = 0; dwBuffer < m_dwNumBuffers; dwBuffer++)
	{
		// Distanzen setzen
		m_pp3DSoundBuffers[dwBuffer]->SetMinDistance(fMinDistance, DS3D_IMMEDIATE);
		m_pp3DSoundBuffers[dwBuffer]->SetMaxDistance(fMaxDistance, DS3D_IMMEDIATE);
	}

	return TB_OK;
}
Esempio n. 10
0
bool
Server::init()
{
    if(m_server_type == SERVER_TYPE_USER){
        m_com_contacts = new CompanyContactsKeeper(m_mongodb_addr,m_company_list_filename);
        if(m_com_contacts->init()==false){
            return false;
        }
    }
    if(m_server_type == SERVER_TYPE_JOB){
        m_com_score = new CompanyScoreKeeper(m_company_score_filename);
        if(m_com_score->init()==false){
            return false;
        }
    }
    m_tag_scorer = new TagScorer(1.0);
    memcached_create(&m_memcached_conn);
    memcached_behavior_set(&m_memcached_conn,MEMCACHED_BEHAVIOR_BINARY_PROTOCOL,1);
    //memcached_behavior_set(&m_memcached_conn, MEMCACHED_BEHAVIOR_USE_UDP,1);
    if(m_memcache_addr!=""){
        memcached_server_st *servers;
        servers= memcached_servers_parse(m_memcache_addr.c_str());
        memcached_return_t rc = memcached_server_push(&m_memcached_conn, servers);
        memcached_server_free(servers);
        if(rc!=MEMCACHED_SUCCESS){
            TB_ERROR("connect to memcached failed, error="<<memcached_strerror(NULL, rc));
            return false;
        }else{
            TB_INFO("connected to memcached on "<<m_memcache_addr);
        }
    }
    pthread_mutex_init(&m_cache_lock,0);
    pthread_mutex_init(&m_db_lock,0);
    pthread_cond_init(&m_db_cond,0);
    for(size_t i=0;i<db_pool_size;i++){
        m_dbs.push_back(new Xapian::Database(m_index_dir));
        m_dbs_busy.push_back(false);
        m_dbs_last_reload_ts.push_back(time(0));
    }
    TB_INFO("database doccount: "<<m_dbs[0]->get_doccount());
    Session* new_session = create_session();
    new_session->init();
    acceptor_.async_accept(new_session->socket(),
		boost::bind(&Server::handle_accept, this, new_session,
		boost::asio::placeholders::error));
   return true; 
}
Esempio n. 11
0
bool
Server::cache_get(const string &key,string &value)
{
    if(m_memcached_conn.number_of_hosts == 0){
        return false;
    }
    pthread_mutex_lock(&m_cache_lock);
    size_t valuelen = 0; 
    memcached_return_t rc;
    uint32_t flags= 0;
    string cachekey = cache_hash(key);
    char *val = memcached_get(&m_memcached_conn, cachekey.c_str(), cachekey.size(),
                               &valuelen, &flags, &rc);    
    pthread_mutex_unlock(&m_cache_lock);
    if(val != NULL){
        value = string(val,valuelen);    
        free(val);
        return true;
    }else{
        TB_ERROR("cache get failed: error="<<memcached_strerror(NULL, rc)<<",key="<<cachekey);
        return false;
    }
}
Esempio n. 12
0
// ******************************************************************
// Liest einen Knoten rekursiv
tbResult tbOctree::ReadNode(tbOctreeNode* pNode,
                            tbOctreeTreeChunkHeader* pTreeCH,
                            tbVFile* pVFile)
{
    tbOctreeNodeHeader	NodeHeader;
    BYTE*				pData;


    // Knoten-Header lesen
    if(pVFile->Read(sizeof(tbOctreeNodeHeader), &NodeHeader))
    {
        // Fehler!
        TB_ERROR("Fehler beim Lesen eines Knoten-Headers!", TB_ERROR);
    }

    m_dwNumNodes++;

    // Daten kopieren
    pNode->bIsLeaf			= NodeHeader.bIsLeaf;
    pNode->dwStartIndex		= NodeHeader.dwStartIndex;
    pNode->dwNumIndices		= NodeHeader.dwNumIndices;
    pNode->vBoundingBoxMin	= NodeHeader.vBoundingBoxMin;
    pNode->vBoundingBoxMax	= NodeHeader.vBoundingBoxMax;

    // Ist es ein Endknoten?
    if(pNode->bIsLeaf)
    {
        m_dwNumLeaves++;

        // Indexdaten einlesen
        pData = (BYTE*)(m_pIndexBuffer->GetBuffer());
        pData += NodeHeader.dwStartIndex * pTreeCH->dwIndexSize;
        if(pVFile->Read(pNode->dwNumIndices * pTreeCH->dwIndexSize, pData))
        {
            // Fehler!
            TB_ERROR("Fehler beim Lesen der Indexdaten!", TB_ERROR);
        }

        // Speicher für Start, Ende und minimalen/maximalen Index jedes Effekts reservieren
        pNode->pdwEffectStart = (DWORD*)(tbMemAlloc(m_dwNumEffects * sizeof(DWORD)));
        pNode->pdwEffectEnd = (DWORD*)(tbMemAlloc(m_dwNumEffects * sizeof(DWORD)));
        pNode->pdwMinIndex = (DWORD*)(tbMemAlloc(m_dwNumEffects * sizeof(DWORD)));
        pNode->pdwMaxIndex = (DWORD*)(tbMemAlloc(m_dwNumEffects * sizeof(DWORD)));
        if(pNode->pdwEffectStart == NULL ||
                pNode->pdwEffectEnd == NULL ||
                pNode->pdwMinIndex == NULL ||
                pNode->pdwMaxIndex == NULL)
        {
            // Fehler!
            TB_ERROR_OUT_OF_MEMORY(TB_ERROR);
        }

        // Start, Ende und minimalen/maximalen Index jedes Effekts einlesen
        for(DWORD i = 0; i < m_dwNumEffects; i++)
        {
            pVFile->Read(sizeof(DWORD), &pNode->pdwEffectStart[i]);
            pVFile->Read(sizeof(DWORD), &pNode->pdwEffectEnd[i]);
            pVFile->Read(sizeof(DWORD), &pNode->pdwMinIndex[i]);
            pVFile->Read(sizeof(DWORD), &pNode->pdwMaxIndex[i]);
        }
    }
    else
    {
        // Speicher für die Unterknoten reservieren und sie rekursiv einlesen
        for(int i = 0; i < 8; i++)
        {
            // Speicher reservieren
            pNode->apChild[i] = (tbOctreeNode*)(tbMemAlloc(sizeof(tbOctreeNode)));
            if(pNode->apChild[i] == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

            // Unterknoten einlesen
            if(ReadNode(pNode->apChild[i], pTreeCH, pVFile))
            {
                // Fehler!
                TB_ERROR("Fehler beim Lesen eines Unterknotens!", TB_ERROR);
            }
        }
    }

    return TB_OK;
}
Esempio n. 13
0
// ******************************************************************
// Laden der Texturen eines Effekts
tbResult tbOctree::LoadEffectTextures(DWORD dwEffect,
                                      char* pcTexturePrefix,	// = ""
                                      char* pcTexturePostfix)	// = ""
{
    char	acVariable[256];
    char*	pcTextureFilename;
    char	acNewTextureFilename[256];
    DWORD	dwNumTextures;
    DWORD	dwTextureType;
    DWORD	dwColorKey;


    if(pcTexturePrefix == NULL) pcTexturePrefix = "";
    if(pcTexturePostfix == NULL) pcTexturePostfix = "";

    // Anzahl der Texturen lesen und in die Effektstruktur eintragen
    dwNumTextures = 0;
    m_pEffects[dwEffect].pEffect->GetEffect()->GetInt("NumTextures", (int*)(&dwNumTextures));
    m_pEffects[dwEffect].dwNumTextures = dwNumTextures;

    // Alle Texturen durchgehen
    for(DWORD dwTex = 0; dwTex < dwNumTextures; dwTex++)
    {
        // Dateiname abfragen
        sprintf(acVariable, "Texture%dFilename", dwTex + 1);
        if(SUCCEEDED(m_pEffects[dwEffect].pEffect->GetEffect()->GetString(acVariable, (LPCSTR*)(&pcTextureFilename))))
        {
            if(!tbTextureManager::IsInitialized()) TB_ERROR("Der Texturmanager wurde noch nicht initialisiert!", TB_ERROR);

            // Präfix und Postfix einfügen
            sprintf(acNewTextureFilename, "%s%s%s", pcTexturePrefix, pcTextureFilename, pcTexturePostfix);

            // Standardtexturtyp: 2D
            dwTextureType = 1;

            // Typ der Textur abfragen
            sprintf(acVariable, "Texture%dType", dwTex + 1);
            m_pEffects[dwEffect].pEffect->GetEffect()->GetInt(acVariable, (int*)(&dwTextureType));

            // Color-Key abfragen
            dwColorKey = 0;
            sprintf(acVariable, "Texture%dColorKey", dwTex + 1);
            m_pEffects[dwEffect].pEffect->GetEffect()->GetInt(acVariable, (int*)(&dwColorKey));

            // Nun die Textur laden
            if(dwTextureType == 1) m_pEffects[dwEffect].apTexture[dwTex] = tbTextureManager::GetTexture(acNewTextureFilename, TRUE, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, D3DFMT_UNKNOWN, 0, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, dwColorKey);
            else if(dwTextureType == 2) m_pEffects[dwEffect].apTexture[dwTex] = tbTextureManager::GetCubeTexture(acNewTextureFilename, TRUE, D3DX_DEFAULT, D3DX_DEFAULT, D3DFMT_UNKNOWN, 0, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, dwColorKey);
            else if(dwTextureType == 3) m_pEffects[dwEffect].apTexture[dwTex] = tbTextureManager::GetVolumeTexture(acNewTextureFilename, TRUE, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, D3DFMT_UNKNOWN, 0, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, dwColorKey);
            else
            {
                // Unbekannter Texturtyp!
                TB_ERROR("Unbekannter Texturtyp!", TB_ERROR);
            }

            // Prüfen
            if(m_pEffects[dwEffect].apTexture[dwTex] == NULL)
            {
                // Fehler!
                TB_ERROR("Fehler beim Laden einer Textur!", TB_ERROR);
            }

            // Dem Effekt die Textur zuweisen
            sprintf(acVariable, "Texture%d", dwTex + 1);
            m_pEffects[dwEffect].pEffect->GetEffect()->SetTexture(acVariable, m_pEffects[dwEffect].apTexture[dwTex]);
        }
    }

    return TB_OK;
}
Esempio n. 14
0
// ******************************************************************
// Initialisierung aus einer virtuellen Datei
tbResult tbSound::Init(tbVFile* pVFile,
					   DWORD dwFlags,			// = DSBCAPS_STATIC | DSBCAPS_LOCDEFER
					   GUID GUID3DAlgorithm,	// = GUID_NULL
					   DWORD dwNumBuffers)		// = 4
{
	HRESULT	hResult;
	DWORD	dwVFileCursor;


	// Parameter prüfen
	if(pVFile == NULL)		TB_ERROR_NULL_POINTER("pVFile", TB_ERROR);
	if(dwNumBuffers == 0)	TB_ERROR_INVALID_VALUE("dwNumBuffers", TB_ERROR);

	// Sicherstellen, dass DirectSound initialisiert wurde
	if(!tbDirectSound::IsInitialized()) TB_ERROR("DirectSound wurde noch nicht initialisiert!", TB_ERROR);


	// Platz für die Soundpufferschnittstellen machen
	m_ppSoundBuffers = (LPDIRECTSOUNDBUFFER*)(tbMemAlloc(dwNumBuffers * sizeof(LPDIRECTSOUNDBUFFER)));
	if(m_ppSoundBuffers == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

	// Speicher für DWORD-Zeitstempel reservieren
	m_pdwTimeStamps = (DWORD*)(tbMemAlloc(dwNumBuffers * sizeof(DWORD)));
	if(m_pdwTimeStamps == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

	// Wenn Effekte mit im Spiel sind, brauchen wir auch eine Liste der 8er-Versionen.
	if(dwFlags & DSBCAPS_CTRLFX)
	{
		m_ppSoundBuffers8 = (LPDIRECTSOUNDBUFFER8*)(tbMemAlloc(dwNumBuffers * sizeof(LPDIRECTSOUNDBUFFER8)));
		if(m_ppSoundBuffers8 == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);
	}

	// Wenn es 3D-Schnittstellen sind, brauchen wir noch drei weitere Listen:
	// - eine für die 3D-Soundpufferschnittstellen
	// - Zeitstempel für SetPosition
	// - eine für die ehemaligen Positionen
	if(dwFlags & DSBCAPS_CTRL3D)
	{
		m_pp3DSoundBuffers = (LPDIRECTSOUND3DBUFFER*)(tbMemAlloc(dwNumBuffers * sizeof(LPDIRECTSOUND3DBUFFER)));
		m_pllTimeStamps = (LONGLONG*)(tbMemAlloc(dwNumBuffers * sizeof(LONGLONG)));
		m_pvStartVelocities = (tbVector3*)(tbMemAlloc(dwNumBuffers * sizeof(tbVector3)));
		m_pvOldPositions = (tbVector3*)(tbMemAlloc(dwNumBuffers * sizeof(tbVector3)));
		if(m_pp3DSoundBuffers == NULL || m_pllTimeStamps == NULL || m_pvOldPositions == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);
	}

	// Die Flags und die Anzahl der Puffer kopieren
	m_dwFlags = dwFlags;
	m_dwNumBuffers = dwNumBuffers;

	// ------------------------------------------------------------------

	if(!(dwFlags & DSBCAPS_CTRLFX))
	{
		// Bei einem Sound, der ohne Effekte abgespielt wird, reicht es, den Soundpuffer
		// einmal zu erstellen und ihn dann immer wieder zu "klonen".
		m_ppSoundBuffers[0] = tbLoadWAVFile(tbDirectSound::GetDSound(), pVFile, dwFlags, GUID3DAlgorithm);
		if(m_ppSoundBuffers[0] == NULL) TB_ERROR("Fehler beim Laden der WAV-Datei!", TB_ERROR);

		if(m_dwNumBuffers > 1)
		{
			// Die restlichen Puffer klonen
			for(DWORD dwBuffer = 1; dwBuffer < m_dwNumBuffers; dwBuffer++)
			{
				hResult = tbDirectSound::GetDSound()->DuplicateSoundBuffer(m_ppSoundBuffers[0],
										 							       &m_ppSoundBuffers[dwBuffer]);
				if(FAILED(hResult)) TB_ERROR_DIRECTX("tbDirectSound::GetDSound()->DuplicateSoundBuffer",
					                                 hResult, TB_ERROR);
			}
		}
	}
	else
	{
		// Es sind Effekte erwünscht!
		// Dazu brauchen wir nun auch noch die 8er-Schnittstellen und Klonen der
		// Soundpuffer durch DuplicateSoundBuffer ist nicht mehr möglich.

		// Den Cursor der virtuellen Datei speichern, denn wenn wir den Sound mehrfach
		// laden, würde der Cursor über das Ende der Datei hinaus geraten.
		dwVFileCursor = pVFile->GetCursor();

		// Für jeden Puffer die WAV-Datei neu laden
		for(DWORD dwBuffer = 0; dwBuffer < m_dwNumBuffers; dwBuffer++)
		{
			// Cursorposition wiederherstellen
			pVFile->Seek(TB_VFSO_START, dwVFileCursor);

			// WAV-Datei laden
			m_ppSoundBuffers[dwBuffer] = tbLoadWAVFile(tbDirectSound::GetDSound(), pVFile, dwFlags, GUID3DAlgorithm);
			if(m_ppSoundBuffers[dwBuffer] == NULL) TB_ERROR("Fehler beim Laden der WAV-Datei!", TB_ERROR);

			// 8er-Schnittstelle erstellen
			m_ppSoundBuffers[dwBuffer]->QueryInterface(IID_IDirectSoundBuffer8,
				                                       (void**)(&m_ppSoundBuffers8[dwBuffer]));
		}
	}

	// Wenn 3D-Sound erwünscht ist, erstellen wir zu jedem Sound noch eine 3D-Schnittstelle.
	if(dwFlags & DSBCAPS_CTRL3D)
	{
		for(DWORD dwBuffer = 0; dwBuffer < m_dwNumBuffers; dwBuffer++)
		{
			// Schnittstelle abfragen
			m_ppSoundBuffers[dwBuffer]->QueryInterface(IID_IDirectSound3DBuffer,
				                                       (void**)(&m_pp3DSoundBuffers[dwBuffer]));
		}
	}

	return TB_OK;
}
Esempio n. 15
0
// ******************************************************************
// Initialisiert das Schattenvolumen
tbResult tbShadowVolume::Init(tbModel* pModel)
{
	// Parameter prüfen
	if(pModel == NULL)			TB_ERROR_NULL_POINTER("pModel", TB_ERROR);
	if(!pModel->m_bExtraData)	TB_ERROR("Das Modell hat keine Extradaten!", TB_ERROR);


	// Modell kopieren
	m_pModel = pModel;

	// Effekt für das Schattenvolumen erstellen
	m_pShadowVolumeEffect = new tbEffect;
	if(m_pShadowVolumeEffect->Init("TECHNIQUE T1\n"
								   "{\n"
								   "	PASS P1\n"
								   "	{\n"
								   "        Texture[0]			= Null;\n"
								   "		ZEnable				= True;\n"
								   "		ZWriteEnable		= False;\n"
								   "		ShadeMode			= Flat;\n"
								   "        FogEnable			= False;\n"
								   "		ColorOp[0]			= SelectArg1;\n"
								   "		ColorArg1[0]		= Current;\n"
								   "		ColorOp[1]			= Disable;\n"
								   "		Lighting			= False;\n"
								   "		StencilEnable		= True;\n"
								   "		StencilFunc			= Always;\n"
								   "		StencilFail			= Keep;\n"
								   "		StencilZFail		= Keep;\n"
								   "		StencilPass			= Decr;\n"
								   "		StencilMask			= 0xFFFFFFFF;\n"
								   "		StencilWriteMask	= 0xFFFFFFFF;\n"
								   "		TwoSidedStencilMode	= True;\n"
								   "		CCW_StencilFunc		= Always;\n"
								   "		CCW_StencilFail		= Keep;\n"
								   "		CCW_StencilZFail	= Keep;\n"
								   "		CCW_StencilPass		= Incr;\n"
								   "		CullMode			= None;\n"
								   "		ColorWriteEnable	= 0;\n"
								   "	}\n"
								   "}\n"
								   "\n"
								   "TECHNIQUE T2\n"
								   "{\n"
								   "	PASS P1\n"
								   "	{\n"
								   "        Texture[0]			= Null;\n"
								   "		ZEnable				= True;\n"
								   "		ZWriteEnable		= False;\n"
								   "		ShadeMode			= Flat;\n"
								   "        FogEnable			= False;\n"
								   "		ColorOp[0]			= SelectArg1;\n"
								   "		ColorArg1[0]		= Current;\n"
								   "		ColorOp[1]			= Disable;\n"
								   "		Lighting			= False;\n"
								   "		StencilEnable		= True;\n"
								   "		StencilFunc			= Always;\n"
								   "		StencilFail			= Keep;\n"
								   "		StencilZFail		= Keep;\n"
								   "		StencilPass			= Decr;\n"
								   "		StencilMask			= 0xFFFFFFFF;\n"
								   "		StencilWriteMask	= 0xFFFFFFFF;\n"
								   "		TwoSidedStencilMode	= True;\n"
								   "		CCW_StencilFunc		= Always;\n"
								   "		CCW_StencilFail		= Keep;\n"
								   "		CCW_StencilZFail	= Keep;\n"
								   "		CCW_StencilPass		= Incr;\n"
								   "		CullMode			= None;\n"
								   "		AlphaBlendEnable	= True;\n"
								   "		SrcBlend			= Zero;\n"
								   "		DestBlend			= One;\n"
								   "	}\n"
								   "}\n"
								   "\n"
								   "TECHNIQUE T3\n"
								   "{\n"
								   "	PASS P1\n"
								   "	{\n"
								   "        Texture[0]			= Null;\n"
								   "		ZEnable				= True;\n"
								   "		ZWriteEnable		= False;\n"
								   "		ShadeMode			= Flat;\n"
								   "        FogEnable			= False;\n"
								   "		ColorOp[0]			= SelectArg1;\n"
								   "		ColorArg1[0]		= Current;\n"
								   "		ColorOp[1]			= Disable;\n"
								   "		Lighting			= False;\n"
								   "		StencilEnable		= True;\n"
								   "		StencilFunc			= Always;\n"
								   "		StencilFail			= Keep;\n"
								   "		StencilZFail		= Keep;\n"
								   "		StencilPass			= Decr;\n"
								   "		StencilMask			= 0xFFFFFFFF;\n"
								   "		StencilWriteMask	= 0xFFFFFFFF;\n"
								   "		CullMode			= CCW;\n"
								   "		ColorWriteEnable	= 0;\n"
								   "	}\n"
								   "\n"
								   "	PASS P2\n"
								   "	{\n"
								   "		StencilPass			= Incr;\n"
								   "		CullMode			= CW;\n"
								   "	}\n"
								   "}\n"
								   "\n"
								   "TECHNIQUE T4\n"
								   "{\n"
								   "	PASS P1\n"
								   "	{\n"
								   "        Texture[0]			= Null;\n"
								   "		ZEnable				= True;\n"
								   "		ZWriteEnable		= False;\n"
								   "		ShadeMode			= Flat;\n"
								   "        FogEnable			= False;\n"
								   "		ColorOp[0]			= SelectArg1;\n"
								   "		ColorArg1[0]		= Current;\n"
								   "		ColorOp[1]			= Disable;\n"
								   "		Lighting			= False;\n"
								   "		StencilEnable		= True;\n"
								   "		StencilFunc			= Always;\n"
								   "		StencilFail			= Keep;\n"
								   "		StencilZFail		= Keep;\n"
								   "		StencilPass			= Decr;\n"
								   "		StencilMask			= 0xFFFFFFFF;\n"
								   "		StencilWriteMask	= 0xFFFFFFFF;\n"
								   "		CullMode			= CCW;\n"
								   "		AlphaBlendEnable	= True;\n"
								   "		SrcBlend			= Zero;\n"
								   "		DestBlend			= One;\n"
								   "	}\n"
								   "\n"
								   "	PASS P2\n"
								   "	{\n"
								   "		StencilPass			= Incr;\n"
								   "		CullMode			= CW;\n"
								   "	}\n"
								   "}\n", -1))
	{
		// Fehler!
		TB_ERROR("Fehler beim Erstellen des Effekts für das Schattenvolumen!", TB_ERROR);
	}

	// Effekt für den Schatten erstellen
	m_pShadowEffect = new tbEffect;
	if(m_pShadowEffect->Init("TECHNIQUE T1\n"
							 "{\n"
							 "	  PASS P1\n"
							 "	  {\n"
							 "        Texture[0]		= Null;\n"
							 "		  ZEnable			= False;\n"
							 "		  ZWriteEnable		= False;\n"
							 "		  StencilEnable		= True;\n"
							 "		  StencilFunc		= NotEqual;\n"
							 "		  StencilRef		= 0;\n"
						     "		  StencilFail		= Keep;\n"
						     "		  StencilZFail		= Keep;\n"
						     "		  StencilPass		= Keep;\n"
							 "		  StencilMask		= 0xFFFFFFFF;\n"
							 "		  ShadeMode			= Flat;\n"
 							 "        FogEnable			= False;\n"
							 "		  ColorOp[0]		= SelectArg1;\n"
							 "		  ColorArg1[0]		= Current;\n"
							 "		  ColorOp[1]		= Disable;\n"
							 "		  Lighting			= False;\n"
							 "		  ColorVertex		= True;\n"
							 "		  AlphaBlendEnable	= True;\n"
							 "		  SrcBlend			= SrcAlpha;\n"
							 "		  DestBlend			= InvSrcAlpha;\n"
							 "	  }\n"
						     "}\n", -1))
	{
		// Fehler!
		TB_ERROR("Fehler beim Erstellen des Effekts für den Schatten!", TB_ERROR);
	}

	// Speicher für die Dreiecksseiten reservieren
	m_pEdges = (tbEdge*)(tbMemAlloc(m_pModel->m_dwNumIndices * sizeof(tbEdge)));
	if(m_pEdges == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

	// Speicher für die Mittelpunkte der Dreiecke reservieren
	m_pvTriangleCenters = (tbVector3*)(tbMemAlloc(m_pModel->m_dwNumIndices / 3 * sizeof(tbVector3)));
	if(m_pvTriangleCenters == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

	// Speicher für die Vertizes des Schattenvolumens reservieren
	m_pvVertices = (tbVector3*)(tbMemAlloc(m_pModel->m_dwNumIndices * 6 * sizeof(tbVector3)));
	if(m_pvVertices == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

	// ------------------------------------------------------------------

	// Die Mittelpunkte aller Dreiecke berechnen
	for(DWORD t = 0; t < m_pModel->m_dwNumIndices / 3; t++)
	{
		// Mittelwert aus den drei Vektoren dieses Dreiecks berechnen
		m_pvTriangleCenters[t] = (m_pModel->m_pvVectors[m_pModel->m_pdwIndices[t * 3]] +
			                      m_pModel->m_pvVectors[m_pModel->m_pdwIndices[t * 3 + 1]] +
								  m_pModel->m_pvVectors[m_pModel->m_pdwIndices[t * 3 + 2]]) / 3.0f;
	}

	return TB_OK;
}
Esempio n. 16
0
// ******************************************************************
// Initialisierung aus virtuellen Dateien
tbResult tb2DSprite::Init(char* pcINIFile,
						  char* pcINISection,
						  tbVector2 (*converter)(tbVector2 vParam),	// = NULL
						  char* pcTextureFile)						// = NULL
{
	// vorsichtshalber alles vorher freigeben
	Exit();

	HRESULT		hResult;
	tbResult	tbRes;

	// Parameter prüfen und sicherstellen, dass tbDirect3D initialisiert wurde
	if(pcINIFile == NULL)				TB_ERROR_NULL_POINTER("pcINIFile", TB_ERROR);
	if(pcINISection == NULL)			TB_ERROR_NULL_POINTER("pcINISection", TB_ERROR);
	if(!tbDirect3D::IsInitialized())	TB_ERROR("Es muss zuerst eine tbDirect3D-Klasseninstanz erstellt werden!", TB_ERROR);

	
	// Informationsdatei vorbereiten
	tbINIReader* pINIReader;
	pINIReader = new tbINIReader; 	if(pINIReader == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);
	pINIReader->SetFilePath(pcINIFile);

	// ColorKey laden
	tbColor ColorKey = pINIReader->ReadINIColor(pcINISection, "ColorKey");
	if(ColorKey == tbColor(12345678.0f, 12345678.0f, 12345678.0f, 12345678.0f)) ColorKey = tbColor(0.0f, 0.0f, 0.0f, 1.0f);

	// Wenn kein Parameter übergeben nach INI-Eintrag suchen
	char acTextur[256];
	ZeroMemory(acTextur, sizeof(acTextur));
	if(pcTextureFile == NULL)
	{
		// Texturname aus INI laden wenn möglich
		pINIReader->ReadINIString(pcINISection, "Texture", acTextur, 256);
	
		// Kein INI-Eintrag gefunden?
		if(!strcmp(acTextur, "[NOT FOUND]"))
		{
			TB_ERROR("Fehler beim Laden der Sprite-Textur, kein INI-Eintrag gefunden!", TB_ERROR);
		}
	}
	else
	{
		strncpy(acTextur, pcTextureFile, 256);
	}

	// Texturmanager benutzen, wenn er initialisiert ist
	if(tbTextureManager::IsInitialized())
	{
		// Texturmanager benutzen merken
		m_bTexturmanager = TRUE;

		m_pTexture = tbTextureManager::GetTexture(acTextur, 
						TRUE, D3DX_DEFAULT, D3DX_DEFAULT, 
						1, D3DFMT_UNKNOWN, 0, D3DPOOL_MANAGED, 
						D3DX_DEFAULT, D3DX_DEFAULT, ColorKey);
		// Fehler?
		if(m_pTexture == NULL) TB_ERROR("Fehler beim Laden der Textur mit dem Texturmanager!",TB_ERROR);

		// Bilddimensionen speichern
		D3DSURFACE_DESC Desc;
		m_pTexture->GetLevelDesc(0, &Desc);
		m_2DSpriteInfo.fTextureHeight = (float)Desc.Height;
		m_2DSpriteInfo.fTextureWidth = (float)Desc.Width;
	}
	else
	{
		// Texturmanager nicht benutzen merken
		m_bTexturmanager = FALSE;

		tbVFile*	pVFile;

		// Virtuelle Dateien erstellen
		pVFile = new tbVFile;	if(pVFile == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

		// Aus Datei laden
		if(pVFile->Init(acTextur)) TB_ERROR("Fehler beim Erstellen der virtuellen Datei!", TB_ERROR);

		// Textur laden
		D3DXIMAGE_INFO dinfo;
		ZeroMemory(&dinfo, sizeof(dinfo));
		if(FAILED(hResult = D3DXCreateTextureFromFileInMemoryEx(tbDirect3D::GetDevice(),
																(BYTE*)(pVFile->GetBuffer()) + pVFile->GetCursor(),
																pVFile->GetSize() - pVFile->GetCursor(),
																D3DX_DEFAULT, D3DX_DEFAULT, 1, 0,
																D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
																D3DX_DEFAULT, D3DX_DEFAULT,
																ColorKey, &dinfo, NULL, &m_pTexture)))
		{
			// Fehler!
			TB_ERROR_DIRECTX("D3DXCreateTextureFromFileInMemoryEx", hResult, TB_ERROR);
		}
		// Bilddimensionen speichern
		m_2DSpriteInfo.fTextureHeight = (float)dinfo.Height;
		m_2DSpriteInfo.fTextureWidth = (float)dinfo.Width;

		// Die virtuellen Dateien wieder freigeben
		TB_SAFE_DELETE(pVFile);
	}


	// Sprite-Informationen laden
	ReadINISpriteInfo(pINIReader,
					  pcINISection, 
					  "Sprite", 
					  &m_2DSpriteInfo,
					  converter);


	// Effektname aus INI laden
	char acEffect[256];
	ZeroMemory(acEffect, sizeof(acEffect));
	pINIReader->ReadINIString(pcINISection, "Effect", acEffect, 256);
	if(!strcmp(acEffect, "[NOT FOUND]")) TB_ERROR("Fehler beim Laden des Sprite-Effekts!", TB_ERROR);
	// Effekt laden
	m_pEffect = new tbEffect; if(m_pEffect == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);
	if(TB_OK != (tbRes = m_pEffect->Init(acEffect))) TB_ERROR("Fehler beim Erstellen des Sprite-Effekts!", TB_ERROR);
	// Effekt setzen
	if(TB_OK != m_pEffect->SetTechnique())	TB_ERROR("Fehler beim Setzen des Sprite-Effekts!", TB_ERROR);

	// Textur setzen
	if(FAILED(hResult = m_pEffect->GetEffect()->SetTexture("Texture1", m_pTexture)))
	{
		// Fehler!
		TB_ERROR_DIRECTX("SetTexture", hResult, TB_ERROR);
	}


	// INIReader wieder freigeben
	TB_SAFE_DELETE(pINIReader);

	return TB_OK;
}
Esempio n. 17
0
// ******************************************************************
// Laden einer WAV-Datei
LPDIRECTSOUNDBUFFER tbLoadWAVFile(LPDIRECTSOUND8 pDSound,
								  tbVFile* pVFile,
								  DWORD dwFlags,
								  GUID GUID3DAlgorithm)
{
	HRESULT				hResult;
	tbRIFFHeader		RIFFHeader;
	tbWAVChunkHeader	ChunkHeader;
	BOOL				bFormatChunkRead = FALSE;
	BOOL				bDataChunkRead = FALSE;
	DWORD				dwNumBytesToRead;
	WAVEFORMATEX		WaveFormat;
	void*				pSoundData = NULL;
	DSBUFFERDESC		BufferDesc;
	LPDIRECTSOUNDBUFFER	pSoundBuffer;
	void*				pSoundBufferData;
	DWORD				dwSoundBufferDataSize;


	// Parameter prüfen
	if(pDSound == NULL)	TB_ERROR_NULL_POINTER("pDSound", NULL);
	if(pVFile == NULL)	TB_ERROR_NULL_POINTER("pVFile", NULL);


    // RIFF-Header lesen und prüfen
	if(pVFile->Read(sizeof(tbRIFFHeader), &RIFFHeader)) TB_ERROR("Fehler beim Lesen des RIFF-Headers!", NULL);
	if(strnicmp(RIFFHeader.acRIFF, "RIFF", 4)) TB_ERROR("RIFF-Signatur nicht gefunden!", NULL);
	if(strnicmp(RIFFHeader.acFormat, "WAVE", 4)) TB_ERROR("WAVE-Signatur nicht gefunden - die Datei ist keine WAV-Datei!", NULL);

	// ------------------------------------------------------------------

	// WAV-Chunks einlesen
	while(TRUE)
	{
		// Chunk-Header lesen. Bei einem Lesefehler haben wir das Dateiende erreicht.
		if(pVFile->Read(sizeof(tbWAVChunkHeader), &ChunkHeader)) break;

		if(!strnicmp(ChunkHeader.acType, "fmt ", 4))
		{
			// Es ist der Format-Chunk!
			// Prüfen, ob die Größe der Daten in Ordnung ist. Wenn sie größer ist als
			// die Größe der WAVEFORMATEX-Struktur, dann lassen wir die restlichen Bytes weg.
			dwNumBytesToRead = TB_MIN(ChunkHeader.dwDataSize, sizeof(WAVEFORMATEX));
			if(pVFile->Read(dwNumBytesToRead, &WaveFormat)) TB_ERROR("Fehler beim Lesen des Soundformats!", NULL);
			bFormatChunkRead = TRUE;
		}
		else if(!strnicmp(ChunkHeader.acType, "data", 4))
		{
			// Es ist der Daten-Chunk!
			// Genügend Speicher reservieren und dann die Daten lesen.
			pSoundData = tbMemAlloc(ChunkHeader.dwDataSize);
			if(pSoundData == NULL) TB_ERROR_OUT_OF_MEMORY(NULL);
			if(pVFile->Read(ChunkHeader.dwDataSize, pSoundData)) TB_ERROR("Fehler beim Lesen der Sounddaten!", NULL);
			bDataChunkRead = TRUE;
		}
		else
		{
			// Unbekannter Chunk - überspringen
			pVFile->Seek(TB_VFSO_CURSOR, ChunkHeader.dwDataSize);
		}
	}

	// Prüfen, ob alle wichtigen Chunks vorhanden waren
	if(!(bFormatChunkRead && bDataChunkRead))
	{
		// Fehler!
		TB_SAFE_MEMFREE(pSoundData);
		TB_ERROR("Die Chunks \"fmt \" und \"data\" müssen beide vorhanden sein!", NULL);
	}

	// ------------------------------------------------------------------

	// DSBUFFERDESC-Struktur ausfüllen
	BufferDesc.dwSize			= sizeof(DSBUFFERDESC);
	BufferDesc.dwFlags			= dwFlags;
	BufferDesc.dwBufferBytes	= tbMemGetSize(pSoundData);
	BufferDesc.dwReserved		= 0;
	BufferDesc.lpwfxFormat		= &WaveFormat;
	BufferDesc.guid3DAlgorithm	= GUID3DAlgorithm;

	// Puffer erstellen
	if(FAILED(hResult = pDSound->CreateSoundBuffer(&BufferDesc,
		                                           &pSoundBuffer,
												   NULL)))
	{
		// Fehler!
		TB_ERROR_DIRECTX("pDSound->CreateSoundBuffer", hResult, NULL);
	}

	// ------------------------------------------------------------------

	// Puffer komplett sperren
	hResult = pSoundBuffer->Lock(0, 0, &pSoundBufferData, &dwSoundBufferDataSize, NULL, NULL, DSBLOCK_ENTIREBUFFER);
	if(FAILED(hResult))
	{
		// Fehler!
		TB_SAFE_MEMFREE(pSoundData);
		TB_SAFE_RELEASE(pSoundBuffer);
		TB_ERROR_DIRECTX("pSoundBuffer->Lock", hResult, NULL);
	}

	// Die Daten hineinschreiben und den Puffer entsperren
	memcpy(pSoundBufferData, pSoundData, TB_MIN(tbMemGetSize(pSoundData), (int)(dwSoundBufferDataSize)));
	pSoundBuffer->Unlock(pSoundBufferData, dwSoundBufferDataSize, NULL, 0);

	// Die Sounddaten freigeben
	TB_SAFE_MEMFREE(pSoundData);

	// Den Soundpuffer zurückliefern
	return pSoundBuffer;
}
Esempio n. 18
0
// ******************************************************************
// Berechnet die Extradaten des Octrees
tbResult tbOctree::ComputeExtraData(tbOctreeNode* pNode)
{
    DWORD		dwVertexSize;
    BYTE*		pVector;
    DWORD		dwIndexSize;
    BYTE*		pIndex;
    tbVector3	vTriA;
    tbVector3	vTriB;
    tbVector3	vTriC;
    tbVector3	vTemp;


    if(pNode == m_pRootNode)
    {
        // Speicher für die Positionsvektoren reservieren
        m_pvVectors = (tbVector3*)(tbMemAlloc(m_dwNumVertices * sizeof(tbVector3)));
        if(m_pvVectors == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

        // Vertexgröße ermitteln
        dwVertexSize = m_pVertexBuffer->GetVertexSize();

        // Die Positionsvektoren kopieren
        pVector = (BYTE*)(m_pVertexBuffer->GetBuffer());
        for(DWORD i = 0; i < m_dwNumVertices; i++)
        {
            // Die Positionsangabe ist immer der erste Teil eines Vertex.
            m_pvVectors[i] = *((tbVector3*)(pVector));
            pVector += dwVertexSize;
        }
    }

    if(pNode->bIsLeaf)
    {
        // Indexgröße ermitteln
        dwIndexSize = m_pIndexBuffer->GetIndexSize();

        // Platz für die Indizes und die Dreiecksebenen reservieren
        pNode->pdwIndices = (DWORD*)(tbMemAlloc(pNode->dwNumIndices * sizeof(DWORD)));
        if(pNode->pdwIndices == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);
        pNode->pTrianglePlanes = (tbPlane*)(tbMemAlloc(pNode->dwNumIndices / 3 * 4 * sizeof(tbPlane)));
        if(pNode->pTrianglePlanes == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

        // Die Indizes kopieren
        pIndex = (BYTE*)(m_pIndexBuffer->GetBuffer());
        pIndex += pNode->dwStartIndex * dwIndexSize;
        for(DWORD i = 0; i < pNode->dwNumIndices; i++)
        {
            // Index herausfinden
            if(m_pIndexBuffer->GetIndexFormat() == D3DFMT_INDEX16) pNode->pdwIndices[i] = *((WORD*)(pIndex));
            else if(m_pIndexBuffer->GetIndexFormat() == D3DFMT_INDEX32) pNode->pdwIndices[i] = *((DWORD*)(pIndex));
            else pNode->pdwIndices[i] = 0;
            pIndex += dwIndexSize;
        }

        // Jeweils vier Ebenen pro Dreieck berechnen
        for(i = 0; i < pNode->dwNumIndices / 3; i++)
        {
            // Die drei Vektoren des Dreiecks kopieren
            vTriA = m_pvVectors[pNode->pdwIndices[i * 3]];
            vTriB = m_pvVectors[pNode->pdwIndices[i * 3 + 1]];
            vTriC = m_pvVectors[pNode->pdwIndices[i * 3 + 2]];

            // Ebene des Dreiecks berechnen
            pNode->pTrianglePlanes[i * 4] = tbPlaneNormalize(tbPlaneFromPoints(vTriA, vTriB, vTriC));

            // Die drei Seitenebenen berechnen
            vTemp = tbVector3Normalize(tbVector3Cross(vTriA - vTriB, pNode->pTrianglePlanes[i * 4].n));
            pNode->pTrianglePlanes[i * 4 + 1] = tbPlaneFromPointNormal(vTriA, vTemp);

            vTemp = tbVector3Normalize(tbVector3Cross(vTriB - vTriC, pNode->pTrianglePlanes[i * 4].n));
            pNode->pTrianglePlanes[i * 4 + 2] = tbPlaneFromPointNormal(vTriB, vTemp);

            vTemp = tbVector3Normalize(tbVector3Cross(vTriC - vTriA, pNode->pTrianglePlanes[i * 4].n));
            pNode->pTrianglePlanes[i * 4 + 3] = tbPlaneFromPointNormal(vTriC, vTemp);
        }
    }
    else
    {
        // Die Extradaten der Unterknoten berechnen
        for(int i = 0; i < 8; i++)
        {
            if(ComputeExtraData(pNode->apChild[i]))
            {
                // Fehler!
                TB_ERROR("Fehler beim Berechnen der Extradaten!", TB_ERROR);
            }
        }
    }

    return TB_OK;
}
Esempio n. 19
0
// ******************************************************************
// Initialisierung aus virtuellen Dateien
tbResult tbFont::Init(tbVFile* pTGAFile,
					  tbVFile* pTBFFile)
{
	HRESULT hResult;

	// Parameter prüfen und sicherstellen, dass tbDirect3D initialisiert wurde
	if(pTGAFile == NULL)				TB_ERROR_NULL_POINTER("pTGAFile", TB_ERROR);
	if(pTBFFile == NULL)				TB_ERROR_NULL_POINTER("pTBFFile", TB_ERROR);
	if(!tbDirect3D::IsInitialized())	TB_ERROR("Es muss zuerst eine tbDirect3D-Klasseninstanz erstellt werden!", TB_ERROR);


	// Textur laden
	if(FAILED(hResult = D3DXCreateTextureFromFileInMemoryEx(tbDirect3D::GetDevice(),
		                                                    (BYTE*)(pTGAFile->GetBuffer()) + pTGAFile->GetCursor(),
															pTGAFile->GetSize() - pTGAFile->GetCursor(),
															D3DX_DEFAULT, D3DX_DEFAULT, 1, 0,
															D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
															D3DX_DEFAULT, D3DX_DEFAULT,
															0, NULL, NULL, &m_pTexture)))
	{
		// Fehler!
		TB_ERROR_DIRECTX("D3DXCreateTextureFromFileInMemoryEx", hResult, TB_ERROR);
	}

	// Informationen laden
	if(pTBFFile->Read(sizeof(tbFontInfo), &m_FontInfo))
	{
		// Fehler!
		TB_ERROR("Fehler beim Lesen der Schriftinformationen!", TB_ERROR);
	}

	// Effekt aus String erstellen
	m_pEffect = new tbEffect; if(m_pEffect == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);
	if(m_pEffect->Init("TEXTURE Texture;\n"
		               "\n"
		               "TECHNIQUE T1\n"
		               "{\n"
					   "	PASS P1\n"
					   "	{\n"
					   "        Texture[0]          = <Texture>;\n"
					   "		ZEnable				= False;\n"
					   "		ZWriteEnable		= False;\n"
					   "		ColorOp[0]			= Modulate;\n"
					   "		ColorArg1[0]		= Texture;\n"
					   "		ColorArg2[0]		= Current;\n"
					   "		ColorOp[1]			= Disable;\n"
					   "		AlphaOp[0]			= Modulate;\n"
					   "		AlphaArg1[0]		= Texture;\n"
					   "		AlphaArg2[0]		= Current;\n"
					   "		AlphaOp[1]			= Disable;\n"
					   "		AlphaBlendEnable	= True;\n"
					   "		SrcBlend			= SrcAlpha;\n"
					   "		DestBlend			= InvSrcAlpha;\n"
					   "	}\n"
					   "}\n", -1))
	{
		// Fehler!
		TB_ERROR("Fehler beim Erstellen des Effekts!", TB_ERROR);
	}

	// Textur setzen
	m_pEffect->GetEffect()->SetTexture("Texture", m_pTexture);

	return TB_OK;
}
Esempio n. 20
0
// ******************************************************************
// Laden aus einer virtuellen Datei
tbResult tbOctree::Init(tbVFile* pVFile,
                        char* pcTexturePrefix,		// = ""
                        char* pcTexturePostfix,		// = ""
                        D3DPOOL VBPool,				// = D3DPOOL_DEFAULT
                        DWORD dwVBUsage,			// = D3DUSAGE_WRITEONLY
                        D3DPOOL IBPool,				// = D3DPOOL_DEFAULT
                        DWORD dwIBUsage,			// = D3DUSAGE_WRITEONLY
                        BOOL bGenerateExtraData)	// = TRUE
{
    tbOctreeChunkHeader			ChunkHeader;
    tbOctreeVerticesChunkHeader	VerticesCH;
    tbOctreeTreeChunkHeader		TreeCH;
    DWORD						dwEffect;


    // Parameter prüfen und sicherstellen, dass alles initialisiert wurde
    if(pVFile == NULL)					TB_ERROR_NULL_POINTER("pVFile", TB_ERROR);
    if(!tbDirect3D::IsInitialized())	TB_ERROR("Direct3D wurde noch nicht initialisiert!", TB_ERROR);


    // Die Datei Chunk für Chunk lesen
    while(!pVFile->IsEOF())
    {
        // Chunk-Header lesen
        if(pVFile->Read(sizeof(tbOctreeChunkHeader), &ChunkHeader))
        {
            // Fehler!
            TB_ERROR("Fehler beim Lesen des Chunk-Headers!", TB_ERROR);
        }

        // Je nach Chunk-Typ...
        switch(ChunkHeader.ChunkType)
        {
        case TB_CT_OCTREE_VERTICES: // Vertexdaten
            // Vertexdaten-Chunk-Header einlesen
            if(pVFile->Read(sizeof(tbOctreeVerticesChunkHeader), &VerticesCH))
            {
                // Fehler!
                TB_ERROR("Fehler beim Lesen des Vertexdaten-Chunk-Headers!", TB_ERROR);
            }

            // Angaben kopieren
            m_dwFVF			= VerticesCH.dwFVF;
            m_dwNumVertices	= VerticesCH.dwNumVertices;

            // Vertex-Buffer erstellen
            m_pVertexBuffer = new tbVertexBuffer;
            if(m_pVertexBuffer == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

            // Initialisierung mit den in der Datei gespeicherten Parametern
            if(m_pVertexBuffer->Init(VerticesCH.dwNumVertices * VerticesCH.dwVertexSize,
                                     VerticesCH.dwVertexSize, VerticesCH.dwFVF,
                                     dwVBUsage | D3DUSAGE_WRITEONLY, VBPool))
            {
                // Fehler beim Erstellen des Vertex-Buffers!
                TB_ERROR("Fehler beim Erstellen des Vertex-Buffers!", TB_ERROR);
            }

            // Die Vertexdaten lesen
            if(pVFile->Read(VerticesCH.dwNumVertices * VerticesCH.dwVertexSize,
                            m_pVertexBuffer->GetBuffer()))
            {
                // Lesefehler!
                TB_ERROR("Fehler beim Lesen der Vertexdaten!", TB_ERROR);
            }

            // Vertex-Buffer aktualisieren
            m_pVertexBuffer->SetFirstVertex(0);
            m_pVertexBuffer->SetLastVertex(VerticesCH.dwNumVertices - 1);
            if(m_pVertexBuffer->Update()) TB_ERROR("Fehler beim Aktualisieren des Vertex-Buffers!", TB_ERROR);
            break;


        case TB_CT_OCTREE_EFFECTS: // Effekte
            // Anzahl der Effekte lesen
            if(pVFile->Read(sizeof(DWORD), &m_dwNumEffects)) TB_ERROR("Fehler beim Lesen der Effektanzahl!", TB_ERROR);

            // Genug Speicher für die Effekte reservieren
            m_pEffects = (tbOctreeEffect*)(tbMemAlloc(m_dwNumEffects * sizeof(tbOctreeEffect)));
            if(m_pEffects == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

            // Jeden Effekt durchgehen
            for(dwEffect = 0; dwEffect < m_dwNumEffects; dwEffect++)
            {
                // Den Effekt-Header lesen
                if(pVFile->Read(sizeof(tbOctreeEffectHeader), &m_pEffects[dwEffect].Header))
                {
                    // Fehler!
                    TB_ERROR("Fehler beim Lesen des Effekt-Headers!", TB_ERROR);
                }

                // Speicher für den Effektcode reservieren
                m_pEffects[dwEffect].pcCode = (char*)(tbMemAlloc(m_pEffects[dwEffect].Header.dwEffectCodeSize));
                if(m_pEffects[dwEffect].pcCode == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

                // Effektcode lesen
                if(pVFile->Read(m_pEffects[dwEffect].Header.dwEffectCodeSize,
                                m_pEffects[dwEffect].pcCode))
                {
                    // Fehler!
                    TB_ERROR("Fehler beim Lesen des Effektcodes!", TB_ERROR);
                }

                // tbEffect-Klasseninstanz erstellen
                m_pEffects[dwEffect].pEffect = new tbEffect;
                if(m_pEffects[dwEffect].pEffect == NULL)
                {
                    // Fehler!
                    TB_ERROR_OUT_OF_MEMORY(TB_ERROR);
                }

                // Den Effekt initialisieren
                if(m_pEffects[dwEffect].pEffect->Init(m_pEffects[dwEffect].pcCode,
                                                      m_pEffects[dwEffect].Header.dwEffectCodeSize))
                {
                    // Fehler beim Erstellen des Effekts!
                    TB_ERROR("Fehler beim Erstellen des Effekts!", TB_ERROR);
                }

                // Die Texturen für den Effekt laden
                if(LoadEffectTextures(dwEffect, pcTexturePrefix, pcTexturePostfix))
                {
                    // Fehler!
                    TB_ERROR("Fehler beim Laden der Effekttexturen!", TB_ERROR);
                }
            }
            break;


        case TB_CT_OCTREE_LIGHTING: // Beleuchtung
            // Anzahl der Lichter lesen
            if(pVFile->Read(sizeof(DWORD), &m_dwNumLights))
            {
                // Fehler!
                TB_ERROR("Fehler beim Lesen der Anzahl der Lichter!", TB_ERROR);
            }

            // Speicher für die Lichter reservieren
            m_pLights = (D3DLIGHT9*)(tbMemAlloc(m_dwNumLights * sizeof(D3DLIGHT9)));
            if(m_pLights == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

            // Die Lichtdaten einlesen
            if(pVFile->Read(m_dwNumLights * sizeof(D3DLIGHT9), m_pLights))
            {
                // Fehler!
                TB_ERROR("Fehler beim Lesen der Lichter!", TB_ERROR);
            }
            break;


        case TB_CT_OCTREE_TREE: // Octree-Daten
            // Header lesen
            if(pVFile->Read(sizeof(tbOctreeTreeChunkHeader), &TreeCH))
            {
                // Fehler!
                TB_ERROR("Fehler beim Lesen des Octree-Chunk-Headers!", TB_ERROR);
            }

            // Index-Buffer-Daten kopieren und Index-Buffer erzeugen
            m_IndexFormat = TreeCH.IndexFormat;
            m_dwNumIndices = TreeCH.dwNumIndices;

            // Index-Buffer erstellen
            m_pIndexBuffer = new tbIndexBuffer;
            if(m_pIndexBuffer == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

            // Initialisierung mit den in der Datei gespeicherten Parametern
            if(m_pIndexBuffer->Init(TreeCH.dwNumIndices * TreeCH.dwIndexSize,
                                    TreeCH.dwIndexSize, TreeCH.IndexFormat,
                                    dwIBUsage | D3DUSAGE_WRITEONLY, IBPool))
            {
                // Fehler beim Erstellen des Index-Buffers!
                TB_ERROR("Fehler beim Ersstellen des Index-Buffers!", TB_ERROR);
            }

            // Wurzelknoten erzeugen
            m_pRootNode = (tbOctreeNode*)(tbMemAlloc(sizeof(tbOctreeNode)));
            if(m_pRootNode == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);

            // Baum rekursiv lesen
            if(ReadNode(m_pRootNode, &TreeCH, pVFile))
            {
                // Fehler!
                TB_ERROR("Fehler beim Lesen des Octrees!", TB_ERROR);
            }

            // Index-Buffer aktualisieren
            m_pIndexBuffer->SetFirstIndex(0);
            m_pIndexBuffer->SetLastIndex(TreeCH.dwNumIndices - 1);
            if(m_pIndexBuffer->Update()) TB_ERROR("Fehler beim Aktualisieren des Index-Buffers!", TB_ERROR);

            // Speicher für die Sichtbarkeitsliste reservieren
            m_ppVisibleList = (tbOctreeNode**)(tbMemAlloc(m_dwNumLeaves * sizeof(tbOctreeNode*)));
            if(m_ppVisibleList == NULL) TB_ERROR_OUT_OF_MEMORY(TB_ERROR);
            break;


        default:
            // Dieser Chunk wird nicht gelesen - wir überspringen ihn!
            if(pVFile->Seek(TB_VFSO_CURSOR, ChunkHeader.dwDataSize))
            {
                // Fehler!
                TB_ERROR("Fehler beim Überspringen eines Chunks!", TB_ERROR);
            }
            break;
        }
    }

    m_bExtraData = bGenerateExtraData;

    if(m_bExtraData)
    {
        // Die Extradaten berechnen
        ComputeExtraData(m_pRootNode);
    }

    return TB_OK;
}
Esempio n. 21
0
// ******************************************************************
// Initialisiert die Sky-Box
tbResult tbSkyBox::Init(PDIRECT3DCUBETEXTURE9 pCubeMap)
{
	tbSkyBoxVertex aVertex[8];

	// Sicherstellen, dass Direct3D korrekt initialisiert wurde
	if(!tbDirect3D::IsInitialized()) TB_ERROR("Direct3D wurde noch nicht initialisiert!", TB_ERROR);


	// Vertex-Buffer erstellen
	m_pVB = new tbVertexBuffer;
	if(m_pVB->Init(8 * sizeof(tbSkyBoxVertex), sizeof(tbSkyBoxVertex),
		           TB_SKYBOX_FVF))
	{
		// Fehler!
		TB_ERROR("Fehler beim Erstellen des Vertex-Buffers!", TB_ERROR);
	}

	// Index-Buffer erstellen
	m_pIB = new tbIndexBuffer;
	if(m_pIB->Init(36 * sizeof(WORD), sizeof(WORD), D3DFMT_INDEX16))
	{
		// Fehler!
		TB_ERROR("Fehler beim Erstellen des Index-Buffers!", TB_ERROR);
	}

	// ------------------------------------------------------------------

	// Die Vertizes erstellen
	aVertex[0].vPosition = tbVector3(-1.0f,  1.0f,  1.0f);
	aVertex[1].vPosition = tbVector3( 1.0f,  1.0f,  1.0f);
	aVertex[2].vPosition = tbVector3( 1.0f,  1.0f, -1.0f);
	aVertex[3].vPosition = tbVector3(-1.0f,  1.0f, -1.0f);
	aVertex[4].vPosition = tbVector3(-1.0f, -1.0f,  1.0f);
	aVertex[5].vPosition = tbVector3( 1.0f, -1.0f,  1.0f);
	aVertex[6].vPosition = tbVector3( 1.0f, -1.0f, -1.0f);
	aVertex[7].vPosition = tbVector3(-1.0f, -1.0f, -1.0f);

	// Die Texturkoordinaten entsprechen den Vertexpositionen
	for(int iVertex = 0; iVertex < 8; iVertex++)
	{
		// Texturkoordinate eintragen und Sky-Box skalieren
		aVertex[iVertex].vTexture = aVertex[iVertex].vPosition;
		aVertex[iVertex].vPosition *= 50.0f;
	}

	// Alle Vertizes eintragen und den Vertex-Buffer aktualisieren
	m_pVB->AddVertices(8, aVertex);
	if(m_pVB->Update()) TB_ERROR("Fehler beim Schreiben in den Vertex-Buffer!", TB_ERROR);

	// ------------------------------------------------------------------

	// Den Index-Buffer ausfüllen
	WORD awIndex[36] = {7, 3, 0,   4, 7, 0,		// Vorderseite
						5, 1, 2,   6, 5, 2,		// Hinterseite
						4, 0, 1,   5, 4, 1,		// Linke Seite
						6, 2, 3,   7, 6, 3,		// Rechte Seite
						2, 1, 0,   3, 2, 0,		// Oberseite
						4, 5, 6,   7, 4, 6};	// Unterseite
	m_pIB->AddIndices(36, awIndex);
	if(m_pIB->Update()) TB_ERROR("Fehler beim Schreiben in den Index-Buffer!", TB_ERROR);

	// ------------------------------------------------------------------

	// Textur kopieren
	m_pCubeMap = pCubeMap;

	// Effekt aus String erstellen
	m_pEffect = new tbEffect;
	if(m_pEffect->Init("TEXTURE Texture;\n"
		               "\n"
		               "TECHNIQUE T1\n"
		               "{\n"
					   "	PASS P1\n"
					   "	{\n"
					   "        Texture[0]		= <Texture>;\n"
					   "		ZEnable			= False;\n"
					   "		ZWriteEnable	= False;\n"
					   "		ColorOp[0]		= SelectArg1;\n"
					   "		ColorArg1[0]	= Texture;\n"
					   "		ColorOp[1]		= Disable;\n"
					   "		Lighting		= False;\n"
					   "		ColorVertex		= False;\n"
					   "	}\n"
					   "}\n", -1))
	{
		// Fehler!
		TB_ERROR("Fehler beim Erstellen des Effekts!", TB_ERROR);
	}

	// Textur setzen
	m_pEffect->GetEffect()->SetTexture("Texture", m_pCubeMap);

	return TB_OK;
}
static char *
get_exc_trace()
{
    char *tbstr = NULL; 

    PyObject *iostrmod = NULL;
    PyObject *tbmod = NULL;
    PyObject *iostr = NULL;
    PyObject *obstr = NULL;
    PyObject *args = NULL;
    PyObject *newstr = NULL;
    PyObject *func = NULL;
    char* rv = NULL; 

    PyObject *type, *value, *traceback;
    TARGET_THREAD_BEGIN_BLOCK; 
    PyErr_Fetch(&type, &value, &traceback);
    debug("** type %p, value %p, traceback %p", type, value, traceback); 
    PyErr_Print(); 
    PyErr_Clear(); 
    PyErr_NormalizeException(&type, &value, &traceback);
    debug("** type %p, value %p, traceback %p", type, value, traceback); 

    iostrmod = PyImport_ImportModule("StringIO");
    if (iostrmod==NULL)
        TB_ERROR("can't import StringIO");

    iostr = PyObject_CallMethod(iostrmod, "StringIO", NULL);

    if (iostr==NULL)
        TB_ERROR("cStringIO.StringIO() failed");

    tbmod = PyImport_ImportModule("traceback");
    if (tbmod==NULL)
        TB_ERROR("can't import traceback");

    obstr = PyObject_CallMethod(tbmod, "print_exception",
        "(OOOOO)",
        type ? type : Py_None, 
        value ? value : Py_None,
        traceback ? traceback : Py_None,
        Py_None,
        iostr);

    if (obstr==NULL) 
    {
        PyErr_Print(); 
        TB_ERROR("traceback.print_exception() failed");
    }

    Py_DecRef(obstr);

    obstr = PyObject_CallMethod(iostr, "getvalue", NULL);
    if (obstr==NULL) 
        TB_ERROR("getvalue() failed.");

    if (!PyString_Check(obstr))
        TB_ERROR("getvalue() did not return a string");

    debug("%s", PyString_AsString(obstr)); 
    args = PyTuple_New(2);
    PyTuple_SetItem(args, 0, string2target("\n")); 
    PyTuple_SetItem(args, 1, string2target("<br>")); 
    
    func = PyObject_GetAttrString(obstr, "replace"); 
    //newstr = PyObject_CallMethod(obstr, "replace", args); 
    newstr = PyObject_CallObject(func, args); 

    tbstr = PyString_AsString(newstr); 

    rv = fmtstr("plugin:%s", tbstr); 

cleanup:
    PyErr_Restore(type, value, traceback);

    if (rv == NULL)
    {
        rv = tbstr ? tbstr : "";
    }

    Py_DecRef(func);
    Py_DecRef(args);
    Py_DecRef(newstr);
    Py_DecRef(iostr);
    Py_DecRef(obstr);
    Py_DecRef(iostrmod);
    Py_DecRef(tbmod);


    TARGET_THREAD_END_BLOCK; 
    return rv;
}