Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: 2d scaling, pixel size vs. gameworld size  (Read 10387 times)

0 Members and 1 Guest are viewing this topic.

lid6j86

  • Newbie
  • *
  • Posts: 23
    • View Profile
    • Email
2d scaling, pixel size vs. gameworld size
« on: July 06, 2014, 02:36:46 pm »
So I was looking through and I guess i'm a little confused on the whole texture size/game world object size separation.

What is the most proper way to scale an image down to a specific unit size?  For instance say I made a 64x64 image that i want to be 1x1 game unit (those being soft numbers subject to change), do I have to say for every sprite created  Sprite.Scale(1/width,1/height)  (note* not sure that's the correct calculation, but it seems right off the top of my head)?

when I create a sprite it defaults the size to that of the texture itself, but i'd like to use game world units... or am I looking at this completely incorrectly?

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: 2d scaling, pixel size vs. gameworld size
« Reply #1 on: July 06, 2014, 02:58:53 pm »
This belongs in the graphics section since it is not directly related to the binding, however...

You are mentioning several things here, original texture size, world unit measurement, target pixel size, and scaling.

The original texture size is the size of the texture you are drawing. In order to convert to anything else you need to know this value.

World units can make it easier to think of your game world. 1x1 world unit can represent a square tile or 1x5 could represent a platform your player is walking on.

Target pixel size is what each world unit is valued in pixels. Lets say for this example 1 world unit is equal to 64 pixels. So we have a platform that is 1x5 (world units), the actual size of this is 64x320 pixels. All SFML cares about is pixels so you need to be able to convert between world units and pixels.

World Units to Pixels
sf::Vector2f ratio(64, 64);
sf::Vector2f pixelSize( worldUnits * ratio );
 

Pixels to World Units
sf::Vector2f ratio(64, 64);
sf::Vector2f worldUnits( pixelSize / ratio );
 



Now to calculate the sprite scale. Remember that the scale is dependent on pixels and not world units.

sf::Vector2f pixelSize( { 64, 320 } );
sf::Vector2i textureSize( { 128, 640} );
sprite.setScale(pixelSize / textureSize);
 

Lets put it all together.

// 1x5 platform
sprite.setScale( toPixels(1, 5) / texture.getSize() );
 

I hope this clears it up for you.
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

lid6j86

  • Newbie
  • *
  • Posts: 23
    • View Profile
    • Email
Re: 2d scaling, pixel size vs. gameworld size
« Reply #2 on: July 06, 2014, 03:05:15 pm »
this example is exactly what i was looking for, thank you.  I was used to directly dealing with OpenTK, where you basically deal with GW units and the texture is pasted based on the whole (0,0) (0,1) (1,0) (1,1) thing.  Appreciate the help

lid6j86

  • Newbie
  • *
  • Posts: 23
    • View Profile
    • Email
Re: 2d scaling, pixel size vs. gameworld size
« Reply #3 on: July 06, 2014, 06:45:23 pm »
having some odd problems,  can get colored verticies to appear, but when i attempt to apply a texture it simply does not show up:

Vertex[] vArray = new Vertex[4];

            Texture tx = new Texture("flag.png");
            RenderStates rs = new RenderStates(tx);


            vArray[0].Position = new Vector2f(0, 0);
            vArray[0].TexCoords = new Vector2f(0, 0);

            vArray[1].Position = new Vector2f(0, 421);
            vArray[0].TexCoords = new Vector2f(0, 421);

            vArray[2].Position = new Vector2f(800, 0);
            vArray[2].TexCoords = new Vector2f(800, 0);

            vArray[3].Position = new Vector2f(800, 421);
            vArray[3].TexCoords = new Vector2f(800, 421);

         
         

            while(true)
            {
                rw.DispatchEvents();

                rw.Draw(vArray,0,4, PrimitiveType.TrianglesStrip , rs);
             


                rw.Display();
            }

anyone see what i'm doing wrong with the texture?

Edit: Just realized the addition to the post should have probably been its own post, apologies
« Last Edit: July 07, 2014, 07:38:39 am by Laurent »

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: 2d scaling, pixel size vs. gameworld size
« Reply #4 on: July 06, 2014, 06:52:33 pm »
Quote
Texture tx = new Texture("flag.png");
You're dynamically allocating a texture and then assigning the pointer to it to a texture, not a pointer to texture.  I don't think this should even compile, so I assume you typo'd.  Plus, Textures don't have a constructor taking a filepath. You need to use loadFromFile.

Either way, you shouldn't be doing any heap allocation or copying of textures without a good reason.  Just create one texture and load it from a file:
Quote
Texture tx;
if(!tx.loadFromFile("flag.png"))
    std::cout << "Error!" << std::endl;

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: 2d scaling, pixel size vs. gameworld size
« Reply #5 on: July 06, 2014, 06:57:02 pm »
This is C# code, not C++.

And where is this code by the way?
Laurent Gomila - SFML developer

lid6j86

  • Newbie
  • *
  • Posts: 23
    • View Profile
    • Email
Re: 2d scaling, pixel size vs. gameworld size
« Reply #6 on: July 06, 2014, 07:06:22 pm »
this was a sample code i was using to get a grasp of the difference between the c++ implementation and making a C# version with primitives.

It's all sitting within the main entry point, with everything declared above, and then rendered in the while loop
« Last Edit: July 06, 2014, 07:09:22 pm by lid6j86 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: 2d scaling, pixel size vs. gameworld size
« Reply #7 on: July 06, 2014, 07:08:35 pm »
Sorry, I didn't see the two lines that create the texture and the render states, they are lost in the initialization of the vertex array :P
Laurent Gomila - SFML developer

lid6j86

  • Newbie
  • *
  • Posts: 23
    • View Profile
    • Email
Re: 2d scaling, pixel size vs. gameworld size
« Reply #8 on: July 06, 2014, 07:15:51 pm »
yea it's declared at the top, i set the coords, and use a while loop to render (all in the main loop).  if i dont try to add a texture it shows up fine, as soon as i add the texture is when it 'disappears'

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: 2d scaling, pixel size vs. gameworld size
« Reply #9 on: July 06, 2014, 07:36:12 pm »
You never call rw.Clear().
Laurent Gomila - SFML developer

lid6j86

  • Newbie
  • *
  • Posts: 23
    • View Profile
    • Email
Re: 2d scaling, pixel size vs. gameworld size
« Reply #10 on: July 06, 2014, 07:43:31 pm »
although that was quite dumb, still didn't cause anything to appear.  I would think that even without clear it would appear, it would just "smear" or do something else unexpected if it weren't static

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: 2d scaling, pixel size vs. gameworld size
« Reply #11 on: July 06, 2014, 08:00:06 pm »
Does drawing a normal sprite work?
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: 2d scaling, pixel size vs. gameworld size
« Reply #12 on: July 06, 2014, 08:34:47 pm »
Quote
            vArray[1].Position = new Vector2f(0, 421);
            vArray[0].TexCoords = new Vector2f(0, 421);

Should be vArray[1] ;)
Laurent Gomila - SFML developer

lid6j86

  • Newbie
  • *
  • Posts: 23
    • View Profile
    • Email
Re: 2d scaling, pixel size vs. gameworld size
« Reply #13 on: July 07, 2014, 12:18:54 am »
so at this point (that was another dumb one) i have this:

 RenderWindow rw = new RenderWindow(new VideoMode(800, 600), "SFML test box");
 rw.Closed += rw_Closed;

Vertex[] vArray = new Vertex[4];

            Texture tx = new Texture("flag.png");
           
            RenderStates rs = new RenderStates(tx);


            vArray[0].Position = new Vector2f(0, 0);
            vArray[0].TexCoords = new Vector2f(0, 0);

            vArray[1].Position = new Vector2f(0, 421);
            vArray[1].TexCoords = new Vector2f(0, 421);

            vArray[2].Position = new Vector2f(800, 0);
            vArray[2].TexCoords = new Vector2f(800, 0);

            vArray[3].Position = new Vector2f(800, 421);
            vArray[3].TexCoords = new Vector2f(800, 421);

         
         
            while(true)
            {
                rw.DispatchEvents();
                rw.Clear();

                rw.Draw(vArray, 0, 4, PrimitiveType.TrianglesStrip, rs);

                rw.Display();
            }

        }

        static void rw_Closed(object sender, EventArgs e)
        {
            ((RenderWindow)sender).Close();
            Environment.Exit(0);
        }


    }

  • I checked that all libraries and the image are set to "copy if newer"
  • I checked the indicies again   (going upper left, bottom left, upper right, bottom right)
  • Normal sprites definitely work
  • There is a clear message at the beginning of the draw loop and the swap buffers message at the end
  • Opened the image to make sure there was data in it
  • double checked the dimensiones (800,421)
  • made a view to zoom out (just to make sure)
« Last Edit: July 07, 2014, 07:38:51 am by Laurent »

lid6j86

  • Newbie
  • *
  • Posts: 23
    • View Profile
    • Email
Re: 2d scaling, pixel size vs. gameworld size
« Reply #14 on: July 07, 2014, 04:33:00 am »
so interesting (perhaps odd?) update, i tried it again using vertexarray instead of individual vertices, and it is now displaying correctly.

I'm wondering:  I used quads instead of triangle fan, and i just went clockwise for vertex declaration... did that previous code have a logic error in the vertex  declaration?  I thought Triangle fan should be jagged? (i.e.  top left, bottom left, top right, bottom right, etc...)?

I'll try it again one more time with basic vertices and see if i can't reproduce the problem

 

anything