Gammastrahler

Members
  • Content count

    552
  • Joined

  • Last visited

Community Reputation

150 Neutral

About Gammastrahler

  • Rank
    Advanced Member
  1. BSP Tree Question

    Thank you for the detailed description :)
  2. BSP Tree Question

    Hi,   i want to use a BSP tree for processing boolean operations on solids (CSG). In theory, i have understood the algorithm, but what actually confuses me is the step when selecting the splitting polygons for the BSP construction process. For example, if i have a cube, do i need a split plane / left and right nodes for each side of the cube?   Any help would be appreciated.   Regards Gammastrahler
  3. Portal Rendering Loop

    Hi, i have read some articles about portal rendering - unfortunately, it seems there are only a few on the web. From what i have understand i have build some code. It would be nice if someone could review my main loop for object culling / rendering. Short description of the code: I render the current sector (the one the viewpos is in), then iterate over each portal, clip them against the current view frustum and build a reduced view frustum from those. Finally, i render the adjacent sector, which should recursively render all sectors until all visible ones are drawn. Is this procedure correct or are there some flaws in my code? Thanks in adavance, Gammastrahler [code] void ZSector::render(const CVector3 &currPos, CFrustum &viewFrustum) { if (_tagged) return; _tagged = true; gPolysDrawn++; // Render the current sector std::vector<CPolygon*>::iterator pPoly = _polyList.begin(); for ( ; pPoly != _polyList.end(); ++pPoly) { (*pPoly)->render(currPos); } for (std::vector<ZPortal*>::iterator p = _portalList.begin(); p != _portalList.end(); ++p) { CPolygon clippedPortal = (*p)->_poly; // If the portal is not within the current view frustum, ignore it if (!viewFrustum.poly_visible(clippedPortal)) continue; // Clip the portal against each plane of our view frustum for (int plane = 0; plane < viewFrustum._nPlanes; plane++) { CPolygon result[2]; if (SplitPolygon(clippedPortal, viewFrustum._planes[plane], result)) clippedPortal = result[0]; } // Check for invalid portals if (clippedPortal._nVerts < 3) continue; // Remember the near and far plane CPlane farPlane = viewFrustum._planes[viewFrustum._nPlanes-2]; CPlane nearPlane = viewFrustum._planes[viewFrustum._nPlanes-1]; viewFrustum._nPlanes = 0; // Build the reduced view frustum from the // new portal for (int i = 0; i < clippedPortal._nVerts; i++) { CVertex v1 = clippedPortal._verts[i]; CVertex v2 = clippedPortal._verts[i+1]; if (i == clippedPortal._nVerts - 1) v2 = clippedPortal._verts[0]; CVector3 sideNormal; sideNormal.Cross(v2, v1); sideNormal.normalize(); viewFrustum._planes[i]._normal = sideNormal; viewFrustum._planes[i]._d = 0.0; viewFrustum._nPlanes++; } // Reset the near and far plane viewFrustum._planes[viewFrustum._nPlanes++] = farPlane; viewFrustum._planes[viewFrustum._nPlanes++] = nearPlane; // Call adjacent sector if ((*p)->_adjacent) (*p)->_adjacent->render(currPos, viewFrustum); } } [/code]
  4. Hi, in my project i need to store the memory address of strings, to access them later. for some implementation specific reasons, the code enforces that i have to store that address in a variable of an unsigned int type rather than directly in a pointer. here is an example: gStringPtr = new char[..]; // copy something into gStringPtr strcpy(gStringPtr, "..."); // save address unsigned int addr = (unsigned int)gStringPtr; char* copy = (char*)addr; strcpy(copy, "Blabla"); // Crashes The call to strcpy crashes, although it points to the correct memory address saved before. Can someone help me with this problem? I have no idea of how to solve my problem. Thanks Gammastrahler
  5. OOP Design Question (C++)

    @mikeman: okay, i´ll show you an example :) my parser uses code like this: consider this simple expression parser: void parse_expr() { CVar* myLeftVal = /* irgs :( */ static_cast<CVar*>(_symTable.find_symbol(token.lexeme)); CVar* myRightVal = /* irgs :( */ static_cast<CVar*>(_symTable.find_symbol(token.lexeme)); create_mov_instr(myLeftVal.address, myRightVal.address); } Since the abstract symbol class has no address() member, i need to cast i could provide an asbtract virtual function address() in the CSymbol base class, but this doesn´t make sense, then CType, which represents a data type also derives from CSymbol, has no address @luke2 Thanks, i give it a try ;) but is there a way to restrict the client to always use types of CSymbol?
  6. Hi, i´m writing a compiler for my scripting language. Currently, i design the symbol table, and i use OOP to implement it: class CSymbol { const string _name; size_t dataSize; CScope* _scope; &&... } class CType : public CSymbol { bool _isArray; bool _isPointer; &&... } class CVar : public CSymbol { size_t address; //... } The problem with this design is, that it violates the OOP rule that an abstract class should have at least one virtual method. but in my design, i don´t need any virtual methods, i only need the inheritance. Should i use another approach to implement my symbol table? The second pain in the neck is, that if i lookup specific symbols, then i always need to cast to the proper type, consider this: CSymbol *find_symbol(...); CVar* sym = static_cast<CVar*>(find_symbol(...)); it could be also a CType symbol, a CFunction, etc... to solve this problem, i could use templates, like this template <class T> T* find_symbol(...) ... But then it is no longer guaranted, that a client uses CSymbol, he could also write int i = <int>find_symbol(...); Can you give me some suggestions to redesign my classes? What way should i go? Thanks in advance for any ideas, Gammstrahler
  7. My Own scripting language - design?

    Thanks for your answer, i want to go in a similar direction, currently my syntax is fully C-oriented (with the same limitations (no OOP)), but performs very fast. Another question i have is: How do you code your virtual machine? To have process the instructions and memory access very fast, i thought it would be a better idea to use good old C to implement the VM. However, this makes the library more inflexible when it comes to adding new features / opcodes, etc. What i want to prevent is a running loop like this: VM::Execute_Script(...) { for (each instr) { switch (instr.opcode) { case 0: case 1: ... } } or even worst, like this class INSTRUCTION { virtual void Execute() = 0; } class MOV_INSTR : public INSTRUCTION { virtual void Execute() { ... } } derived classes for other instructions follow VM::Execute_Script(...) { for (i = each in instr) { i->Execute(); // Call i´s virtual Execute method } } The third possibility, using Callbacks, is very fast: typedef void (*INSTR_CALLBACK)(SCRIPT &script); std::vector<INSTR_CALLBACK> _instrCallbacks; VM::Execute_Script(...) { for (i = each in instr) { _instrCallbacks[i->opcode](); // Call callback method } } But it has following disadvantage: I cannot directly access the memory, instruction, operand, etc void mov_callback(SCRIPT &script) { INSTR currInstr = script.instr(script.curr_index)); script.mem.move(currInstr.operand[0].value.i, currInstr.operand[0].value.i); script.curr_index++; } Can someone give me a few ideas of which method is most suitable for best performance in script execution? thanks Gammastrahler
  8. Hi, i want to completely redesign my existing scripting language (not the syntax and functionality), but the way it is coded. I want focus on execution speed, but i think this leads to a more C-like programming style which is not as maintable and flexible (especially if i want to easy add new features), as to use object oriented class programming where i encapsulate everything in a class. what would you suggest? any ideas are welcome thanks gammastrahler
  9. Problem with push_back on vector

    Quote:Original post by Palidine no. you're storing that offset in the array thusly: 10 total bytes allocate 1 byte push_back a struct with a .size = 9 allocate 1 byte push_back a struct with a .size = 8 allocate another byte iterate the list addr += 9 addr += 8 return _chunk + 17; note that the addr offset is horribly wrong note that _chunk + 17 is no where in your vector of memory because the pointer stored in _chunk has no relationship with the memory space of the vector -me I´m just using the vector for holding information about the size of the block, they have no relationship to the memory addressed by _chunk, neither physically nor logically :) the vector only keeps track of the number of blocks and the block sizes / as well as the status (used/unused) The problem is fixed now, it was the error detected by Enigma. Now it works :)
  10. Problem with push_back on vector

    @Palidine Thanks for your help. But i think my code is a little bit confusing due to the fact, that the variable named "freeBlock" is somewhat misleading. freeBlock is the "first fit" block that is greater than or equal to the bytes the user aquired, and freeblock is then marked as used, so it is no longer a freeblock but actual the block that is related to the allocated memory. And then, newBlock is created to store information of the remaining free bytes Lets say, i have a single free block of 100 byte, and the user aks me for 80 bytes, then i set this block´s size to 80 bytes, and create a new (free block) with 20 bytes in size.
  11. Problem with push_back on vector

    Here is the complete code Little explanation: The _blockList vector is separated from the actual memory block, as opposed to common implementations struct MEMBLOCK { size_t size : 31; bool used : 1; }; class ALLOCATOR { size_t _chunkSize; char* _chunk; std::vector<MEMBLOCK> _blockList; size_t _freeMem; public: ALLOCATOR(const size_t chunkSize) : _chunkSize(chunkSize) { MEMBLOCK block; block.size = chunkSize; block.used = false; _chunk = new char(chunkSize); _blockList.push_back(block); _freeMem = chunkSize; } void* allocate(const size_t bytes) { if (_chunkSize < bytes || bytes == 0) return NULL; MEMBLOCK *freeBlock = NULL; size_t addr = 0; for (std::vector<MEMBLOCK>::iterator pBlock = _blockList.begin(); pBlock != _blockList.end(); ++pBlock) { if (pBlock->size >= bytes && !pBlock->used) { freeBlock = &(*pBlock); break; } else addr += pBlock->size; } if (!freeBlock) return NULL; freeBlock->used = true; if (bytes < freeBlock->size) { MEMBLOCK newBlock; newBlock.size = freeBlock->size - bytes; newBlock.used = false; freeBlock->size = bytes; _blockList.push_back(newBlock); _freeMem -= bytes; } else { freeBlock->size = bytes; _freeMem -= bytes; } return (_chunk + addr); } } ALLOCATOR mem(1024); char* my_new_string(const char* str) { char* pDest =(char*)mem.allocate(strlen(str) + 1); strcpy(pDest, str); return pDest; } void main() { char* s1, *s2, *s3; std::cout << (s1 = my_new_string("HelloWorld!")) << std::endl; std::cout << (s2 = my_new_string("I´m going to bed now")) << std::endl; // When the third string is created, this causes push_back to crash in my allocator function std::cout << (s3 = my_new_string("Good morning, Mrs. Meyers")) << std::endl; }
  12. Hi, i have written a custom memory allocator, and i have a vector of memblocks for housekeeping. if i need to create a new block, i call push_back, but this crashes after creating some blocks! here is the relevant code if (bytes < freeBlock->size) { MEMBLOCK newBlock; newBlock.size = freeBlock->size - bytes; newBlock.used = false; freeBlock->size = bytes; _blockList.push_back(newBlock); // crashes!!!! _freeMem -= bytes; } is it because the newBlock variable is local? would be nice of anyone could help me with this problem...
  13. Hi, in OpenGL, i can easily pass a normal to a face, as well as a color, just by calling glNormal3f or glColor3f, but from what i have seen in D3D, you always need to specify a normal for each vertex separately, as well as a diffuse color. Is there a similar method to the one OpenGl uses? Thanks Gammastrahler
  14. OpenGL Low FPS with Direct3D

    Thanks, that´s it! :) The problem was indeed the presentation interval, now i have changed it to immediate, and i get 999 frames with FRAPS thanks Gammastrahler
  15. OpenGL Low FPS with Direct3D

    Here is the relevant D3D code: Almost all of the code is adopted from the texture D3D sample from the DirectX 9.0 Dec. SDK HRESULT InitD3D( HWND hWnd ) { if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) ) return E_FAIL; D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof(d3dpp) ); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) ) { return E_FAIL; } g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); return S_OK; } HRESULT InitGeometry() { if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "mytext.bmp", &g_pTexture ) ) return E_FAIL; g_pd3dDevice->SetTexture(0, g_pTexture); g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); g_pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); // Create the vertex buffer. if( FAILED( g_pd3dDevice->CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL ) ) ) { return E_FAIL; } CUSTOMVERTEX* pVertices; if( FAILED( g_pVB->Lock( 0, 0, (void**)&pVertices, 0 ) ) ) return E_FAIL; pVertices[0].position = D3DXVECTOR3(-1.0f, 1.0f,-1.0f); pVertices[0].color = 0xFFFFFF; pVertices[0].tu = 0.0; pVertices[0].tv = 0.0; pVertices[1].position = D3DXVECTOR3(1.0f, 1.0f,-1.0f); pVertices[1].color = 0xFFFFFF; pVertices[1].tu = 1.0; pVertices[1].tv = 0.0; pVertices[2].position = D3DXVECTOR3(-1.0f,-1.0f,-1.0f); pVertices[2].color = 0xFFFFFF; pVertices[2].tu = 0.0; pVertices[2].tv = 1.0; pVertices[3].position = D3DXVECTOR3(1.0f,-1.0f,-1.0f); pVertices[3].color = 0xFFFFFF; pVertices[3].tu = 1.0; pVertices[3].tv = 1.0; g_pVB->Unlock(); return S_OK; } VOID SetupMatrices() { D3DXMATRIXA16 matWorld; D3DXMatrixIdentity( &matWorld ); D3DXMatrixRotationX( &matWorld, timeGetTime()/1000.0f ); g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f ); D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f ); D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f ); D3DXMATRIXA16 matView; D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec ); g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView ); D3DXMATRIXA16 matProj; D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f ); g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); } VOID Render() { g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 ); if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) { SetupMatrices(); g_pd3dDevice->SetTexture( 0, g_pTexture ); g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) ); g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 ); g_pd3dDevice->EndScene(); } g_pd3dDevice->Present( NULL, NULL, NULL, NULL ); }