• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.


  • Content count

  • Joined

  • Last visited

Community Reputation

150 Neutral

About Gammastrahler

  • Rank
    Advanced Member
  1. Thank you for the detailed description :)
  2. 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. 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. @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. 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. 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. @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. 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

    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

    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 ); }