Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


CombatWombat

Member Since 28 May 2000
Offline Last Active Yesterday, 02:17 PM

Topics I've Started

Yet Another Rendering Queue Thread

14 July 2014 - 04:51 PM

I've read everything I could find on these things, and I'm starting to implement this and questions are arising.  Sometimes I find typing all this out helps get my head in order...A lot of this might be duplicates of prior threads asked in a different way and much of it will be just plain hypotheticals...  Without further ado...

 

I am using SFML and want to sort by texture, and then by depth (really layer, since this is a 2d game). 

 

So.  I can store all the sf::Drawables in a vector (that gets filled by the scenegraph/culling/whatever system).

std::vector<sf::Drawable> allOpaqueDrawables;
std::vector<sf::Drawable> allAlphaDrawables;

Should these be pointers to the drawable which is instead stored in the game objects themselves? 

Should there be a master list of all drawables in the game that "owns" them, letting both the game object and these "sub-drawables-within-the-scene" use pointers to this master list?

Some other third option?

 

 

Now, I need to sort this.  So I can make a render queue which is just indicies into the vector of all drawables.

I'm not positive how to implement this... a first try might be something like:

std::map<sortKey, int16_t> renderQOpaque;
std::map<sortKey, int16_t> renderQAlpha;
// with sortkey being a POD integer type built from the texureID and layer value of the drawable

I guess the idea is that the small int16 keys are the only thing that needs to be copied around to sort the map?

 

1) Is this a sane way of doing this part?

2) Is std::map a reasonable choice for the implementation?

 

Then the map can be iterated through taking the int16_t as indicies into the vector allDrawables to call draw() on each one.

 

A few problems:

1) Where to store and generate the sortKey, if it needs to be stored at all?

       a) I need an integer representation of a texture.

       b) (At least part of) the sortKey needs to be updated if the objects layer (depth) changes.

 

My texture storage assigns a unique integer ID number and prevents duplicates from loading.  Does it make sense to actually store this value in the texture?  Right now it is only kept in the texture storage (as a std::map<texID, sf::Texture>).

I could inheret from sf::Texture and create a version that contains the texID.  Unnecessary?

 

SFML uses an sf::Drawable which contains the geometry to be drawn as well as the "rules" to draw it (actual draw() call).

It also uses an sf::RenderStates which holds...

1) *Texture

2) *Shader (if used)

3) *Transform

4) BlendType

 

Since this RenderState holds damn near everything I need to generate the sortKey, it almost sounds reasonable to create my own RenderStates which derives from sf::RenderStates so that I can contain the sortKey in it and regenerate the sortKey anytime one of those three items are changed.  Yea/Nay?

 

I realize most of this is just my thinking out-loud/rambling.  Any feedback is appreciated.

 

 

 


Object Composition and Getter/Setters

10 August 2013 - 07:40 AM

Say I have a class "Connection".

A connection knows how to Read and Write.  It also needs a buffer to Read Into.  So...

class Connection
{
protected:
Reader asyncReader;
Writer asyncWriter;
DataBuffer rawData;
}

Now, say "DataBuffer" has a member called "MaxElements" that defines how many entries are in there.

If I want to change this number of elements from outside, I would essentially be doing something silly like:

AConnection->SetDataBufferSize(size)
// which in turns ends up calling
rawData->SetBufferSize(size)

With deeper nested composition, I just end up with a giant chain of set/get methods (each of which could be a source of some bizarre bug).

 

Is there a better way?

Should Reader/Writer/DataBuffer *not* be members of the connection?  This gets tricky, because then a connection can be created without resources it needs to function.  Sounds bad.


Avoid the abstract templates

12 September 2012 - 05:08 PM

I'd like some feedback from more experienced folks on how they would implement the following (In C++)

I have a Least-Recently-Used Cache which is a template class. The data is type<T> and it is always keyed by unsigned int. It works as far as putting data in from outside, and retrieving it again (with a the proper bump in "used recently" status).

Now, when another service requests data from the cache, it is possible for the data to be missing. What should the cache do in this situation? It is not his responsibility to generate the data, only to store it. So the first option is the cache class can just throw some kind of NULL flag out instead of data and the outside world must take action to fill that data in. I really don't know how I would implement this solution. The second option is the cache should understand who to call upon to generate the data that is missing. This is the option that I started to implement, and then things went south.

I started by trying to do an abstract "DataGenerator" object, from which other specific generator objects would derive. This would let the cache keep one of these objects handy so it would know how to generate it's missing data.
So this DataGenerator would have some function like
[source lang="cpp"]typeOfDataToMake generate(int sourceID);[/source]
Ok, great. Now I want my derived classes to be required to implement this "generate" member to make their type. So there might be a MeshGenerator, a CharacterGenerator, and so on, each one required to generate his type of data.

So shouldnt the method in the base class be virtual to force implementation by the derived classes? But I cannot (and probably do not want) to make it both virtual and template, as that sounds a bit over my pay grade and/or not allowed at all. Yet, it must be a template, since the return type could be anything!

Am I way off base here?

Where & How to store resoures

01 September 2012 - 10:32 AM

I am in the process of breaking up my game into some states. I am (so far) trying something similar to the approach seen here:
http://gamedevgeek.c...me-states-in-c/, where each state inherets from an abstract state.
First off, is this generally considered to be an "abuse" of OOP, or is this a valid solution?

Now, for a given state's "draw" method to work, it needs to know *what* to draw. Hrm. So it needs resources like textures, geometry, strings, etc. So a naive option is for each state to own this data. This is a problem from a coupling perspective, as now "State" needs to include a gazillion headers to understand what all this data is. It is also a problem from a "single responsibility" perspective, as it is giving a lot of work to "State" (creating & owning all these resources). So this does not sound like a good solution.

Another option I think, is to have the resources loaded externally into some kind of resource pool, and then pass a pointer to the pool to the state that needs it. This seems ok, as now "State" only needs to know about this generic resource type and doesnt really care how it is implemented.
But that is where I am stuck.

So the big question:
How to implement a "holder" of many different types? The POOL can just be a std::vector<Resource>, where Resource is an abstract type, with each individual type of resource wrapped into an inhereted class. This seems absolutely bonkers for a variety of reasons. Or...give POOL a std::vector to each type of data that it can hold. Maybe a bit better, but still the list of types it could hold could be very long indeed.
Is there a less naive approach that is still understandable by a rank amatuer?

Thanks.

Rendering Architecture

12 September 2011 - 03:52 PM

I think this is more a software engineering type problem. I don't know how the overall structure of my rendering bits should function. I don't know that I even have a specific question to ask, but sometimes I find typing this nonsense out here will help me wrap my own head around it... so...

What is a good way to organize your drawing code. There are a few key bits I think of when I say "Drawing code".
1) There's the actual "draw" call.
2) There is setup before the draw call. Select the proper texture. Select the right shaders. Etc
3) There is *what* to draw. Model. Vertex Data. Index Buffers, etc.

One option is for game (Or UI, or particle, or whatever) objects to keep their own Render function. They could also know of their own model data, texture, etc. This does not lend itself to sorting and batching of draw calls. Additionally, it puts too much responsibility on the game objects. Should they *care* what their model is? Should they care about index buffers, etc. Should that not be delegated elsewhere?

So, I could do a centralized rendering function/object/whatever. Problem here, is that now it needs to know about all these object types in order to draw them. It needs their position, what texture to use, what render states to set, etc. Modularity is doomed here, I think.

Right now I have a combination of the two, which is a disaster waiting to happen. I am getting myself confused over where to keep my model data, when to load shaders, etc. How do I manage all of this? I'd like to fix it before I get further along.

So in summary, my question amounts to this:
Who is responsible for (possibly shared) items like model vertex data? My game consists almost entirely of square blocks. So many items share the same vertex buffer / index buffer, but use their own unique textures.
How do I create a rendering function/object/whatever that can draw without having to know the deepest intricate secrets of the objects it must draw?
Alternately, how can I do the above without the objects having to know the details of the rendering function?

I am using DirectX9 / C++, but I think this question is pretty generic.

PARTNERS