• 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

162 Neutral

About SFCBias

  • Rank
  1. Sponji and mhagain are right, that was my question and thank you for your answers. As well as marcClintDion, thank you for your descriptive answer, and references(!).  This was more of a simply a conceptual question since I noticed it could work both ways.
  2. After writing some code to load a 3ds mesh (using lib3ds) I found that rendering using indices caused problems, at least for me. After storing all the vertex data into one array. I divide each lib3dsMesh into my own Submesh subclass which stores index data.   My question is what are (if any) the performance differences in storing index data in an array and using it to call glDrawElements:   GLuint* indices; void draw() { ... glDrawElements(GL_TRIANGLES, submesh.i_data.size(), GL_UNSIGNED_SHORT, &indices[0]); ... }     And using a BufferObject to store them   GLuint* indices; ...Fill array... void build() { glGenBuffers(1,&ibo); ...Fill buffer... } void draw() { glBindBuffer(GL_ELEMENT_ARRAY,...); ... glDrawElements(GL_TRIANGLES, submesh.i_data.size(), GL_UNSIGNED_SHORT, <submesh offset>); ... }      
  3. I mean why explicitly use nothrow only to ultimately end up replicating the throw behaviour? The return is also pointless since it can never be reached.   I'm aware of this, thank you. This also wasn't what my post was about, the code originally had other behavior but in the interim of deciding how to refactor the code, I changed it (rather than deleting it and letting new throw the exception). As I said in the OP, it's a learning exercise, so if you have nothing worth while to contribute, please don't.   @Khatharr, Thank you for your suggestions, I actually wrote this a long time ago and didn't understand what I was doing( to an even greater extent than I do now xD). I'll try you suggestions and see where they take me. If I run into any problems I can't fix on my own, I'll find myself right back here in the forum.
  4.     You must have edited this out, but I looked into it and finally made sense of it. After looking it over, I realized that this line of code was going back 8 bytes from 'ptr' but my real intention was to basically subtract 8 [ sizeof (MemChunk* )* 2 ] from the actual address of the pointer. I _think_ I accomplished that, like this. MemChunk *pCurChunk = (MemChunk*) reinterpret_cast<char*>(reinterpret_cast<ptrdiff_t>(ptr) - static_cast<ptrdiff_t>(sizeof(MemChunk*) * 2));   Whether this fixed my problem is still yet to be tested extensively, but it passed the quick test I put together for it.   I also took your advice and added a data member to the MemChunk struct which does allow me to use an array index, making things a lot more readable.    Lastly, I realized that the addresses from mFirst to mLast were descending, which was the opposite of what I wanted it to do (which accounts for the weird subtraction in the getPtr() function). To fix that, I made the loop that links the nodes together run backwards (from mMaxSize to 0). That allowed me to directly access the memory in the getPtr function the way I intended.
  5. destroy is defined in AllocBase, it simply calls the destructor of the object,   and yes the dealloc call is triggering the segfault, although it will work for a variable amount of times before causing a crash.
  6. As a learning exercise I wrote my own version of several STL components, this allocator generally works however while I was testing particles with it, it crashes after a variable number of iterations with alloc's and dealloc's . I've been playing with the code for ours and I'm sure there's something I'm doing wrong. Perhaps someone can point it out to me.   During the loop, I save the address of particles that will need to be dealloc'd in a vector, then later dealloc the pointers.   The problem always occurs with a segfault at ln. 76 and happens because the MemChunk's pointers point to memory that looks like it should be NULL but is something like 0x1, 0x5, etc.     This is the allocator's code template<class T = void> class PoolAllocator: public AllocBase<T> { public: typedef typename AllocBase<T>::AllocType AllocType; typedef typename AllocBase<T>::AllocTypePtr AllocTypePtr; PoolAllocator(size_t sizeInUnits = 1024) : mMemory(NULL), mUsedSize(0), mMaxSize(sizeInUnits), mOffset( sizeof(MemChunk) + sizeof(T)) { mMemory = new (std::nothrow) char[mMaxSize * mOffset]; // mMemory = malloc(mMaxSize * mOffset); if (!mMemory) { //Do something more informational here throw std::bad_alloc(); return; } for (size_t i = 0; i < mMaxSize; i++) { MemChunk *pCurUnit = (MemChunk *) ((char *) mMemory + i * mOffset); pCurUnit->mPrevChunk = mFreeList.mLast; pCurUnit->mNextChunk = NULL; if (mFreeList.mLast) mFreeList.mLast->mNextChunk = pCurUnit; mFreeList.mLast = pCurUnit; if (!mFreeList.mFirst) mFreeList.mFirst = pCurUnit; } } virtual ~PoolAllocator() { delete[] mMemory; } template<typename T1> struct rebind { typedef PoolAllocator<T1> other; }; struct MemChunk { MemChunk* mNextChunk, *mPrevChunk; }; struct ChunkList { ChunkList() : mFirst(0), mLast(0) { } MemChunk* mFirst, *mLast; }; virtual AllocTypePtr allocate(size_t n, const AllocTypePtr = 0) { if ((mUsedSize + n) > (mMaxSize)) _resize((mUsedSize * mOffset) + (mOffset * n) * 2); //Get the last chunk of unused memory MemChunk* pCurChunk = mFreeList.mLast; if (mFreeList.mFirst == pCurChunk) mFreeList.mFirst = pCurChunk->mNextChunk; //This shouldn't happen, since it's the back of the free list if (pCurChunk->mNextChunk) pCurChunk->mNextChunk->mPrevChunk = pCurChunk->mPrevChunk; //This should only _not_ happen if this is the last available piece of memory //When it does, the value of pCurChunk->mNextChunk should be NULL if (pCurChunk->mPrevChunk) pCurChunk->mPrevChunk->mNextChunk = NULL; //Set the new value of the last chunk in the free list mFreeList.mLast = pCurChunk->mPrevChunk; //Place it at the end of the AllocList pCurChunk->mPrevChunk = mAllocList.mLast; pCurChunk->mNextChunk = NULL; if (mAllocList.mLast) mAllocList.mLast->mNextChunk = pCurChunk; mAllocList.mLast = pCurChunk; if (!mAllocList.mFirst) mAllocList.mFirst = pCurChunk; mUsedSize += 1; return reinterpret_cast<AllocTypePtr>((reinterpret_cast<char*>(pCurChunk) + sizeof(MemChunk))); } //Returns a pointer to the memory at a specific offset. Do NOT modify this pointer inline const AllocTypePtr getPtr(unsigned i) const { return reinterpret_cast<AllocTypePtr>(reinterpret_cast<char*>(mAllocList.mFirst) - (mOffset * i) + sizeof(MemChunk)); } virtual void dealloc(AllocTypePtr ptr, size_t = 0) { MemChunk *pCurChunk = (MemChunk*) ((char*) ptr - sizeof(MemChunk)); std::cout << pCurChunk << "\n"; //Remove the chunk from the AllocList if (pCurChunk->mNextChunk) pCurChunk->mNextChunk->mPrevChunk = pCurChunk->mPrevChunk; if (pCurChunk->mPrevChunk) pCurChunk->mPrevChunk->mNextChunk = pCurChunk->mNextChunk; if (mAllocList.mLast == pCurChunk) mAllocList.mLast = pCurChunk->mPrevChunk; if (mAllocList.mFirst == pCurChunk) mAllocList.mFirst = pCurChunk->mNextChunk; //Put it back on the FreeList pCurChunk->mPrevChunk = mFreeList.mLast; pCurChunk->mNextChunk = NULL; if (mFreeList.mLast) mFreeList.mLast->mNextChunk = pCurChunk; mFreeList.mLast = pCurChunk; if (!mFreeList.mFirst) mFreeList.mFirst = pCurChunk; mUsedSize -= 1; } protected: /* * NOTE: This is a slow operation and can be avoided by preallocating enough memory * to hold your data. */ void _resize(unsigned size) { //Simple array reallocation size_t newSize = size; char* newArr = new (std::nothrow) char[newSize * mOffset]; for (unsigned counter = 0; counter < mUsedSize; ++counter) newArr[counter] = mMemory[counter]; //memcpy(newArr, mMemory, mMaxSize * mOffset); mMaxSize = newSize; delete[] mMemory; mMemory = newArr; //Relink the list for (size_t i = 0; i < mMaxSize; i++) { MemChunk *pCurUnit = (MemChunk *) ((char *) mMemory + i * mOffset); pCurUnit->mPrevChunk = mFreeList.mLast; pCurUnit->mNextChunk = NULL; if (mFreeList.mLast) mFreeList.mLast->mNextChunk = pCurUnit; mFreeList.mLast = pCurUnit; if (!mFreeList.mFirst) mFreeList.mFirst = pCurUnit; } } protected: char* mMemory; //The big chunk of allocated memory from the OS ChunkList mFreeList; ChunkList mAllocList; size_t mUsedSize; //current used size in chunks size_t mMaxSize; //peak size in chunks size_t mOffset; //The total step in memory from one chunk to another (also equal to the sizeof(MemChunk) + sizeof(T)) };   Here is the loop for (unsigned i = 0; i < mNumParticles; i++) { // Check particle's lifespan //Particle* pTemp = reinterpret_cast<Particle*>(mBuffer) + i; Particle* pTemp = mAllocator.getPtr(i); if (pTemp->m_Life-- < 0) { //Keep up with the particles to delete m_ParticleList.push_back(pTemp); continue; } // Update particle's position pTemp->m_Position.fX += pTemp->m_Velocity.fX; pTemp->m_Position.fY += pTemp->m_Velocity.fY; glColor3f(float(pTemp->m_Colour.r) / 255, float(pTemp->m_Colour.g) / 255, float(pTemp->m_Colour.b) / 255); glVertex2fv(pTemp->m_Position.ptr()); } bool clear = false; for (unsigned i = 0; i < m_ParticleList.size(); i++) { Particle* p = m_ParticleList[i]; mAllocator.destroy(p); mAllocator.dealloc(p); mNumParticles--; clear = true; } if (clear) m_ParticleList.clear(); // If there are less particles than the maximum allowed create another if (mNumParticles < m_MaxParticles) createParticles(m_MaxParticles - mNumParticles); the createParticles method calls allocate.
  7. [quote name='LennyLen' timestamp='1332654492' post='4925047'] I don't feel like going to another site just to see a screenshot. [/quote] Here you are. I'll grab more when I can. [img]http://img17.imageshack.us/img17/9778/screenshotat20120325184.png [/img][img]http://img823.imageshack.us/img823/9778/screenshotat20120325184.png[/img][img] http://img15.imageshack.us/img15/9778/screenshotat20120325184.png [/img] [img]http://i.imgur.com/25rOi.png[/img]
  8. Because i'm not directly modifiying the element from the heap. After i pop the root element which is a node, i modify one of it's neighbors which i don't know the index of within the heap.
  9. Woops, sorry. I'm using C++ and I wrote the heap class myself. I actually came across a method of doing what i was looking for and implemented it this morning. [code]void heapify(int pos = 1) { assert(pos > 0 && pos <= mNumItems); T _parent = mHeap[pos]; int leftPos = int(pos * 2); int rightPos = int(pos * 2) + 1; T _left = mHeap[leftPos]; T _right = mHeap[rightPos]; int smallestPos = pos; T _smallest = _parent; if (leftPos <= mNumItems && compare(_left, _parent)) { _smallest = _left; smallestPos = leftPos; } if (rightPos <= mNumItems && compare(_right, _smallest)) { _smallest = _right; smallestPos = rightPos; } if (smallestPos != pos) { mHeap[pos] = mHeap[smallestPos]; mHeap[smallestPos] = _parent; heapify(smallestPos); } } [/code]
  10. I have a minimum ordered binary heap. (I'm using A* pathfinding) at one point or another I come to a point where I must modify a node that may or may not be the top or bottom of the tree. How would I go about resorting the entire array (since, I don't know the exact position within the heap of the node i modified)?
  11. I use Eclipse's C++ IDE on my Linux box and its been the best to me so far. It has alot of plugins that make working easier (including SVN/CVS manager for collaboration). SO If your looking at Linux I definitely recommend Eclipse. For Windows (I too am anti-Microsoft) hands down its Visual Studio.
  12. The hierarchy sounds good. It's alot of preference involved in what should come first. But the as a general rule, try to make your code as generalized as possible,that way even if you change your structure, it shouldn't be alot of work simply plugging in some data into a function etc. So my suggestion is to start out with base classes that will contain a combination of basic operations. Then when you specialize this class, they will all have a common feature.
  13. Theoretically speaking (as im not a java programmer) i think you would make a loop that goes through each element in your first array and get a usable object out of it. Then inside that loop go through each of the elements inside the second array and check the intersection between them. Heres some pseudo if its understandable: [code] For each element in array1; Extract element i from the array; For each element in array2; Extract element j from the array; Do intersection checks against the two objects; End Loop End Loop [/code] In C++ it would look something like this (You may be able to convert) [code]for(int i = 0; i < NumberOfElementsInArray1; i++) { ElementType Object1 = Array1[i]; for(int j = 0; j < NumberOfElementsInArray2;j++) { ElementType Object2 = Array2[j]; if(Object1 intersects Object2) { React_to_collision(); } } } [/code]
  14. You could position the perspective so that you cant see any depth to the object. and/or you could shade it with only diffuse lighting.
  15. umm thats cool. Did you have a question or want to start a discussion?