Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


noodleBowl

Member Since 08 Sep 2013
Offline Last Active Today, 07:07 AM

Posts I've Made

In Topic: Design: Managers VS Single Entities

Yesterday, 05:14 PM

You don't need any sort of "end" method any more, the RenderSystem has all the draw calls requested as a big list of these RenderObject and all the logic to make sure they ordered and sequenced properly along with their appropriate API state changes is in there, in one place.


I think things are starting to click, but I do not understand this. How do I not have a end call for my batcher? or should I say what is its replacment?

Let assume my systems generate / fill a struct that describes a render command (information about a batch of sprites or a emitter's particles) just like the one you have mentioned above. And that the RenderSystem is the only thing responsible for carrying out the commands required by the GPU. For the particle emitter this is simple, everything is formulated in one call. But for the sprite batcher everything is formulated over several calls. A batch only finished when the End call or when the current buffer is full, where a new buffer is filled / a new batch is started.

How could the RenderSystem know that a batch of sprites is officially done? This is more in regards to the "final" batch. Not one that is flagged as complete by a "buffer is full" or "texture change" trigger

In Topic: Design: Managers VS Single Entities

24 April 2015 - 04:52 PM

A "batch" is a "renderable." Geometry, associated textures, flags (et cetera). A sprite batcher produces n renderables. 

A "renderable" has buffers (VBOs, TBOs), properties (uniforms) and shaders..


I see this differently, maybe I have thinking of this concept wrong, to me a renderable is a object such as a Quad.
Just the data that would be in a VBO (The XYZ positions, Texture Coords, assigned texture, etc), the VBO is just the medium to get it to the GPU

 

Maybe this is cause my focus is 2D
 

It's not going to be possible to give you further advice without more specifics about what you find so different between these two things.

 

I hope this will explain things better

 

For an instance of SpriteBatcher they have:

Renders Quads. Single vertex Data is:

XYZ position

UV tex cords

 

Single VAO:

Contains a VBO and IBO

 

Single Shader Program:

Contains a Vertex Shader and  Fragment Shader

 

The VBO is filled using Draw methods that map directly into the buffer. Vertices are pre transformed

 

Drawing [When a batch's end has been signaled using the End() method or forced (ran out of space) through the VBO space check)]:

Bind the shader program

Bind the batch's texture

upload uniforms (MVP matrix / texture)

Bind the VAO

True draw call that uses the IBO to render all the data that was placed in the VBO

 

 

For an instance of Particle Emitter they have:

Renders quads transformed from point data. TBO Data:

XY position

XY acceleration

XY Velocity...

all use vec2 in shaders. 8 vec2s total

 

Two VAOs

VAO 1: contains only a TBO

VAO 2: contains only a IBO

 

Two Shader Programs.

Shader Program 1 (used for updating particles):

Contains a Vertex Shader and Geometry Shader

 

Shader Program 2 (used for rendering particles):

Contains a Vertex Shader and Fragment Shader

 

Pertains to Updating [thought I would include just in case]:

TBOs are initial given one "generator" particle. This particle created more particles based on uniforms that are used to describe the properties a particle can have (velocity, acceleration, etc). Particles are generated over time in the Geo shader, where they are also discarded if they are "dead". The vertex shader is the one that actually updates the positions etc

 

Pertains to Rendering [Explicitly done through a DrawParticles call]:

Bind Shader Program 2 (render program)

upload uniforms (MVP matrix / texture for particles / bind texture for TBO use)

Bind VAO 2 (one with IBO only)

True draw call that uses the IBO. Magic happens in the Vertex Shader where the TBO is iterated over to take each Point Data (single vertex and its data that makes up the particle) and expand it into a quad. Number of particles is based on the actual number of point data in the TBO

 

If you have any questions let me know 


In Topic: Design: Managers VS Single Entities

24 April 2015 - 01:47 PM

I think, you did not understand he wants you to ditch the idea of a huge RenderSystem with dependencies on "everything", make the most basic one by avoiding it having any dependence on game objects and just take simple structures, which are still descriptive enough to render everything, as they contain only low-level data.
Then you can have any number of independent higher level systems, which only know of one type of game object and the RenderSystem interface and do the job of translating the data into the mentioned simple structures and feeding it into the RenderSystem.

 

In the approach I am describing, you have OpenGL or D3D at the bottom of the stack. On top of that is the "RenderSystem," which abstracts away those APIs allowing you to speak in terms of "draw this geometry with these flags at the correct time." On top of that you build the highest-level visualizers for transforming you logical game data (tile maps, sprites, particle emitters) into appropriate commands or objects for the RenderSystem to consume.


I do understand what Josh means, but I think the thing that is tripping me up is the way I currently have it VS the way I should have it.

 

The "Render System" Josh describes actually truly is my sprite batcher, it handles all my intended render calls for my sprites, tiles, etc.

But here is where the issue, the trip up I have, comes into play. Its that the system I wanted afterwards, my particle emitter, have been built on a whole different way of rendering.

It so drastically different that it did not/does not make sense to make it apart of my sprite batcher.

 

 

The reason these systems are so different / hard to fit together is what everything is when its boiled down.

The sprite batcher takes vertex data, manipulates it, fills a VBO, then if the batch needs to end because of a texture swap or we ran out of space then it is and new batch is started. Then you have my emitters, these are full on GPU emitters. In a nutshell, they get configured once on creation and you let them go. The GPU handles everything: it is responsible for creating new particles, killing particles, etc. The "renderable object" in turn gets handled internally by the hardware.

 

The two systems have very different vertex data footprints and ways of rendering. The batcher has its "normal" use of VBOs / a few uniforms and makes quads; where the emitter uses TBOs filled with point / particle property data, then the emitter's vertex shader "expands them" into quads.

 

That is why I am falling apart here :(

I can't make sense of having something that already handles itself and forcing it to be handled by something else that really does nothing for it


In Topic: Design: Managers VS Single Entities

23 April 2015 - 07:14 PM

No, more like a "RenderSystem" object that methods to "enqueue" and "flush" objects of type "Renderable." A renderable object is a simple structure (not the base of some class hierarchy) that has references to geometry (vertex and index data), textures, shaders, and whatever other metadata you need to render (such as some flags to indicate sort order requirements, and so on). The render system simply enqueues these, sorting them as appropriate based on the data, and flushes them when needed (or demanded). This puts all the logic for dealing with batching, sorting, et cetera in one place. 

 

Higher-level systems (like a "particle visualizer") are built on top of that medium-level system. The ParticleVisualizer interface can take a *logical* particle system description and produce the appropriate renderable instance or instances, which can then be fed to the RenderSystem.

 

This sounds a lot like my sprite batcher in a sense. It takes in the all my data, manipulates it, gets it all ready for the render pipe, and etc. The only unfit puzzle piece is my emitters, since I created them with a dramatically different rendering method in mind. I guess its just a matter of fusing them together / building a system that can handle them both properly

 

Leaving me with a few questions, but mainly does this mean my "render system" is going to be tightly coupled to my current rendering objects or any future one's I create? Or am I missing the point here? And that I should be rewriting my current systems into one giant one instead of trying to keep them separated?

 

The way I see it is that my render system is the highest level and the subsystems (sprite batchers, emitter, light, etc) are the medium level. Maybe I'm thinking of this wrong?


In Topic: Design: Managers VS Single Entities

23 April 2015 - 04:26 PM

having a renderer interface responsible for properly sequencing all draw requests is a pretty common pattern.


Are we talking about a literal interface here that each "sub system" implements?
Or are we talking about some kind of larger "render system object", it has where all the "sub systems" as members and then we have wrapper functions?

EG Something like:


class RenderSystem
{

    public:
    DrawSprite(const Sprite &sprite, float posX, float posY);
    DrawParticles(const ParticleEmitter &emitter, float posX, float posY);

    private:
    SpriteBatcher batcher;
    bool pipeHasItems;

    /* Other members */
};

//=====================================================================================

void RenderSYstem::DrawSprite(const Sprite &sprite, float posX, float posY)
{  
    if(pipeHasItems)
       FlushRenderPipe();

    pipeHasItems = true;
    batcher.Draw(sprite, posX, posY);
}


/* Similar method for particle emitter */

/* -- Other render systems methods -- */


PARTNERS