Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

Options
Go to last post Go to first unread
Offline saviilsy  
#1 Posted : Sunday, September 4, 2011 1:29:18 PM(UTC)
saviilsy

Joined: 8/24/2011(UTC)
Posts: 95

Thanks: 6 times
Was thanked: 2 time(s) in 2 post(s)
Hi again,

I have been busy coding a extensible yet simple scene graph for DE, but I'm having bit of problems with the rendering principles of this engine.

First I would like to use the already made Camera classes of the engine to do the view/projection things, but I have literally no idea how the engine handles the rendering. I have tried to read the source and the help and got the impression that delta collects the rendering of every frame and at the beginning of the next frame it actually renders them.

Ok now I create a scenegraph with the node :

Code:

                SceneGraphNode root = new SceneGraphNode();
                SceneGraphNode a = new SceneGraphNodeBox(Color.Red);
                SceneGraphNode b = new SceneGraphNodeBox(Color.Green);
                root.Add(a);
                root.Add(b);
                a.LocalPosition = new Vector(0, 10, 0);
                b.LocalPosition = new Vector(-10, 0, 0);
                BaseCamera.Current = new LookAtCamera(new Vector(0, 0, 20), Vector.Zero);
                root.Update(true); // here the actual rendering happens


The SceneGraphNodeBox is just a basic box node for testing :
Code:

class SceneGraphNodeBox : SceneGraphNode
    {
        public Color Color
        {
            get;
            set;
        }

        public SceneGraphNodeBox(Color color)
        {
            this.Color = color;
        }

        public override void Render()
        {
            Box.DrawOutline(new Vector(-1, -1, -1), new Vector(1, 1, 1), this.Color);
        }
    }


Ok, now the SceneGraphNode it self renders the whole tree with the update(bool) method (names will change to render when i get this to work). The camera classes update the ViewProjection and ViewInverse so we don't need to worry about them, let the camera do it's stuff, just use the data collected. Now the rendering in the node.
Code:

// mWorldTransformation is the objects transformation in the world space, calculated and tested, it is correct
Matrix.Multiply(ref mWorldTransformation, ref Screen.ViewProjection3D, ref Screen.ViewProjection3D);
                        Render();

This is all very simple yet totally wrong, now the ViewProjection3D is a cumulative product of all the scenegraph nodes (ie. having more than one node will mess up the viewproj matrix). But this way there is something on the screen (granted the upvector get's messed up, but still, it renders stuff). However there is only ONE box in the screen but there should be two. If I comment either one of the nodes a or b, other shows up, the rendering is not done when It is asked, it only renders the last Box.DrawOutline method.

Now we can fix the cumulative effect on the update method simply by storing the last viewproj matrix and restoring it after the render :
Code:

// store old
Matrix old = Screen.ViewProjection3D;
// mWorldTransformation is the objects transformation in the world space, calculated and tested, it is correct
Matrix.Multiply(ref mWorldTransformation, ref Screen.ViewProjection3D, ref Screen.ViewProjection3D);
                        Render();
// restore old
Screen.ViewProjection3D = old;


But now there is abolutely nothing on screen!

DynamicModules (especially the camera) seem to reset their state on their run (when the proj/viewinv and updatescreen is called). But they do not remember the states when something is actually drawn. How can I manipulate the view matrices when drawing multiple stuff on screen to actually make the scenegraph work???

I tried to create custom cameras with no Run methods to prevent the state from being reset - yet this is all hacky and I possibly could make it work rewriting some code from cameras, this is all wrong as I would like to use the Camera classes from the engine. No need to rewrite the wheel right...

Another problem, when I make a Game class like in the examples the Game's Run method is never called - even the static constructor of my Game class is never called. What seems to be the problem here? I have to use the optionalRunCode delegate to test and draw stuff - the only way it works. I start the Game with Game.Start();

Edited by user Sunday, September 4, 2011 1:32:14 PM(UTC)  | Reason: Typos.

Wanna join the discussion?! Login to your forum accountregister a new account. Or Connect via Facebook Twitter Google

Offline Benjamin  
#2 Posted : Sunday, September 4, 2011 4:09:08 PM(UTC)
Benjamin

Medals: Admin

Joined: 8/20/2011(UTC)
Posts: 1,421
Location: Hannover

Thanks: 18 times
Was thanked: 97 time(s) in 92 post(s)
Can you zip up your project (just the .cs and .csproj files) and send it so I can take a look. What you are saying about Box.DrawOutline sounds very wrong that you only would see one box.

About the other issues with ViewProjection3D and not getting Update called I have to look at your code to make sense. If you want to have Run called automatically you can use the DynamicModule class as a parent. A game class is used in the Sample games, but not really required, it is not part of the Delta Engine. You can just have a delegate passed to Application.Start or you could even just use a bunch of DynamicModules and call Application.Start without anything.
Offline saviilsy  
#3 Posted : Sunday, September 4, 2011 7:27:22 PM(UTC)
saviilsy

Joined: 8/24/2011(UTC)
Posts: 95

Thanks: 6 times
Was thanked: 2 time(s) in 2 post(s)
Ok here is the test thingy in attached zip. A bit disclaimer that it is a work-in-progress Smile

Now it renders to boxes but totally the wrong way. I made a small couple of debug lines to be drawn to show where the boxes should be.
Red box's center should be where the red line ends, same with green. That is the result I'm trying to achieve but can't get the model view matrices (or in this case the combination of view/projection) to change accordingly to the position of the box in world space).

Granted, there could be a problem with my matrix math since it's been awhile when I have coded a scene graph from start.
File Attachment(s):
HierarchialTreeNodeTests.zip (6kb) downloaded 3 time(s).

You cannot view/download attachments. Try to login or register.
Offline saviilsy  
#4 Posted : Monday, September 5, 2011 6:58:02 AM(UTC)
saviilsy

Joined: 8/24/2011(UTC)
Posts: 95

Thanks: 6 times
Was thanked: 2 time(s) in 2 post(s)
Hmm, It could be that if I cannot manipulate model-view straight I could just wrap either Geometry and Material or Mesh and draw them with the additional matrix that in this case would be the mWouldTransformation. This could work right? However the downside would be that it would just support those constructs.

And how is the performance on Mesh.Draw(Matrix) or Material.Draw(Geometry,Matrix)?
Offline saviilsy  
#5 Posted : Monday, September 5, 2011 9:39:13 PM(UTC)
saviilsy

Joined: 8/24/2011(UTC)
Posts: 95

Thanks: 6 times
Was thanked: 2 time(s) in 2 post(s)
A bit more discoveries :

- Studied the engine and it seems that the key point where one can manipulate world matrices would be in the middle of rendering phase setting the world matrix in the Shader.Set3DMatrix(or similar). This is a no-go since we cannot directly get into middle of the rendering process. The solution is to use Meshes or Geometry and this is the correct way since it does not interfere with Cameras or rendering.

- Made the scene graph work with Meshes and Geometries, these both have draw(..., ref Matrix) so one can inject own world matrix where and how the model is drawn (would be nice to know if this affects performance though).

- GeometryHelper.CreateCube creates a weird cube (not a cube at all), only a crooked plane(could be a bug???). CreateSphere works correctly.

- How to create Shader via code and set it to the MaterialData ? MaterialData only consists the shader name not the shader object itself.

- How to create Material based on MaterialData? Material(MaterialData) constructor is internal only - why?

- I could not create a texture/diffuse shader, no matter how I tried (could be related to missing content manager). I wish there could be a programmable way to create Material, MaterialData and it's shader so we could use CustomMaterial.Draw(Geometry, ref Matrix).

- Do we have an orthogonal camera class? Would be nice to use the new scene graph on 2d things as well.

So I made progress though :)

When Cameras, Meshes and Geometries work perfectly I will release the code to the Scene Graph so anyone can hack it/useit/whatever. Oh that brings one more thing :

- When releasing stuff to extend Delta Engine, how the licensing goes, can one choose a license or is there a license the code mush comply to?
Offline Marcel  
#6 Posted : Tuesday, September 6, 2011 2:14:58 PM(UTC)
Marcel

Joined: 9/5/2011(UTC)
Posts: 2
Location: Hannover

Hi Santtu,

i looked at your code and as you already found out in your last post the rendering is always getting cached and then rendered out at once in the end.
So manipulating the render matrix, than calling render and resetting the matrix to the original has no effect on the "real" rendering.

As you already figured out the mesh drawing has a Matrix transformation in the Draw method.
For drawing primitives like lines, boxes etc. you have to transform your position vectors and then draw them with the new positions.
Offline Benjamin  
#7 Posted : Tuesday, September 6, 2011 2:45:19 PM(UTC)
Benjamin

Medals: Admin

Joined: 8/20/2011(UTC)
Posts: 1,421
Location: Hannover

Thanks: 18 times
Was thanked: 97 time(s) in 92 post(s)
Btw: If you want to change rendering to immediate mode (not recommended at all, performance will be horrible and none of our optimizations will work anymore), you can directly call the draw methods of each low level rendering class (Geometry and Shader mostly). You probably also have to break up some linking in the higher classes (Material mainly, which talks to the MaterialManager instead of rendering directly).

Another way to force rendering is just to call MaterialManager.Run(), which is used as a hack in some of the Render To Texture tests (because it does not work on its own in all cases, we will focus on advanced rendering in the upcoming months).

But obviously what you found out and what Marcel said makes more sense, just use the system as it is and you will enjoy all the performance benefits.

Edited by user Tuesday, September 6, 2011 2:45:59 PM(UTC)  | Reason: Not specified

Offline Benjamin  
#8 Posted : Tuesday, September 6, 2011 2:49:51 PM(UTC)
Benjamin

Medals: Admin

Joined: 8/20/2011(UTC)
Posts: 1,421
Location: Hannover

Thanks: 18 times
Was thanked: 97 time(s) in 92 post(s)
Originally Posted by: Santtu Syrjä Go to Quoted Post
- When releasing stuff to extend Delta Engine, how the licensing goes, can one choose a license or is there a license the code mush comply to?


The license is not yet announced, but it will probably be some BSD, MIT or very simple open source license (do whatever you want, just keep the copyright notes in there).

So if you want to have your code integrated you can either push it to the public repository (with our license, btw: branches are called forks on CodePlex) or you can host it own your own and let people just download or license it from you (with whatever license you want, you might want to get payed ^^).
Offline saviilsy  
#9 Posted : Tuesday, September 6, 2011 7:11:31 PM(UTC)
saviilsy

Joined: 8/24/2011(UTC)
Posts: 95

Thanks: 6 times
Was thanked: 2 time(s) in 2 post(s)
Hopefully the upcoming Model class also has draw with matrix in it :) (I'm counting on it).

Quote:

Btw: If you want to change rendering to immediate mode (not recommended at all, performance will be horrible and none of our optimizations will work anymore), you can directly call the draw methods of each low level rendering class (Geometry and Shader mostly). You probably also have to break up some linking in the higher classes (Material mainly, which talks to the MaterialManager instead of rendering directly).


Surely You mean other than Geometry? Mesh basically is just a wrapper for Material and Geometry - so it would not be different from drawing Geometry through Material than drawing a Mesh.

How about those Material questions - Why we cannot create them via code? The example code and the engine code shows us how, but they have internal access protection so we cannot use them. If

There is no way to create Material from MaterialData, constructor Material(MaterialData) is internal only.
There is no way to create Shader straight from Shader.Create(Flags), since it is protected (this would be better if it would be accessible so we need not to inherit Shader everytime when creating a Custom Shader (of course we could make shader wrapper that exposes the protected constructor).
There is no way to link an instance of Shader to MaterialData, it only consists name of the Shader, not the actual reference to object - it would be great to be able to link Shader objects to MaterialData.

I will post a picture of the bug with CreateCube and the code bringing that up - as soon as I can.
Offline Benjamin  
#10 Posted : Tuesday, September 6, 2011 8:02:33 PM(UTC)
Benjamin

Medals: Admin

Joined: 8/20/2011(UTC)
Posts: 1,421
Location: Hannover

Thanks: 18 times
Was thanked: 97 time(s) in 92 post(s)
Hi Santtu,

Mesh is just a Material and a Geometry, which is used in Models (list of meshes plus Animation data if needed). The thing is that to draw meshes material.Draw is used, which again passes everything to the MaterialManager (which optimizes everything as best as possible).

What do you mean with "We cannot create materials"? There are a bunch of tests on how to do this. You can not even load materials, you always need to create them either from loaded textures, from created textures or from render to texture targets. Check out the test MaterialTests.CreateTextureDynamically on how to dynamically create a texture and pass it to a material.

I just saw that all of the Material constructors are internal for some reason (have to check why, probably because it is only needed for low level stuff), but since the Material class is available in Delta.Rendering.Basics you can just change the constructors to public and use them (or become a friend of the assembly).

For Shaders it really makes not much sense to create them in code because they would never work on other platforms. Instead you would have to use the ShaderEditor, which allows you to create and drag around nodes and create optimized shaders this way. Of course you can also directly create OpenTKShaders with shader code, but then it would only work in OpenTK (or Xna for XnaShaders, etc.)

For the question about linking Shader to MaterialData, it does not make much sense. MaterialData is just a container class in the ContentSystem namespace. Shader is the actual loaded shader in the Graphics namespace (which is way above content classes). For linking Materials with Shaders, that is what all the constructors are for.

Thanks for your feedback, please post small code examples for more specific help so we can tell you how it should be done and it helps us improving our tutorials and tests.
thanks 1 user thanked Benjamin for this useful post.
saviilsy on 9/6/2011(UTC)
Offline saviilsy  
#11 Posted : Tuesday, September 6, 2011 9:47:06 PM(UTC)
saviilsy

Joined: 8/24/2011(UTC)
Posts: 95

Thanks: 6 times
Was thanked: 2 time(s) in 2 post(s)
Originally Posted by: Benjamin Nitschke Go to Quoted Post

Mesh is just a Material and a Geometry, which is used in Models (list of meshes plus Animation data if needed). The thing is that to draw meshes material.Draw is used, which again passes everything to the MaterialManager (which optimizes everything as best as possible).


Great, this is what I was going for, now my drawing methods won't hinder the engine. Does model class have Draw(ref Matrix) also?

Originally Posted by: Benjamin Nitschke Go to Quoted Post

What do you mean with "We cannot create materials"? There are a bunch of tests on how to do this. You can not even load materials, you always need to create them either from loaded textures, from created textures or from render to texture targets. Check out the test MaterialTests.CreateTextureDynamically on how to dynamically create a texture and pass it to a material.


I did not mean that, umm. When I want to create a material based on some shader and put it to geometry is this the way to do it? MaterialData is just a way to send data to shader am I right? The only Material class I could found for 3D meshes was the MaterialColored as Material(MaterialData) is internal.

Code:

MaterialData materialData = new MaterialData
{
  ShaderName = "TexturedShader3D",
  Ambient = Color.White, 
  DiffuseMapName = "",
};
Material material = new MaterialColored(materialData);
Shader shader = Shader.Create(materialData.ShaderName);
GeometryData = GeometryHelper.CreateCube(shader.VertexFormat, size, size, size, "SceneGraphNodeCube", 0, Color.White);


Originally Posted by: Benjamin Nitschke Go to Quoted Post

I just saw that all of the Material constructors are internal for some reason (have to check why, probably because it is only needed for low level stuff), but since the Material class is available in Delta.Rendering.Basics you can just change the constructors to public and use them (or become a friend of the assembly).


If You ask me, I prefer them to be public as I try to remain far away from making ANY changes to DE - this way I can be at least half sure they will work on the next version I pull from version control Smile

Originally Posted by: Benjamin Nitschke Go to Quoted Post

For Shaders it really makes not much sense to create them in code because they would never work on other platforms. Instead you would have to use the ShaderEditor, which allows you to create and drag around nodes and create optimized shaders this way. Of course you can also directly create OpenTKShaders with shader code, but then it would only work in OpenTK (or Xna for XnaShaders, etc.)


Ok now I get it, it makes sense now. The question rises though that when are we going to be able to use the shader editor Cool

Originally Posted by: Benjamin Nitschke Go to Quoted Post

Thanks for your feedback, please post small code examples for more specific help so we can tell you how it should be done and it helps us improving our tutorials and tests.


I will post some possible bug affecting code and some examples as soon as I get some time (damn day job).

Edited by user Tuesday, September 6, 2011 9:49:50 PM(UTC)  | Reason: Fixed quotes

Offline Benjamin  
#12 Posted : Tuesday, September 6, 2011 11:06:39 PM(UTC)
Benjamin

Medals: Admin

Joined: 8/20/2011(UTC)
Posts: 1,421
Location: Hannover

Thanks: 18 times
Was thanked: 97 time(s) in 92 post(s)
Hi Santtu,

Originally Posted by: Santtu Syrjä Go to Quoted Post
Great, this is what I was going for, now my drawing methods won't hinder the engine. Does model class have Draw(ref Matrix) also?


Yes, basically all rendering classes have some kind of Draw and usually some overloads to position them in 2D (points) or 3D (vectors and matrices).

Originally Posted by: Santtu Syrjä Go to Quoted Post

Originally Posted by: Benjamin Nitschke Go to Quoted Post

I just saw that all of the Material constructors are internal for some reason (have to check why, probably because it is only needed for low level stuff), but since the Material class is available in Delta.Rendering.Basics you can just change the constructors to public and use them (or become a friend of the assembly).


If You ask me, I prefer them to be public as I try to remain far away from making ANY changes to DE - this way I can be at least half sure they will work on the next version I pull from version control Smile


Yeah, I just changed them to public and we will rethink this for v0.9.0 (probably will stay public).

Originally Posted by: Santtu Syrjä Go to Quoted Post

Ok now I get it, it makes sense now. The question rises though that when are we going to be able to use the shader editor Cool

Well, there are two kinds of shader editors, we have a shader feature editor, which allows you to click together features (like I want diffuse map+normal map+fresnel) and it gives you a shader that works on all platforms. We have been using this since last year, but it is not very flexible because complex games and especially PC games want their own custom shaders. For that reason we have been working on a Shader Node Editor, which is planed to be released soon, but probably won't make it this month. Maybe our developer for it (Amer) can give you some more insight and post some early screenshots ^^

Thanks for all your feedback Smile
Rss Feed  Atom Feed
Users browsing this topic
OceanSpiders 2.0
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Powered by YAF.NET | YAF.NET © 2003-2023, Yet Another Forum.NET
This page was generated in 0.188 seconds.