0

I am trying to sort my renderables/actors correctly and noticed that I have some troubles with walls since they get sorted by their centerpoint. So I am sorting all my actors before I draw them depending on their distance to the camera with an insertion sort. After that, I am trying to determine if the wall should be drawn behind or in front of the gamefield. To explain this, the game takes place inside of a cube which is out of 6 planes. Since I can rotate the camera around that cube I need a sorting which would put the planes in front/back depending on that. So here is a picture so you know what we are talking about:

enter image description here

You can clearly see the rendermisstake whats happening at the front of those kind of snake.

Okay here is my current sorting:

//list of Actors the abstract class which Wall and cube and so on extend
void Group::insertionSort(vector<Actor *> &actors)
{
    int j;

    for (int i = 1; i < actors.size(); i++)
    {
        Actor *val = actors[i];
        j = i - 1;

        while (j >= 0 && distanceToCamera(*actors[j]) < distanceToCamera(*val))
        {
            actors[j + 1] = actors[j];
            j = j - 1;
        }
        actors[j + 1] = val;
    }
}

float Group::distanceToCamera(Actor &a)
{
    float result = 0;
    XMVECTOR posActor = XMLoadFloat3(&a.getPosition()); //here i get the centerpoint of the object
    XMVECTOR posCamera = XMLoadFloat3(&m_camera->getPosition());
    XMVECTOR length = XMVector3Length(posCamera - posActor);
    XMStoreFloat(&result, length);
    return result;
}

To determine if it's a Wall I used kind like this dynamic_cast<Wall*>(val) but I don't get them in front/back of the vector depending on that. To remember the objects return their centerpoint. Can anyone lead me to the right way?

Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55
bemeyer
  • 6,154
  • 4
  • 36
  • 86
  • If you use the depth buffer, it won't matter the order you draw? – Will May 24 '14 at 14:27
  • Just to verify, the issue is that the lines of the grid that forms the cube are hidden by something inside the cube at the bottom, right? – Ulrich Eckhardt May 24 '14 at 14:28
  • yea right. And no if i use a depthbuffer it just works for a single object not for the whole scene or i do something definite wrong. and i use a depth stencil view – bemeyer May 24 '14 at 14:30
  • @UlrichEckhardt Yes it is that issue because i sort them by their centerpoint and i am a bit confused how to solve it somehow practically since the view meight change by changing the camera position. – bemeyer May 25 '14 at 09:49

1 Answers1

1

It's difficult to answer your question because it is a complex system which you haven't fully explained here and which you should also reduce to something simpler before posting. Chances are that you would find a fix yourself on the way. Anyway, I'll do some guessing...

Now, the first thing I'd fix is the sorting algorithm. Without analysing it in depth whether it works correctly in all cases or not, I'd throw it out and use std::sort(), which is both efficient and very unlikely to contain errors.

While replacing it, you need to think about the ordering between two rendered objects carefully: The question is when exactly does one object need to be drawn before the other? You are using the distance of the center point to the camera. I'm not sure if you are sorting 2D objects or 3D objects, but in both cases it's easy to come up with examples where this doesn't work! For example, a large square that doesn't directly face the camera could cover up a smaller one, even if the smaller square's center is closer. Another problem is when two objects intersect. Similarly for 3D objects, if they have different sizes or intersect then your algorithm doesn't work. If your objects all have the same size and they can't intersect, you should be fine though.

Still, and here I suspect one problem, it could be that a surface of an object and a surface of the cube grid have exactly the same position. One approach is that you shrink the objects slightly or enlarge the outside grid, so that the order is always clear. This would also work around an issue that you suffer from floating point rounding errors. Due to these, two objects that don't have an order mathematically could end up in different positions depending on the circumstances. This can manifest as them flickering between visible to covered depending on the camera angle.

One last thing: I'm assuming you want to solve this yourself for educational reasons, right? Otherwise, it would be a plain waste of time with existing rendering toolkits in place that would even offload all the computations to the graphics hardware.

Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55
  • It is a kind of educational think. I do it as a project for the University to lern the basics of direct3d and to do it myself.(No framework and so on) I am sorting 3D objects and the problem is the plane which can be in the back with their centerpoint but the cubes for example are behind that plan but in front of the centerpoint to the camera. I also asked da second question because regulary the depthbuffer should solve that issue without doing a sorting or such. I think I have done something wrong. http://stackoverflow.com/questions/23854020/rendering-multiple-objects-with-depthstencil-fails – bemeyer May 25 '14 at 11:34
  • I just solved that issue bei rewriting the whole direct3d Creation and now there is no need to sort. Whatever was wrong with it 200lines later it was solved. Thanks anyways for that good answer and your opinion! – bemeyer May 25 '14 at 12:22
  • It just occurred to me that you really have two surfaces that overlap, so that neither is really above the other. If that is the case, nothing can really help you, any 3D framework like D3D will suffer the same problems. However, with the framework, there shouldn't be a need to sort anything, as it will determine the correct order itself. – Ulrich Eckhardt May 25 '14 at 12:30