// ****************************************************************** // 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; }
// ****************************************************************** // 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; }
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; } }
// ****************************************************************** // 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; }
// ****************************************************************** // 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; }
// ****************************************************************** // 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; }
// ****************************************************************** // 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; }
// ****************************************************************** // 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; }
// ****************************************************************** // 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; }
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; }
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; } }
// ****************************************************************** // 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; }
// ****************************************************************** // 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; }
// ****************************************************************** // 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; }
// ****************************************************************** // 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; }
// ****************************************************************** // 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; }
// ****************************************************************** // 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; }
// ****************************************************************** // 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; }
// ****************************************************************** // 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; }
// ****************************************************************** // 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; }
// ****************************************************************** // 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; }