Sign in to follow this  
Kasya

Game Design advice?

Recommended Posts

Kasya    207
Hello, Finally, I have started creating a game. I need some advice about the game design: There are Hardware Components (Buffer, Texture, Shader), Resources (Mesh, Skeleton), RenderObjects (Skeleton Instance, Mesh Instance), Managers (TextureManager, ShaderManager, BufferManager) and Renderer. Texture and Shader are also Resources (so they are loaded only once but used many times). The Managers loads or creates the components or resources and store SOME of the components in a list ( e.g TextureManager::TextureList, ShaderManager::ShaderList ) to not load the same resources more than once but use the existing ones. Hardware Components activate themselves during rendering. The Renderer renders the RenderObjects: Here is how i think to use Renderer:

void MeshInstance::Bind() {

 updateBones();
 texture->Bind();
 shader->Bind();
 shader->setMatrix(boneMatrix);
 vertexbuffer->Bind();
 indexbuffer->Bind();

}

void MeshInstance::Unbind() {

 indexbuffer->Unbind();
 vertexbuffer->Unbind();
 shader->Unbind();
 texture->Unbind();

}

void Renderer::Render(RenderObject * obj) {

 obj->Bind();
 hardware->Draw(Hardware::TRIANGLES, obj->getIndexCount());
 obj->Unbind();

}







* NOTE: Most of the game components have not been finished. Thanks, Kasya

Share this post


Link to post
Share on other sites
jyk    2094
What exactly are you looking for advice on? (I didn't see a specific question in your post anywhere.)

Share this post


Link to post
Share on other sites
bzroom    647
Sure, that's a completely plausible solution. But you've left out an important part. How you draw multiple objects, and how you optimize that.

Oh yea, and multiple viewports/cameras, lights, special passes, and multi-threading come to mind.

I'll supplement that with, i heard OGRE is usable.

Share this post


Link to post
Share on other sites
Kasya    207
@bzroom:

For multiple objects I think something like that:


class World {
public:
List<RenderObject *> objects;
Map<String, Camera *> cameras;
List<LightSource *> lights;

Renderer * renderer;
void Render();

};

void World::Render() {

renderer->RenderLights(lights);
activateCamera(cameras["CameraWhichIsAttachedToPlayerCharacter"]);

for(uint i = 0; i < objects.size(); ++i)
renderer->Draw(objects[i]);

}




For multi-threading: thats not a major concern for me right now because i need to finish some core issues like collision, animation right now.


I have one more question to ask. Its actually a programming question rather than design but anyways:

I am using virtual methods to activate Hardware Components (Buffer, Texture, Shader). As far as I know, the virtual table will be updated for every newly created component. Is it a good approach to call "Bind"s from Managers (which are created only once) rather than from components itself to lessen the amount of components in "virtual memory" like that:



void MeshInstance::Bind() {

updateBones();
TextureManager::getInstance().BindTexture(texture);
ShaderManager::getInstance().BindShader(shader);
ShaderManager::getInstance().SetMatrixParam(shader, boneMatrix);
BufferManager::getInstance().BindVertexBuffer(vbo);
BufferManager::getInstance().BindIndexBuffer(ibo);

}

void MeshInstance::Unbind() {

BufferManager::getInstance().UnbindIndexBuffer(ibo);
BufferManager::getInstance().UnbindVertexBuffer(vbo);
ShaderManager::getInstance().UnbindShader(shader);
TextureManager::getInstance().UnbindTexture(texture);

}

void Renderer::Draw(RenderObject * obj) {

Renderer::Bind(obj);
hardware->Draw(Hardware::TRIANGLES, obj->getIndexCount());
Renderer::Unbind(obj);

}




Thanks,
Kasya

Share this post


Link to post
Share on other sites
Lord_Evil    680
Well, that would be an improvement, but you could still do better.

Consider, for example, the following discussion: http://www.gamedev.net/community/forums/topic.asp?topic_id=560855

There are several comments and links that suggest not calling Draw() for one object but for all objects of a sepcific type. (Read the discussion for the reasons.)


Additionally you might consider using smart pointers or another referencing system instead of raw pointers, mostly for safety reasons.

Share this post


Link to post
Share on other sites
JustChris    150
I keep a collection of the assets I wish to use in a SceneCollection object. It shares some similarities to your World class:



class SceneCollection {

std::map<std::string, Renderable> RenderableGroup;
std::map<std::string, GeometryResource> GeometryGroup;
std::map<std::string, TextureResource> TextureGroup;
}

class SceneRenderer {

public:
void render(SceneCollection &Collection);
void setCamera(CameraView &View);
}




This is not the entire collection of members of each class, but you get the idea.

Each Renderable has a pointer to GeometryResource (containing vertex/index buffers) and a TextureResource. The SceneCollection is an implementation of a pool of shared resources that Renderables can pick from and use without loading the same content multiple times.

Each Renderable is a complete object with the resources needed to display on the screen. If you're wondering where the transformation matrix is, it's inside of a Renderable as a separate copy. In practical use I haven't really found a situation where I wanted to render two things with the same rotation, scaling and translation.

But Instead of calling your World to render its objects by passing a Renderer object, I think it would make more sense to have the Renderer take the World object as a parameter and render its objects from there. The World should just be about being a container for your objects, and ways to access and iterate through them.

That's why in my implementation I name the class a SceneCollection. I use the analogy that media formats and media players are in essence very different things, and one must use a DVD player to play DVDs, etc. A DVD wouldn't project pictures onto a screen by itself. Likewise, the World object shouldn't render itself. That would give it too much to do. It would make more sense to have a WorldRenderer that you can "insert" a World into and "play" it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this