Reputation: 9783
I am creating a little game, where you are in a maze. The maze is organized in a 2D Array
, describing the x and z position
and the block type
. So it is Tile-based
. Lets say every block is 1 m³
. Now my character is 2m tall and the maze should be 4m tall. Therefore i add 4 blocks over eachother if there is a wall on that tile. Of course this is a huge performance impact in a 100 * 100
meter/tile maze, even with Viewfrustum- and backface culling
. As this is my first 3D game i want to keep it simple and i don't want to use advanced culling techniques (octree or whatever :P). So i tried to create 1*4*1
blocks instead of 1*1*1
and add them as Walls
to my world. It works great, performance is perfect again (60 FPS), but the Texture (64*64px)
is stretched up and it really looks ugly.
So my questions are:
EDIT: I found out, that Texture
s have the TextureWrap
modes. I set that to TextureWrap.Repeat
, but i can't set the UV
s on a Texture
. If you are creating a Sprite
out of a Texture
you can easily set them to 4 to repeat the Texture
4 times. But i can't add a Sprite
to my Model
, only Texture
s are possible. Is there a way to repeat those Texture
s?
Upvotes: 2
Views: 1348
Reputation: 339
If someone will have problems with changing UVs while using ModelBuilder.createRect method then this might help:
...
Model rect = modelBuilder.createRect ...
Matrix3 mat = new Matrix3();
mat.scl(2);
rect.meshes.get(0).transformUV(mat);
instance = new ModelInstance(rect);
...
That way you will get 2x2 texture repeat. (I wasted some time searching for this solution. I used it to repeat grass texture on big ground surface)
Upvotes: 4
Reputation: 9783
As @kolenda s answer were right, but i did not find any way to apply them i had to find another way. I am now using ModelBuilder.createRect()
and i create 4 rects over each other, for every wall. By using rects, i can simply draw only visible rects, by just ignoring rects, which are occupied by another wall. So if a wall is on the left of another wall i don't draw its left face and the other walls right face.
The problem is, that there are many rects then and even with frustum culling enabled the FPS fall down to 20 if i look in a direction with many rects inside my fiewfrustum.
@xoppa told me, that ModelBuilder
is used for debug only and i should use other techniques, but i am not sure which one. So if somebody knows that, please post it as an answere here, as it answers this question (instead of repeating a texture on the model do this...), and it also solves some other problems.
But for the moment this is my solution, it works good enough for me and maybe it can help someone else to.
But as i said i like to see other, better solutions, as i am still learning some basics of 3D programming.
Upvotes: 0
Reputation: 2801
The way your texture is applied to your model depends on UV values of each vertex in the model.
If you consider one plane of your cube - it is a rectangle made of 4 vertices. If you vertices have UV values like: (0,0), (1,0), (1,1), (0,1)
then your entire texture will be rendered once on your entire plane (as you have right now).
What you need is to change some of your UVs value to 4 instead of 1 - you should use something like (0,0), (1,0), (1,4), (0,4)
- this way your texture will be repeated 4 times.
Unfortunately I don't know how to change UVs in Libgdx, maybe somebody else will help here.
EDIT for questions in comment:
You know that each vertex you render has its own 3D position vector, made of x,y,z
components. This represents the position in a 3D space.
If you want to add texture, you need to tell to your vertex at which point of texture it is. You define some 2D vector that represents a point in your texture (you can also use 3D textures but let's stick to 2D example for now).
Your texture vector components could be named x,y
also, but to avoid possible confusions with position data somebody decided to call them u,v
(it's quite often in mathematics to do such things, even if you store the same type of data it makes some equations easier to read and understand). Those vectors are called texture coordinates
or UVs
in short.
Now imagine you have your texture in front of you, one of its corners is at (0,0)
and the opposite is at (1,1)
. You take 3 vertices of some triangle and for each vertex you take its UVs and you mark this point on your texture. Then, when you connect all 3 points you'll get the same triangle as you would get from the rendering.
But what if one of your UVs component is bigger than 1
or smaller than 0
? For simplicity we could say that GPU will take the same texture and copy it just after the original one (it doesn't work exactly this way but the result is the same). This answers your question about the 4
number - if we used a texture coordinate like (1,4)
it means we're moving 4* textureHeight from origin, so you'll have your texture repeated 4 times.
I think that for now you should find a way to add UVs to your vertices and experiment with this a bit. Try to set 0, 0.1, 1, 10, etc... as your texture coordinates and look what it gives you. This way you should get some basic understanding how does UVs work.
Upvotes: 3