0
\$\begingroup\$

I need to draw a tilemap for a 2d game. For that I created vertices with their relative positions already hard baked. The coordinates start top-left with (0f, 0f) and z is always 0.

I rendered them to the rendertarget with the following view matrix (world and projection are both Identity):

Matrix view = Matrix.CreateOrthographic(this.miniMapRenderTarget.Width, this.miniMapRenderTarget.Height, 0, 1)
     * Matrix.CreateScale((float)(this.miniMapRenderTarget.Width / (this.map.Size.X * this.map.TileSize.X * 2)))
     * Matrix.CreateTranslation(-0.5f, -0.5f, 0);

I noticed that all stuff was just rendered to the top-right quadrant of the texture so I added a translation of -0.5 for x and y. This works find, so far.

The only bug still is that Y seem to be displayed inverted, so top is bottom. I tried to fix this by multiplying Matrix.CreateScale(1, -1, 1) to the matrix but then I do not see anything rendered to the texture. I guess I am doing something fundamentally wrong here and the matrix has to be constructed in a different way?

\$\endgroup\$
5
  • 1
    \$\begingroup\$ When you reverse the Y, you also flip the winding order of the polygons, so front-facing polygons become back-facing. So you need to switch the culling mode (or turn off backface culling entirely) \$\endgroup\$
    – DMGregory
    Commented Dec 28, 2022 at 23:40
  • \$\begingroup\$ @DMGregory: thx for the answer it seems to work now. i needed to set the cullmode and also ensure that the scale it multiplied at the end. but isn't there a simpler way of doing this? \$\endgroup\$
    – codymanix
    Commented Dec 28, 2022 at 23:54
  • \$\begingroup\$ If you've solved your problem, post your corrected code as an Answer below. Folks can offer alternative answers, vote, and comment to give additional feedback about what solutions they think are simplest. \$\endgroup\$
    – DMGregory
    Commented Dec 29, 2022 at 11:45
  • \$\begingroup\$ I would love to present an alternative answer as DMGregory suggested, but the offending lines of code(vertex type and definitions) are not given. If "baked" the load lines may be more appropriate, to allow a single fixed transform at the source.Or the draw line to correct the problem each step, poor solution, but better than rendering twice. \$\endgroup\$
    – user122973
    Commented Jan 8, 2023 at 2:10
  • \$\begingroup\$ "or that I created vertices with their relative positions already hard baked. " un-bake them. and fix the problem at the source. \$\endgroup\$
    – user122973
    Commented Jan 8, 2023 at 2:18

1 Answer 1

1
\$\begingroup\$

As suggested by DMGregory, setting cullmode to none ensures that the inverted Y axis by scaling does not cull away objects. Note: It would be even better to just invert the cullmode, e.g. setting it to counterclockwise when it was clockwise and vice versa.

    this.graphicsDevice.RasterizerState = RasterizerState.CullNone;     

    var view = Matrix.CreateOrthographic(this.miniMapRenderTarget.Width, this.miniMapRenderTarget.Height, 0, 1)               
         * Matrix.CreateTranslation(-1, -1, 0)
         * Matrix.CreateScale(1, -1, 1);

I would have preferred a solution that does not enforce modifying the cullmode but at least it works now.

\$\endgroup\$
6
  • 2
    \$\begingroup\$ You can change the winding of your polygons instead to compensate for the reflection in the matrix. Swapping two indices in every triangle will do the trick. \$\endgroup\$
    – DMGregory
    Commented Dec 30, 2022 at 16:08
  • \$\begingroup\$ "setting cullmode to none" draws every triangle twice. Very poor solution. It may work, but it halves the rendering speed on non-workstation graphics cards. Fix the underlying problem, the workaround is not a viable scalable solution. \$\endgroup\$
    – user122973
    Commented Jan 8, 2023 at 1:51
  • \$\begingroup\$ @Strom: As I wrote, also just inverting the Cullmode does the trick, e.g. setting to counterclockwise when it was clockwise and vice versa. If you now an even better solution please let me now. \$\endgroup\$
    – codymanix
    Commented Jan 9, 2023 at 2:11
  • \$\begingroup\$ @Strom it is not true that setting cullmode to none draws every triangle twice. It still draws them at most once per draw call. It just does not abort rendering of triangles that face away from the camera. If you have a 3D object with both a front & back side, this means two different triangles overlap each pixel, with the front one usually hiding the one behind, so it would've been safe to skip. That's what people mean when they say it doubles the work. It does not apply to a case like this where the object being drawn is only a single layer of polygons, with no back-facing skin to hide. \$\endgroup\$
    – DMGregory
    Commented Jan 9, 2023 at 10:20
  • \$\begingroup\$ @DMGregory My point was to avoid culllmode.none because it will incur a performance penalty, no matter the implementation. \$\endgroup\$
    – user122973
    Commented Jan 13, 2023 at 2:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .