light map from polygons

I've implemented the ray casting technique described in the link below and got it working for an arbitrary number of polygons with arbitrary numbers of vertices.

https://ncase.me/sight-and-light/

For visualization, I'm using the orxDisplay_DrawPolygon function to see my light blocking polygons and also to fill in the resulting "light area" polygon. Since I can't use that function to fill a non-convex polygon, I'm just filling in a series of triangles that can be made from the rays and their endpoints. All working as expected.

My plan was to use the resulting polygon (or collection of triangles) to multiply onto a light map texture that contains my lights in order to create some simple shadows. What I can't figure out yet is how to draw the polygons somewhere other than the main display (ie, onto my light map texture). As far as I can tell, the DrawPolygon feature is tied to the current display, correct?

I'm probably missing the obvious, but what would be the suggested way to get the light polygon drawn onto a texture?

Comments

  • edited April 2020

    All the orxDisplay draw calls will affect the current destination surface. So what you want is a way to trigger your draw calls at the right time.

    To do that, you'll use an impostor object, give it the group and coordinate you want. Make sure your object has a graphic or it won't be considered for rendering. It doesn't matter what the graphic actually is as you'll ask orx not to issue the actual drawcalls for it in the end.

    Then listen to orxRENDER_EVENT_OBJECT_START. When you receive the event for the object you want (you can verify them by GUID, name, config properties or any other mean you want), issue your draw calls there then return orxSTATUS_FAILURE to prevent orx from doing its own rendering of the object.

    I'd recommend using orxDisplay_DrawMesh over orxDisplay_DrawPolygon as you can render any type of mesh with it, convex or not, triangle strips, fans, etc...

  • Great, thanks very much. I'll try this out when I have a chance.

  • I think I need to see an example of how to use orxDisplay_DrawMesh....I'm just trying to draw a simple triangle with it to learn how to use it, but can't get anything to show up. I've set the vertex list to an array of 3 orxDISPLAY_VERTEX with x/y values set, vertex number to 3 with the primitive set to orxDISPLAY_PRIMITIVE_TRIANGLES, using orxNULL for the bitmap parameter (wasn't completely sure on that one). Stepping through, it seems that glDrawElements gets called.

    I looked around on the forum and although there are lot of references to DrawMesh, I can't find an example of working code. As always, any help is much appreciated.

  • edited April 2020

    You can have a look at code/plugins/Demo/orxBounce.c, I'm using orxDisplay_DrawMesh to draw the smoke trail there.
    You'll need indices as well. If you don't provide a bitmap, the current bitmap (ie. the last one used for a draw call) is going to be used.

  • Great, thank you. I didn't think to search through the demo code. Next time!

  • No worries, lemme know if that helps when you get a chance to try it!

  • Yes, I have my triangle! I just have 3 vertices for my test, and orxDISPLAY_PRIMITIVE_TRIANGLES doesn't work, but _STRIP and _FAN does in fact render my triangle. Haven't tested further but the fan is actually what I want to use anyway I think.

  • edited April 2020

    It should be working with orxDISPLAY_PRIMITIVE_TRIANGLES as well. If you make the following changes, you can test it in orxBounce:

      static orxU16     sau16IndexList[(TRAIL_POINT_NUMBER - 2) * 6];
    // [...]
        /* Inits index buffer */
        for(i = 0; i < TRAIL_POINT_NUMBER - 2; i++)
        {
          /* Stores indices */
          sau16IndexList[i * 6]     = (orxU16)(i * 2);
          sau16IndexList[i * 6 + 1] = (orxU16)((i + 1) * 2);
          sau16IndexList[i * 6 + 2] = (orxU16)(i * 2 + 1);
          sau16IndexList[i * 6 + 3] = (orxU16)((i + 1) * 2);
          sau16IndexList[i * 6 + 4] = (orxU16)((i + 1) * 2 + 1);
          sau16IndexList[i * 6 + 5] = (orxU16)(i * 2 + 1);
        }
    // [...]
      stMesh.ePrimitive       = orxDISPLAY_PRIMITIVE_TRIANGLES;
    
  • I wasn't using an index list for my triangle thinking it was unnecessary for a simple 3 point test. It appears that using the triangles option requires there be an index list set...when I have it set the triangle appears. It doesn't even matter what order I specify in the in the index list....any order works (which seems reasonable to me for a triangle). But if I don't specify the list, nothing appears. However, the FAN or STRIP options don't seem to have that requirement and work for a single triangle without setting the index list.

    In any case, I'm one step further on my way to getting my light polygon drawn onto a texture at this point. Thanks.

  • I know it's pretty basic stuff, but I was excited to get this far! I've got DrawMesh running in the render event for my dummy object. Next step is to put the mesh into a light map and see what I can do with it.

  • Normally you should need indices for any mesh, the fact it works for a single triangle strip/fan is a bit lucky I think. :)

    Nice result there, btw, with a shader you'll be able to have a nice falloff and smooth edges.

  • So my plan was to create a light map texture, draw my light onto it and then multiply my polygon onto that. I was assuming if I position my light further from the light camera than my dummy object that renders the polygon, the light would be rendered first and then the polygon multiplied on top of it. I'm doing something wrong though, or my assumptions and strategy are all wrong, because if I use multiply as blend mode on my DrawMesh call, the polygon is gone...multiplied by the black background of the texture I think, before the spotlight is rendered. If I use ADD, I get a combination of my light and polygon as I'd expect, shown here:

    But using MULTIPLY just gives me a spotlight with no polygon or effect from it. The z positioning of the light and the dummy object seems to have no effect on the behavior. Is this the wrong way to go about it?

  • Think I've got it working now...not coming naturally to me at this point but should be able to get it.

  • Finally got the blending working the way I wanted. Once the blue polys are real objects it might look ok.

  • Nice result, sorry for the lack of reply today, I've been busy with Ludum Dare on my side.

  • No worries about replies....good luck with that!

Sign In or Register to comment.