SFCBias

Members
  • Content count

    55
  • Joined

  • Last visited

Community Reputation

162 Neutral

About SFCBias

  • Rank
    Member
  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. A Shapians Tale

    [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. Resorting binary heaps

    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. Resorting binary heaps

    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. Help me choose an IDE for C++

    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. Help with planning my game engine?

    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. how to design football game?

    umm thats cool. Did you have a question or want to start a discussion?