Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (107)
games submitted by our members
Games in WIP (535)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  [LibGDX] creating a mesh with different textures  (Read 1839 times)
0 Members and 1 Guest are viewing this topic.
Offline Jaxes74

Senior Newbie


Projects: 1



« Posted 2014-03-09 21:05:37 »

Hi,

What would be the best way to create a mesh (here a cube) with different textures each side?

I have tried this by creating a textured mesh in Blender. In Blender I have mapped the texture and then exported it to LibGDX. This works, no problem. But I would like to dynamically assign the texture (maybe different ones) to each side. Importing the model is to my understanding static.

As an alternative I have also created a quad (one face) to which I can put a texture. This works too but obviously I am missing 5 sides of the mesh (cube).

1) I probably can create the missing 5 sides (as quads) and have them textured, but is this really the only option?
2) Can I set texture for a mesh parts or faces created by modelBuilder.createBox somehow?
3) Any other or better alternatives for doing this?

Thanks you in advance! I really have tried first to look the net and forum for an answer.

Cheers, Jaxes

WordSlinger- The best word game if developer opinion counts.
https://play.google.com/store/apps/details?id=com.method.wordslinger
Offline trollwarrior1
« Reply #1 - Posted 2014-03-09 21:11:44 »

You can use something call atlas, texturesheet or spritesheet.
Basically, lets say you have 4 textures of size 256x256. You can put them into single texture the size of 1024x1024 and render certain part of that altas.

You can also use a megatexture. Not really sure how that would work, just saw something about it on youtube yesterday Cheesy
Offline Jaxes74

Senior Newbie


Projects: 1



« Reply #2 - Posted 2014-03-09 21:59:26 »

You can use something call atlas, texturesheet or spritesheet.
Basically, lets say you have 4 textures of size 256x256. You can put them into single texture the size of 1024x1024 and render certain part of that altas.

Thanks for the answer.

I tried TextureAtlas and I got everything correctly packed with the tool but my problem is that I don't know how to assign the textures to certain parts of the mesh (here cube face). I am not sure if you can assign texture from TextureAtlas because what you get returned is TextureRegion, but I might be wrong.

You might be answering the correct question but I don't understand how using TextureAtlas helps me in setting different Textures for different parts of the Mesh?

I have also looked the attributes of the Model class and there's an materials but but... How does one compose a Model with 6 meshes with 6 different textures?

Now I have actually done it in MeshBuilder but it sure feels clumsy.

Cheers, Jaxes
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Online Longarmx
« Reply #3 - Posted 2014-03-10 00:39:03 »

You use one texture with the mesh then you use texture coordinates to say what part of the texture you want to be drawn.

Offline Jaxes74

Senior Newbie


Projects: 1



« Reply #4 - Posted 2014-03-10 11:00:31 »

You use one texture with the mesh then you use texture coordinates to say what part of the texture you want to be drawn.

Thank you for the answer. Can you elaborate your answer? Or give me guidance where to find documents / tutorial / material regarding how to do this specific task in LibGDX?

I have done this like you say with MeshBuilder but it seems just a little bit tedious and clumsy. It works though which is the best part. Smiley
I might be asking too simple thing but is there easier way for doing this?

Cheers, Jaxes
Offline trollwarrior1
« Reply #5 - Posted 2014-03-10 11:07:47 »

Uhmm.. Start with LWJGL instead of LibGDX. You obviously have no idea what we are talking about.

This is how rendering works:
- Bind certain texture to opengl
- Point opengl to vertex data: each vertex has position, color, texture coordinate, normal. You can also add custom vertex attributes.
- Tell opengl to rendering everything

If you want to use different textures for 1 mesh, you will need to render mesh in separate parts: render 1st part with texture 1, render 2nd part of the mesh with texture 2, render 3rd part of the mesh with texture 3. That is the only way. If you want to have different textures for 1 mesh, you have to split the mesh into manageable pieces..
Offline Jaxes74

Senior Newbie


Projects: 1



« Reply #6 - Posted 2014-03-10 13:27:44 »

Thank you for the answer.

Uhmm.. Start with LWJGL instead of LibGDX. You obviously have no idea what we are talking about.

Maybe you are right, but I got it working already. I did it by using MeshBuilder by adding 6 meshes with 6 textures and created a model. Now I can rotate the modelInstance created from the Model. This works all very well.

This is how rendering works:
- Bind certain texture to opengl
- Point opengl to vertex data: each vertex has position, color, texture coordinate, normal. You can also add custom vertex attributes.
- Tell opengl to rendering everything

This applies in general level how this is achieved. I know how to do this. But my question was specifically LibGDX specific and moreover I was wondering if there's any easier way than using MeshBuilder which to me felt a little bit "clumsy".

If you want to use different textures for 1 mesh, you will need to render mesh in separate parts: render 1st part with texture 1, render 2nd part of the mesh with texture 2, render 3rd part of the mesh with texture 3. That is the only way. If you want to have different textures for 1 mesh, you have to split the mesh into manageable pieces..

Yeah, this is what I have done.

I might be asking too simple question but this is really LibGDX specific and I would like to know if there's a better way to do this in LibGDX than building the mesh with MeshBuilder. Sorry if I am repeating myself or being just a noob but to me it still looks the actual question remains unanswered.

Cheers, Jaxes
Online Longarmx
« Reply #7 - Posted 2014-03-10 14:59:54 »

@TrollWarrior1
Dont suggest lwjgl if the op is having trouble with the libgdx implementation. Also, dont tell him that he "oubviously has no idea what he his talking about." You were once there too.

@Jaxes74
You dont need a separate texture for each image. Use one texture with all the images on it. You bind that one texture at the start of rendering. Then, each vertex has position, texture coordinates, color, and normal. The texture coordinates tell what part of the the image to render. Basically, theyre texture regions. Use a texture region to get the texture coordinates for the part of the texture youre trying to render.

Offline Jaxes74

Senior Newbie


Projects: 1



« Reply #8 - Posted 2014-03-10 19:41:20 »

You dont need a separate texture for each image. Use one texture with all the images on it. You bind that one texture at the start of rendering. Then, each vertex has position, texture coordinates, color, and normal. The texture coordinates tell what part of the the image to render. Basically, theyre texture regions. Use a texture region to get the texture coordinates for the part of the texture youre trying to render.

Thanks. I am gonna try it now. I am not sure about the binding thing though. I am currently not binding the textures explicitly (at the render), but if OpenGL requires that then it might be done my the framework.

Cheers, Jaxes
Offline Jaxes74

Senior Newbie


Projects: 1



« Reply #9 - Posted 2014-03-10 20:10:19 »

Ok, I don't understand. I admit it.

Relevant parts of my code:
create:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
      textureAtlas = new TextureAtlas(Gdx.files.internal("data/pack.atlas"));
      Texture myTexture = new Texture(Gdx.files.internal("data/treasure.jpg"));
     
      ModelBuilder builder = new ModelBuilder();
      builder.begin();
      builder.part("1", createQuad(),   GL10.GL_TRIANGLES,new Material("1", TextureAttribute.createDiffuse(myTexture)));
      //builder.part("1", createQuad(),   GL10.GL_TRIANGLES,new Material("1", TextureAttribute.createDiffuse(textureAtlas
     //            .findRegion("myRegionName"))));
     quadInstance = new ModelInstance(builder.end(), 0, 0, 0);
      instances.add(quadInstance);


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
   private Mesh createQuad() {
      Mesh quad = new Mesh(true, 4, 6, new VertexAttribute(Usage.Position, 3,   "a_position"),
            new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords"));

      quad.setVertices(new float[] { -1f, -1f, 0, 0, 1, // bottom left
           1f, -1f, 0, 1, 1, // bottom right
           1f, 1f, 0, 1, 0, // top right
           -1f, 1f, 0, 0, 0 }); // top left
     quad.setIndices(new short[] { 0, 1, 2, 2, 3, 0 });
      return quad;
   }


render:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
   public void render() {
      Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(),
            Gdx.graphics.getHeight());
      Gdx.gl.glClearColor(1, 1, 1, 1);
      Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

      camera.update();

      modelBatch.begin(camera);
      modelBatch.render(instances, environment);
      modelBatch.end();
   }


Now, how do I assign the texture from TextureAtlas to the mesh (the out commented part) ? The direct assign from Texture works.

Cheers, Jaxes
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Online Longarmx
« Reply #10 - Posted 2014-03-11 01:27:55 »

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
   private Mesh createQuad() {
      Mesh quad = new Mesh(true, 4, 6, new VertexAttribute(Usage.Position, 3,   "a_position"),
            new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords"));

      TextureRegion region = new TextureRegion("you spritesheet texture", 0, 0, 128, 128); // Basically this just gets the texture region that you want the side to be ("texture path", xLocation, yLocation, width, height)

      quad.setVertices(new float[] { -1f, -1f, 0, region.getU(), region.getV2(), // bottom left
           1f, -1f, 0, region.getU2(), region.getV2(), // bottom right
           1f, 1f, 0, region.getU2(), region.getV(), // top right
           -1f, 1f, 0, region.getU(), region.getV() }); // top left
     quad.setIndices(new short[] { 0, 1, 2, 2, 3, 0 });
      return quad;
   }


Getting the u/v/u2/v2 will give you the texture coordinates of that part of the whole texture. You'll just have to repeat this for every face with different vertex locations & region locations. Basically, you use a spritesheet like this. This way, you don't have to bind different textures, you just use different texture coordinates to locate the image you want.

Offline Jaxes74

Senior Newbie


Projects: 1



« Reply #11 - Posted 2014-03-17 20:32:06 »

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
   private Mesh createQuad() {
      Mesh quad = new Mesh(true, 4, 6, new VertexAttribute(Usage.Position, 3,   "a_position"),
            new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoords"));

      TextureRegion region = new TextureRegion("you spritesheet texture", 0, 0, 128, 128); // Basically this just gets the texture region that you want the side to be ("texture path", xLocation, yLocation, width, height)

      quad.setVertices(new float[] { -1f, -1f, 0, region.getU(), region.getV2(), // bottom left
           1f, -1f, 0, region.getU2(), region.getV2(), // bottom right
           1f, 1f, 0, region.getU2(), region.getV(), // top right
           -1f, 1f, 0, region.getU(), region.getV() }); // top left
     quad.setIndices(new short[] { 0, 1, 2, 2, 3, 0 });
      return quad;
   }


Getting the u/v/u2/v2 will give you the texture coordinates of that part of the whole texture. You'll just have to repeat this for every face with different vertex locations & region locations. Basically, you use a spritesheet like this. This way, you don't have to bind different textures, you just use different texture coordinates to locate the image you want.

Sorry for delay in reply, I was in CeBIT and what not, had a birthday etc. Thanks for the answer Longarmx!

Why are you instantiating the TextureRegion inside the createQuad? Couldn't you just pass the same coordinates (here 0, 0, 128, 128) as u/v/u2/v2 ?

I ended up doing this like this:

1  
2  
3  
4  
5  
6  
7  
         TextureRegion region = textureAtlas.findRegion("regionName");

         quad.setVertices(new float[] { -1f, -1f, 0, region.getU(), region.getV2(), // bottom left
              1f, -1f, 0, region.getU2(), region.getV2(), // bottom right
              1f, 1f, 0, region.getU2(), region.getV(), // top right
              -1f, 1f, 0, region.getU(), region.getV() }); // top left
        quad.setIndices(new short[] { 0, 1, 2, 2, 3, 0 });


And I have created the TextureAtlas like in my previous example. This works all very well.

Now, If I need to create all 6 quads, the next question is do I have to pass the Material to ModelBulder each time I create a MeshPart like this:

1  
2  
builder.part("1", createQuad(),   GL10.GL_TRIANGLES, new Material("1", TextureAttribute.createDiffuse(myTexture)));
builder.part("2", createQuad(),   GL10.GL_TRIANGLES, new Material("2", TextureAttribute.createDiffuse(myTexture)));


Here I am passing the same texture possibly 6 times which I find a bit strange.

Cheers, Jaxes
Pages: [1]
  ignore  |  Print  
 
 

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Riven (7 views)
2014-07-29 18:09:19

Riven (5 views)
2014-07-29 18:08:52

Dwinin (8 views)
2014-07-29 10:59:34

E.R. Fleming (24 views)
2014-07-29 03:07:13

E.R. Fleming (10 views)
2014-07-29 03:06:25

pw (39 views)
2014-07-24 01:59:36

Riven (39 views)
2014-07-23 21:16:32

Riven (26 views)
2014-07-23 21:07:15

Riven (28 views)
2014-07-23 20:56:16

ctomni231 (59 views)
2014-07-18 06:55:21
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!