Fill rect with texture (first scaling the texture to fit the height and then repeating)

Fill rect with texture (first scaling the texture to fit the height and then repeating)
0.0 0

#1

Hi everyone! I’m working on a rectangular sprite that I need to fill with a texture. Currently I’m having two types of textures to fill the rectangular sprite. First one is a png file (size: 3 x 149). Second one is another png file (size: 2 x 128).

I’m working using cocos2d-x 3.10. This is the piece of code:

Texture2D *texture = Director::getInstance()->getTextureCache()->addImage("piano_roll_fondo_tiled_128.png");
texture->setTexParameters({GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT});
_backgroundSprite = Sprite::createWithTexture(texture, (Rect){ 0, 0, getContentSize().width * BACKGROUND_WIDTH_SCALE, getContentSize().height * BACKGROUND_HEIGHT_SCALE});
addChild(_backgroundSprite);

The second line (setTexParameters…) only works properly when I use the second PNG (the one that has a size based 2). When I use the 3x149 png file I have to deactivate this line of code to see the sprite filled with the texture.

I could use the 2x128 png file but the problem is that the texture repeats horizontally and vertically. I want a different behavior but I don’t know if it is possible. What I want is to make the texture scale to fit the height of the rectangle and then repeat horizontally to fit the width of the rectangle. Do you know if this is possible? And what piece of code is necessary to complete this task?

This is an image of the rectangle with the texture:

Regards!


#2

NPOT: **NON** power of two (npot)

Unfortunately this is a restriction of GL_REPEAT.
https://stackoverflow.com/questions/19768652/ios-texture-repeating-for-half-npot-texture .


If the texture doesn’t change throughout the game, or changes infrequently, you could use a RenderTexture and do any rendering you want into that texture which can them be used as the texture for UI or Sprite.

You could use a generated texture instead (such as Gradient Layer or similar).

Similarly you could even just use a software-based image manipulation to generate image data prior to loading it into the GPU texture cache. You could use CoreGraphics on iOS, or manipulate the 32-bit image data bytes directly, etc.

You could probably write a custom fragment shader that uses a form of modulo on the screen XY coordinate to repeat the texture. Unfortunately, I do believe you’ll have to supply the screen coordinates in some manner since the fragment shader really doesn’t know the pixel’s screen or world position without some external information.

You’ll also have to either disable mipmaps or otherwise note that they may affect the shader output.
(2D games that don’t zoom in/out, want to display pixelated art, or often most UI don’t need mipmaps)


#3

I just realized that I can use the texture height to fill a rectangle with that texture horizontally and then I just use sprite setScale method to change the size. I don’t need to preserve the sprite original scale!..

Thanks Anyway!