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

Author Topic: [SOLVED] Incorrect scaling of custom VertexArray  (Read 5218 times)

0 Members and 1 Guest are viewing this topic.

DragonDePlatino

  • Newbie
  • *
  • Posts: 12
    • View Profile
    • Email
[SOLVED] Incorrect scaling of custom VertexArray
« on: June 30, 2016, 01:05:20 am »
Hello! I'm having some problems with the scaling of a custom VertexArray.

In my engine I have a texture for tiles, objects and lights. Tiles and objects are drawn via a custom VertexArray like the one shown here. Lights are drawn using sf::Shape. I draw the objects, tiles and lights to their textures, then I pass everything through a shader. The result is a fog of war system that masks out of view objects:



If I resize the window all of my textures resize accordingly and I can see a further distance:



Here's my problem: I don't want to draw my tile VertexArray to a texture then pass it through my shader. It seems wasteful because I'm not modifying it in my shader. Instead, I want to draw my tile VertexArray directly to the screen then draw the shader's texture over that. If I do this, it works just fine (like in the first image). The problem is when I resize the window. This happens:



Everything passed through the shader resizes correctly, but the tile VertexArray does not. The larger I resize the window, the further offscreen the tile VertexArray stretches. The smaller I make the window, the less the VertexArray takes up the screen.

If I debug my VertexArray, everything seems to be fine. Each vertex is still 32x32 in size and the larger the screen is, the more vertexes are added. I think SFML might be forcibly scaling my tile VertexArray which I do not want! >:(

For the record, I have also tried rendering my tile VertexArray to a texture, making a sprite from that and rendering it to the window. I get the same bad results.
« Last Edit: June 30, 2016, 05:38:54 pm by DragonDePlatino »

DarkRoku12

  • Full Member
  • ***
  • Posts: 203
  • Lua coder.
    • View Profile
    • Email
Re: Incorrect scaling of custom VertexArray
« Reply #1 on: June 30, 2016, 02:47:57 am »
I´m not an expert on shader related themes, and too i did not fully understand what do you want to tell.

But i can advise that a shaders works on an amount of pixels, if the screen size change you need to change the resolution that will work on the shader.

So if you have and uniform for store the window resolution, you need to change it whenever the window size change.
« Last Edit: June 30, 2016, 02:53:23 am by DarkRoku »
I would like a spanish/latin community...
Problems building for Android? Look here

DragonDePlatino

  • Newbie
  • *
  • Posts: 12
    • View Profile
    • Email
Re: Incorrect scaling of custom VertexArray
« Reply #2 on: June 30, 2016, 03:27:54 am »
And that's where I'm confused. I'm not passing my window size into my shader, but things only work if I put them through the shader. If I pass my tile texture through the shader like this...

uniform sampler2D tiletexture;
uniform sampler2D objtexture;
uniform sampler2D fogtexture;
uniform sampler2D lighttexture;

void main()
{
        // Load textures into pixels
        vec4 tilepixel = texture2D(tiletexture, gl_TexCoord[0].xy);
        vec4 objpixel = texture2D(objtexture, gl_TexCoord[0].xy);
        vec4 fogpixel = texture2D(fogtexture, gl_TexCoord[0].xy);
        vec4 lightpixel = texture2D(lighttexture, gl_TexCoord[0].xy);
       
        // Draw objects if a lighttexture pixel is fully-transparent
        // Otherwise, hide objects behind fog
        bool changealpha = bool(ceil(lightpixel.a));
        objpixel = vec4((lightpixel.rgb) * float(changealpha) + objpixel.rgb * float(!changealpha), lightpixel.a * float(changealpha) + objpixel.a * float(!changealpha));
        objpixel = mix(objpixel, fogpixel, fogpixel.a);
        tilepixel = mix(tilepixel, objpixel, objpixel.a);
       
        gl_FragColor = tilepixel;
}

Then resize my window, this happens:



That is what I want. But if I remove the tiletexture from my shader...

uniform sampler2D objtexture;
uniform sampler2D fogtexture;
uniform sampler2D lighttexture;

void main()
{
        // Load textures into pixels
        vec4 objpixel = texture2D(objtexture, gl_TexCoord[0].xy);
        vec4 fogpixel = texture2D(fogtexture, gl_TexCoord[0].xy);
        vec4 lightpixel = texture2D(lighttexture, gl_TexCoord[0].xy);
       
        // Draw objects if a lighttexture pixel is fully-transparent
        // Otherwise, hide objects behind fog
        bool changealpha = bool(ceil(lightpixel.a));
        objpixel = vec4((lightpixel.rgb) * float(changealpha) + objpixel.rgb * float(!changealpha), lightpixel.a * float(changealpha) + objpixel.a * float(!changealpha));
        objpixel = mix(objpixel, fogpixel, fogpixel.a);
       
        gl_FragColor = objpixel;
}

And then I draw the tiles with a VertexArray and resize the window, this happens:



I don't understand why I have to pass my tiletexture through the shader for it to resize correctly. Right now, I'm passing everything through the shader whether or not the shader is editing it. Once I add in a texture for GUI and a parallax background, I don't want to have to pass those too. :(
« Last Edit: June 30, 2016, 06:30:32 am by Laurent »

DarkRoku12

  • Full Member
  • ***
  • Posts: 203
  • Lua coder.
    • View Profile
    • Email
Re: Incorrect scaling of custom VertexArray
« Reply #3 on: June 30, 2016, 04:32:42 am »
By your username i believe that you speak spanish, i can discuss and talk better about your issue with private messages...in spanish.
I would like a spanish/latin community...
Problems building for Android? Look here

DragonDePlatino

  • Newbie
  • *
  • Posts: 12
    • View Profile
    • Email
Re: Incorrect scaling of custom VertexArray
« Reply #4 on: June 30, 2016, 05:13:38 am »
No, I cannot speak fluent Spanish. I would like to get an answer here so other people can learn from it.

It's OK if you can't solve the problem. I'll just wait and see if anyone else has an answer.

DarkRoku12

  • Full Member
  • ***
  • Posts: 203
  • Lua coder.
    • View Profile
    • Email
Re: Incorrect scaling of custom VertexArray
« Reply #5 on: June 30, 2016, 05:23:56 am »
The problem its most probable the screen size and the shader.

most shaders use this code to get the pixel position (clamped between 0~1)

uniform vec2 resolution ; // Our screen dimensions
void main()
{  
    vec2 pixel = gl_FragCoord.xy / resolution.xy ;
   // Do something.
}
 

Whenever the screen size change you must change the resolution uniform, if you used it like the example above.
You can use SFML events for achieve this.
I would like a spanish/latin community...
Problems building for Android? Look here

DragonDePlatino

  • Newbie
  • *
  • Posts: 12
    • View Profile
    • Email
Re: Incorrect scaling of custom VertexArray
« Reply #6 on: June 30, 2016, 05:38:21 pm »
OK! I found my solution. After experimenting a bit, it seems I have to resize the tile VertexArray to be smaller if I make my window size larger. Why? I have no idea.

Code: [Select]
sf::FloatRect initsize(0, 0, 640, 360);
sf::IntRect buffersize(0, 0, initsize.width, initsize.height);

... Do some window resizing and update buffersize ...

sf::Transform tiletransform;
tiletransform.scale(initsize.width / buffersize.width, initsize.height / buffersize.height);
sf::RenderStates tilerender;
tilerender.transform = tiletransform;
window.draw(tilemap, tiletransform);

Here, initsize is the initial window size on startup. Buffersize is the window size after resizing. Every time you draw a custom VertexArray directly to a resized window, you need to shrink it by the same amount the window was upscaled. That will produce the desired effect seen in the 2nd image of the OP.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
AW: [SOLVED] Incorrect scaling of custom VertexArray
« Reply #7 on: June 30, 2016, 05:41:34 pm »
Do you adjust the view somehow?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

DragonDePlatino

  • Newbie
  • *
  • Posts: 12
    • View Profile
    • Email
Re: [SOLVED] Incorrect scaling of custom VertexArray
« Reply #8 on: June 30, 2016, 05:54:18 pm »
I'm not using sf::View. I have a custom camera class that handles the view and only draws tiles that are intersecting the window.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: [SOLVED] Incorrect scaling of custom VertexArray
« Reply #9 on: June 30, 2016, 10:10:39 pm »
So you're using custom OpenGL code?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

DragonDePlatino

  • Newbie
  • *
  • Posts: 12
    • View Profile
    • Email
Re: [SOLVED] Incorrect scaling of custom VertexArray
« Reply #10 on: July 01, 2016, 01:33:39 am »
Nah. I don't know a lick of OpenGL programming. I'm still pretty green when it comes to SFML. :P
Code: [Select]
for(int col = camera.mintile[y]; col <= camera.maxtile[y]; col++)
{
for(int row = camera.mintile[x]; row <= camera.maxtile[x]; row++)
{
Tile* tile = level->getTile(row, col);
sf::IntRect renderrect = { tile->drawclip.left - camera.camerarect.left,
tile->drawclip.top - camera.camerarect.top,
tile->drawclip.width,
tile->drawclip.height};

tilemap.addTile(&renderrect, &tile->imageclip);
}
}

That's the main loop responsible for drawing just the midground tiles. Before rendering, I pass my map's size and the player's position to the camera class. Camera decides the range of tiles to draw (mintile and maxtile) as well as what part of the map is being drawn (camerarect). Each tile in the map stores its draw position (drawclip) and its location on the texture (imageclip). I pass both of those to my VertexArray, offsetting them with the camera.

I do the same for background tiles, monsters and objects. It might sound excessive having each tile store its own drawclip and imageclip, but I'm making a roguelike so I want things to be as flexible as possible. :D

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: [SOLVED] Incorrect scaling of custom VertexArray
« Reply #11 on: July 01, 2016, 12:48:21 pm »
By using a view you could keep everything at 1:1 scale and just change the view (which is basically a camera) to fit the tiles. If performance is noticeably impacted you could then always decide which tiles should or shouldn't be drawn.

But I guess if your solution works, then it's good enough. :)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/