Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

From what I see, the position/matrix is stored in the BasicEffect instance, so it makes sense to me that every object has it's own position matrix, but I'm not 100% sure it's correct to let every Entity have it's own BasicEffect instance, so I'm asking here.

share|improve this question
add comment

3 Answers

up vote 2 down vote accepted

Probably not. But you could...

First of all, you'll note that BasicEffect in fact has 3 matrices: World, View, and Project. World is per-object. But view and project are per-camera - so these should not be duplicated in different places around your program (for reasons of maintainability).

Secondly: You should usually treat states that go onto the GPU as write-only. The upshot of this is that you generally store the information to generate those states (such as effect parameters) yourself - in your own classes. Then, for each object you draw, you generate the appropriate state and set it on the GPU and follow it up with a draw call.

So with a single, shared BasicEffect, what you'll usually do is set the projection matrix once at the start of your game. Then set the view matrix at the start of each frame. And then set the world matrix right before you draw each object.

But - there are scenarios where you might want an Effect for each object. For example: you might have completely different settings for different objects. But at the same time - you still don't want to waste GPU resources by having multiple copes of the same effect program in existence.

To solve this, use the Effect.Clone method (MSDN), which gives you a copy of the Effect object that shares the underlying GPU resources.

(Note, of course, that BasicEffect is an Effect.)

share|improve this answer
    
I see, so for classes that need the same View & Project, but a different World matrix, I just send these classes a cloned Effect, and before they are drawn, I set the world matrix that belongs to that class. –  ProgrammerAtWork Sep 14 '12 at 10:09
    
@ProgrammerAtWork Personally I recommend storing just the World matrix (or translation, rotation, etc required to create the world matrix) with your entities, and then setting it on a single, shared BasicEffect. But, yes, you could clone the effect and it would work (but then what will you do when the camera moves and you need to change the View matrix across so many effects? - kind of messy). –  Andrew Russell Sep 14 '12 at 13:05
2  
There are several things to consider here. 1. BasicEffects take up alot more memory than a simple matrix [World] or vector+quaternion [Pos+Rot], it's not very memory-efficient. Having 200 BasicShaders in your scene just because you have 200 entities is overkill. 2. Using a rendering specific resource just because it contains a datastructure you need instead of using the datastructure directly is a bad design choice. @ProgrammerAtWork It seems to me that you have reusability in mind but you are taking it a bit too far in this case. –  Aaron Kabashi Sep 14 '12 at 15:21
add comment

BasicEffect is shader program. So it is resource it must be single( to save memory etc). And parameters are passed same as in function.

share|improve this answer
    
I understand that textures/shaders are loaded once and then assigned to a BasicEffect, but does every entity get a BasicEffect instance? –  ProgrammerAtWork Sep 14 '12 at 9:38
    
not an instance but reference or pointer to that instantiated effect. –  bobenko Sep 14 '12 at 10:02
add comment

You have different WVP matrices for each object. But you can create a single BasicEffect instance to render all the objects. You just have to make sure that before rendering, you assign the correct matrices to the BasicEffect properties.

for every object
{
    basicEffect.World = obj[i].world;
    basicEffect.View = obj[i].view;
    basicEffect.Projection = obj[i].projection;
    GraphicsDevice.SetVertexBuffer(obj[i].vertexBuffer);
    foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
    {
        pass.Apply();
        GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
    }
}

Check this

share|improve this answer
    
I see. Do I also assign other things to a basiceffect, like different textures/shaders while looping? –  ProgrammerAtWork Sep 14 '12 at 9:42
    
Yes! you can assign –  Shashwat Sep 14 '12 at 9:46
    
Okay, I'll try this out when I get off work. –  ProgrammerAtWork Sep 14 '12 at 9:49
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.