Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (482)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (550)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  Questions on VBO and adding geometry  (Read 4479 times)
0 Members and 1 Guest are viewing this topic.
Online opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Posted 2013-02-07 23:21:03 »

So I have some basic code that renders out a few cubes using a VBO. Now, I want to go a little more advanced and I want to remove and add cubes. I currently render my VBO like this:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
private void newChunk(){
      glBindBuffer(GL_ARRAY_BUFFER, vbo.vboVHandle);
      glVertexPointer(3, GL_FLOAT, 0, 0L);
     
      glBindBuffer(GL_ARRAY_BUFFER, vbo.vboCHandle);
      glColorPointer(3, GL_FLOAT, 0, 0);
     
      glEnableClientState(GL_VERTEX_ARRAY);
      glEnableClientState(GL_COLOR_ARRAY);
      for(int x = 0; x < var1; x++){
         for(int z = 0; z < var2; z++){
            for(int y = 0; y < var3; y++){
               glPushMatrix();
               glTranslatef(x, y, z);
               glDrawArrays(GL_QUADS, 0, 24);
               glPopMatrix();
            }
         }
      }
      glDisableClientState(GL_VERTEX_ARRAY);
      glDisableClientState(GL_COLOR_ARRAY);
   }

And heres my VBO initialization class:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
public class VBO {
   
   public int vboVHandle;

   public int vboCHandle;
   
   public float size = 0.5f;
   public float color = 0.5f;
   
    public FloatBuffer vertices;
   
    public VBO(){
   
    FloatBuffer colorData = BufferUtils.createFloatBuffer(3 * 4 * 6);
   colorData.put(new float[]{
         -color, color, color,
          color, color, color,
          -color, color, color,
          color, color, color,
         
          -color, color, color,
          color, color, color,
          -color, color, color,
          color, color, color,
         
          -color, color, color,
          color, color, color,
          -color, color, color,
          color, color, color,
         
          -color, color, color,
          color, color, color,
          -color, color, color,
          color, color, color,
         
          -color, color, color,
          color, color, color,
          -color, color, color,
          color, color, color,
         
          -color, color, color,
          color, color, color,
          -color, color, color,
          -color, color, color
   });
   colorData.flip();
   
   vertices = BufferUtils.createFloatBuffer(3 * 4 * 6);
    vertices.put(new float[] {
          -size, -size, size,
          size, -size, size,
          size, size, size,
          -size, size, size,
         
          -size, -size, -size,
          -size, size, -size,
          size, size, -size,
          size, -size, -size,
         
          -size, size, -size,
          -size, size, size,
          size, size, size,
          size, size, -size,
         
          -size, -size, -size,
          size, -size, -size,
          size, -size, size,
          -size, -size, size,
         
          size, -size, -size,
          size, size, -size,
          size, size, size,
          size, -size, size,
         
          -size, -size, -size,
          -size, -size, size,
          -size, size, size,
          -size, size, -size});
    vertices.flip();
   
    vboVHandle = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, vboVHandle);
    glBufferData(GL_ARRAY_BUFFER, vertices, GL_DYNAMIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);


    vboCHandle = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, vboCHandle);
    glBufferData(GL_ARRAY_BUFFER, colorData, GL_DYNAMIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
   
    }

}

Pretty basic. How would I go about actually removing or adding cubes? I know I have to use glMapBuffer and glUnMapBuffer, but how do I actually make an array of cubes and upload them to the VBO to be rendered? Also, I am currently rendering the cubes like this:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
glEnableClientState(GL_VERTEX_ARRAY);
      glEnableClientState(GL_COLOR_ARRAY);
      for(int x = 0; x < var1; x++){
         for(int z = 0; z < var2; z++){
            for(int y = 0; y < var3; y++){
               glPushMatrix();
               glTranslatef(x, y, z);
               glDrawArrays(GL_QUADS, 0, 24);
               glPopMatrix();
            }
         }
      }
      glDisableClientState(GL_VERTEX_ARRAY);
      glDisableClientState(GL_COLOR_ARRAY);

Which obviously renders one cube, just with different coords. How would I render multiple cubes instead of just one?
Thanks for any help!

Offline theagentd
« Reply #1 - Posted 2013-02-07 23:23:14 »

What's wrong with what you're currently doing?

Myomyomyo.
Online opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #2 - Posted 2013-02-07 23:25:56 »

I dont think anything is currently wrong, if you're talking about how I'm rendering the cubes. I've just heard people saying that you should render a new cube everytime instead of the same one at different coordinates.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline theagentd
« Reply #3 - Posted 2013-02-07 23:29:41 »

That depends on what you're doing. For static geometry then yes, go ahead and generate your cubes and store them in an array. For dynamic geometry, I wouldn't recommend it, at least not for cubes or anything more advanced than that. What are you expecting to gain?

EDIT: Also, negative color values?

Myomyomyo.
Online opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #4 - Posted 2013-02-07 23:36:39 »

My geometry will be dynamic. And I dont know what I expect to gain, I was just wondering if my way of doing it was wrong as I'm very new to VBOs. So how would you recommend me storing my cubes if you don't think an array would be good?

Offline theagentd
« Reply #5 - Posted 2013-02-07 23:47:59 »

I'd recommend that you merge the data into one VBO by interleaving the vertex attributes. Other than that, I don't see what's wrong with rendering them one by one like you're currently doing. Although you say your geometry will be dynamic, exactly what will you be rendering using cubes?

Myomyomyo.
Online opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #6 - Posted 2013-02-07 23:52:06 »

My terrain? Its a cube world, and I assume by static you mean never changing. If I'm wrong, please correct me!

Offline theagentd
« Reply #7 - Posted 2013-02-07 23:59:30 »

See this thread: http://www.java-gaming.org/index.php?topic=27868.0 It has some good points.

I would call a cube world static, since it only changes very rarely. 99.9% of all frames won't have anything changed, so there's no need to regenerate the data. Split up the world into subsections so you don't have to regenerate the world every time something changes. You'll also have to manually cull faces that aren't visible and do frustum culling, but it's all in the thread I linked.

Myomyomyo.
Online opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #8 - Posted 2013-02-08 00:10:52 »

Wow thank you, that will definetely help me out!

Offline theagentd
« Reply #9 - Posted 2013-02-08 00:13:54 »

Don't convert to display lists though. If you read the whole thread you'll see that display lists are deprecated now and all, so stick with VBOs. They're what you're supposed to use.

Myomyomyo.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Online opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #10 - Posted 2013-02-10 12:51:18 »

I read through that whole post, and I'm still a little confused on how to store all my vertex data in one VBO. Basically, what I want is to have a VBO with 16x16x16 cubes. Then I'll generate new chunks and translate the chunks to the correct position. When that's done, I want to draw the VBO in that chunk position, so I can avoid calling glTranslate a lot. I'm stuck on how I should store 4096 blocks in one VBO though. Should I make an array and then throw the array into the VBO?

Offline theagentd
« Reply #11 - Posted 2013-02-10 16:11:35 »

The definitive theoretical maximum of vertices is 16*16*16 cubes * 6 faces * 4 vertices = 98 304 vertices per chunk. Each vertex needs a 3D float position and an RGBA color, so you get a total of 12 + 4 = 16 bytes per vertex. In total, you need a ByteBuffer with a length of 1 572 864. (1.5MBs of data, it's actually almost nothing). Whenever the geometry of a chunk needs to be regenerated, use this buffer to prepare vertex data for the chunk. Just loop through the 16x16x16 chunk of cubes. For each cube, check if any of the cube's neighbors is air to see if it's visible. If it is, just generate vertex positions for that face (vertexPosition = chunkWorldPosition + localPositionInsideChunk + cubeVertex) and store their data in the buffer. When you're done (note: you'll end up with a LOT less data than the maximum capacity of the buffer in 99.999% of all cases.) just flip the buffer. Tadaah! You now have a perfectly fine buffer ready to be sent of to the GPU with glBufferData()!

Since the data is already translated, you can draw chunks with just a few lines of code later.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

for(int i = 0; i < numVisibleChunks; i++){
    Chunk c = getChunk(i);
    glBindBuffer(GL_ARRAY_BUFFER, c.getVBO());
    glVertexPointer(3, GL_FLOAT, 16, 0);
    glColorPointer(4, GL_UNSIGNED_BYTE, 16, 12);
    glDrawArrays(GL_TRIANGLES, 0, c.getNumVertices());
}

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);

Myomyomyo.
Online opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #12 - Posted 2013-02-27 21:01:33 »

Sorry for bumping the thread, but I have a few more questions!

1. Do you know of any good tutorials on how to texture 3d objects? I'm trying to texture my cubes now and I don't think using
1  
glBindTexture ()
would be a good idea. I have heard about texture atlases, but I'm confused on how to bind the textures to the cube and draw them. Can I use a VBO?

2.I want to be able to pick the cubes in the 3D world and delete or add more. Can I use ray tracing to figure out where the current mouse position is in the world? Or do I have to 'flatten' the image down so its 2D and then just use the mouse position to pick cubes that way? I would a then 'unflatten' the image so it looks 3D again of course. I feel like that would be horribly inefficient though!

Offline StumpyStrust
« Reply #13 - Posted 2013-02-27 21:25:08 »

I am not so good at modern stuff but the way you bind a texture is by calling that function. TextureAtlas has multiple textures on it so you can bind it once and then render without having to bind a different texture. You do this by specifying different texture coordinates. If you are using modern opengl you do not need texture atlases.

You could probably pack all your different cube textures into a single 512*512 or 1024*1024 texture if they are lower resolutions. That is you would have dirt, grass, water, etc all on one texture so there is only one bind call when you render your cubes. You can get away with quite a few texture binds and still stay at 60fps. I would say that as long as you do not bind a texture on every single cube you should be ok. Another thing you could do is have the current texture id saved and before binding a new one see if it matches the texture that is already bound that way you could reduce a bind call which may happen often.

I think the best way is to ray trace and pick the first cube it intersects with.

Online opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #14 - Posted 2013-02-27 21:29:37 »

Thank you! However, my problem is that I cannot find any tutorials on how to actually render the texture. Is there a way to use VBOs to draw textures?

Offline quew8

JGO Coder


Medals: 29



« Reply #15 - Posted 2013-02-27 21:56:21 »

Rendering textures is pretty much the same as plain colours.
Firstly make sure GL_TEXTURE_2D is enabled.
Then replace your per vertex colour values with texture coordinates.
Bind the texture.
Draw the primitive as per normal.
Online opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #16 - Posted 2013-02-28 19:39:04 »

Bind the texture as in calling
1  
glBindTexture()
? Sorry, I've never done this obviously Tongue

Offline Axeman

Senior Member


Medals: 7



« Reply #17 - Posted 2013-03-01 12:30:26 »

I want to add that I´m really new to this myself, but I sat with this all weekend, so I though I might share what I learned... Take a look at Davedes tutorial on how to load textures if you haven´t done that already:

https://github.com/mattdesl/lwjgl-basics/wiki/Textures

Then you basically create a new buffer the same way you did with colors, but instead of colors you add texturecoordinates:

1  
2  
3  
4  
5  
6  
7  
texCoordsData = BufferUtils.createFloatBuffer( **Enter buffersize here**);
texCoords.flip();

vboTextureHandle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboTextureHandleHandle);
glBufferData(GL_ARRAY_BUFFER, texCoordsData, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);


And then you enable GL_TEXTURE_COORD_ARRAY the same way as you did with color and vertex:

1  
glEnableClientState(GL_TEXTURE_COORD_ARRAY);


So it´s basically the same as vertex and color. Just make sure you bind the texture with before the drawmethod.

glBindTexture(GL_TEXTURE_2D, textureID);

I notice you don´t use glVertexPointer() or glColorPointer() method? I thought you had to use that to draw a VBO? Can someone share some insight..? Edit: Did not read all the code in the first post. So never mind me... Smiley
Online opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #18 - Posted 2013-03-18 01:56:30 »

So I'm stuck again! This time, I redesigned my chunk class for probably the fifth time, and now I come up with this error:
1  
Cannot use offsets when Array Buffer Object is disabled


Which means I'm not calling
 
1  
fglBindBuffer(target, buffer)


However, I believe I am. If someone could take a look at my code, I would be very grateful:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
public class BaseChunk {

   BaseBlock block;

   private FloatBuffer vHandle;

   int vboV;
   int vboT;

   int vertSize = 3;
   int vertAmount = 4;
   int faceAmount = 6;
   int blockAmount = 4096;

   int startX;
   int startZ;
   int startY;

   public static final int CHUNK_SIZE = 16;

   public static boolean isChunkActive = false;

   public BaseChunk(int startX, int startZ, int startY, boolean isChunkActive) {
      this.startX = startX;
      this.startZ = startZ;
      this.startY = startY;
      BaseChunk.isChunkActive = isChunkActive;

      vHandle = BufferUtils.createFloatBuffer(vertSize * vertAmount * faceAmount * blockAmount);
   }

   public void fillChunkWith(BlockType type) {
      for (int x = startX; x < CHUNK_SIZE; x++) {
         for (int z = startZ; z < CHUNK_SIZE; z++) {
            for (int y = 0; y < CHUNK_SIZE; y++) {
               vHandle.put(BaseBlock.getQuadRenderCoords(x, z, y, BaseBlock.OFFSET));
               block = new BaseBlock(type, x, z, y);
            }
         }
      }
      vHandle.flip();
      genBuffer(vboV);
      bindBuffer(vboV, vHandle);
      render();
   }

   public void bindBuffer(int vboV, FloatBuffer vHandle) {
      GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboV);
      GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vHandle, GL15.GL_STATIC_DRAW);
   }

   public void genBuffer(int vboV) {
      vboV = GL15.glGenBuffers();
   }

   public void render() {
      GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboV);
      glVertexPointer(3, GL_FLOAT, 0, 0L);

      glEnableClientState(GL_VERTEX_ARRAY);

      for (int x = 0; x < CHUNK_SIZE; x++) {
         for (int z = 0; z < CHUNK_SIZE; z++) {
            for (int y = 0; y < CHUNK_SIZE; z++) {
               glPushMatrix();
               glDrawArrays(GL_QUADS, 0, vertSize * vertAmount * faceAmount * blockAmount);
               glPopMatrix();
            }
         }
      }
      glDisableClientState(GL_VERTEX_ARRAY);
   }
}


Any suggestions?

Offline Vermeer

JGO Coder


Medals: 16



« Reply #19 - Posted 2013-03-19 12:57:44 »

Hi opi

Sorry I can't help you with you code, but I hope you get it sorted, and will keep popping back to see your progress. Look interesting and you are tackling similar problems to me.
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 781
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #20 - Posted 2013-03-19 13:03:21 »

1  
2  
3  
   public void genBuffer(int vboV) {
      vboV = GL15.glGenBuffers();
   }
This is highly suspicious code, as the value is written into a local variable, which is basically a no-op. The fact that there is also a field named 'vboV' doesn't change this.

Fix:
1  
2  
3  
   public void genBuffer() {
      vboV = GL15.glGenBuffers();
   }

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Vermeer

JGO Coder


Medals: 16



« Reply #21 - Posted 2013-03-19 19:17:00 »

1  
2  
3  
   public void genBuffer() {
      vboV = GL15.glGenBuffers();
   }


I was so interested to see this aproach, to have each chunk make a buffer... But no matter what I do, this line will not run...
error.........   115 is not a valid number in GL15 ?

So.... can each chunk make a buffer? and then render itself? That seems the most sensible, but it just will not work for me.... are you having any luck?
Online opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #22 - Posted 2013-03-19 20:00:29 »

1  
2  
3  
   public void genBuffer(int vboV) {
      vboV = GL15.glGenBuffers();
   }
This is highly suspicious code, as the value is written into a local variable, which is basically a no-op. The fact that there is also a field named 'vboV' doesn't change this.

Fix:
1  
2  
3  
   public void genBuffer() {
      vboV = GL15.glGenBuffers();
   }

I figured it out, I just forgot to call
1  
this.vboV
to actually reference the correct int.
As for your question Vermeer, I don't entirely understand what you're asking, but yes, you can create a chunk based on a buffer. I've seen your thread, and I would highly recommend switching over to VBOs, I generally get around 20 FPS more than you do with no optimizations (face culling, only rendering visible cubes).

Offline Vermeer

JGO Coder


Medals: 16



« Reply #23 - Posted 2013-03-22 20:30:44 »

Hi opi

Thanks for your positive comments. I hope you get time to work on yours soon!
Thanks to the suggestions you have posted in your thread I got VBO's working.

Will keep poping back to see how your getting on. Smiley
Online opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #24 - Posted 2013-03-22 20:32:17 »

Hi opi

Thanks for your positive comments. I hope you get time to work on yours soon!
Thanks to the suggestions you have posted in your thread I got VBO's working.

Will keep poping back to see how your getting on. Smiley
No problem! I think you're doing great, I'm actually very envious of how much work you're doing! I unfortunately will barely be able to code for the next couple of weeks at least, so don't expect much from me for a while :/

Keep up the good work!

Online opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #25 - Posted 2013-03-23 18:30:26 »

I tried to conquer textures this weekend, but it doesn't seem like they want to load. I create a new VBO to hold the block texture coordinates, bind the texture two different ways actually(maybe that's whats wrong), and then I create the VBO id for the the texture and call
1  
glEnableClientState(GL_TEXTURE_COORD_ARRAY)

Here's the full code:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
package com.nishu.mime.world;

import java.nio.FloatBuffer;

import static org.lwjgl.opengl.GL11.*;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL15;

import com.nishu.mime.blocks.BaseBlock;
import com.nishu.mime.blocks.BlockType;

public class BaseChunk {

   public BaseBlock blocks[][][] = new BaseBlock[CHUNK_SIZE][CHUNK_SIZE][CHUNK_SIZE];

   BaseBlock block;

   private FloatBuffer vHandle;
   private FloatBuffer tHandle;

   int vboV;
   int vboT;

   int vertSize = 3;
   int vertAmount = 4;
   int faceAmount = 6;
   int blockAmount = 4096;
   int currentBlockCount = 0;

   int startX;
   int startZ;
   int startY;

   int count = 0;

   public static final int CHUNK_SIZE = 16;

   public static boolean isChunkActive = false;
   boolean shouldRenderBlock = false;
   boolean facesVisible[] = new boolean[6];

   public BaseChunk(int startX, int startZ, int startY, boolean isChunkActive) {
      this.startX = startX;
      this.startZ = startZ;
      this.startY = startY;
      BaseChunk.isChunkActive = isChunkActive;

      vHandle = BufferUtils.createFloatBuffer(vertSize * vertAmount * faceAmount * blockAmount);
      tHandle = BufferUtils.createFloatBuffer(vertSize * vertAmount * faceAmount * blockAmount);
   }

   public void fillChunkWith(BlockType type) {
      isChunkActive = true;
      for (int x = startX; x < CHUNK_SIZE; x++) {
         for (int z = startZ; z < CHUNK_SIZE; z++) {
            for (int y = 0; y < CHUNK_SIZE; y++) {
               setBlock(type, x, z, y);
            }
         }
      }
      rebuildChunk(startX, startZ, startY);
   }

   public void rebuildChunk(int startX, int startZ, int startY) {
      boolean render;
      isChunkActive = true;
      int x = startX;
      int z = startZ;
      int y = startY;
      for (x = startX; x < CHUNK_SIZE; x++) {
         for (z = startZ; z < CHUNK_SIZE; z++) {
            for (y = startY; y < CHUNK_SIZE; y++) {
               render = checkFaces(x, z, y);
               if (render) {
                  vHandle.put(BaseBlock.getQuadRenderCoords(x, z, y, BaseBlock.OFFSET));
                  tHandle.put(BaseBlock.getQuadTextureCoords());
                  blocks[x][z][y].bindTexture(vboT);
               }
            }
         }
      }
      vHandle.flip();
      tHandle.flip();
      vboV = genBuffer(vboV);
      vboT = genBuffer(vboT);
      bindBuffer(vboV, vHandle);
      bindBuffer(vboT, tHandle);
      render();
   }

   private boolean checkFaces(int x, int z, int y) {
      if (x <= 0 || z <= 0 || y <= 0 || x >= CHUNK_SIZE || z >= CHUNK_SIZE || y >= CHUNK_SIZE) {
         for(int i = 0; i < 6; i++){
            facesVisible[i] = true;
         }
      }
      if (x > 0 && x < CHUNK_SIZE - 1 && getBlock(x + 1, z, y) != null) {
         facesVisible[0] = false;
      } else {
         facesVisible[0] = true;
      }
      if (x > 0 && x < CHUNK_SIZE && getBlock(x - 1, z, y) != null) {
         facesVisible[1] = false;
      } else {
         facesVisible[1] = true;
      }
      if (z > 0 && z < CHUNK_SIZE && getBlock(x, z - 1, y) != null) {
         facesVisible[2] = false;
      } else {
         facesVisible[2] = true;
      }
      if (z > 0 && z < CHUNK_SIZE - 1 && getBlock(x, z + 1, y) != null) {
         facesVisible[3] = false;
      } else {
         facesVisible[3] = true;
      }
      if (y > 0 && y < CHUNK_SIZE && getBlock(x, z, y - 1) != null) {
         facesVisible[4] = false;
      } else {
         facesVisible[4] = true;
      }
      if (y > 0 && y < CHUNK_SIZE - 1 && getBlock(x, z, y + 1) != null) {
         facesVisible[5] = false;
      } else {
         facesVisible[5] = true;
      }
      shouldRenderBlock = facesVisible[0] && facesVisible[1] && facesVisible[2] && facesVisible[3] && facesVisible[4] && facesVisible[5];
      if (shouldRenderBlock) {
         System.out.println("Rendering");
         currentBlockCount++;
         return true;
      } else {
         System.out.println("Not Rendering");
         return false;
      }
   }

   public void bindBuffer(int vboV, FloatBuffer vHandle) {
      GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboV);
      GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vHandle, GL15.GL_STATIC_DRAW);
     
      GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboT);
      GL15.glBufferData(GL15.GL_ARRAY_BUFFER, tHandle, GL15.GL_STATIC_DRAW);
   }

   public int genBuffer(int id) {
      return id = GL15.glGenBuffers();
   }

   public void render() {
      GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboV);
      glVertexPointer(3, GL_FLOAT, 0, 0L);
     
      GL15.glBindBuffer(GL15.GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, vboT);
      glVertexPointer(3, GL_FLOAT, 0, 0L);

      glEnableClientState(GL_VERTEX_ARRAY);
      glEnableClientState(GL_TEXTURE_COORD_ARRAY);

      glPushMatrix();
      glDrawArrays(GL_QUADS, 0, vertSize * vertAmount * faceAmount * currentBlockCount);
      glPopMatrix();
     
      glDisableClientState(GL_VERTEX_ARRAY);
      glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   }

   public BaseBlock getBlock(int x, int z, int y) {
      return blocks[x][z][y];
   }

   public void setBlock(BlockType type, int x, int z, int y) {
      blocks[x][z][y] = new BaseBlock(type, x, z, y, true);
   }
}

And here's the texture coords:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
public static float[] getQuadTextureCoords(){
      return new float[]{
             0, 0, 0,
             1, 0, 0,
             1, 0, 1,
             0, 0, 1,
             
             0, 0, 1,
             1, 0, 1,
             1, 1, 1,
             0, 1, 1,
             
             1, 0, 0,
             1, 1, 0,
             1, 1, 1,
             1, 0, 1,
             
             0, 1, 0,
             0, 0, 0,
             0, 0, 1,
             0, 1, 1,
             
             0, 1, 1,
             1, 1, 1,
             1, 1, 0,
             0, 1, 0,
             
             0, 1, 0,
             1, 1, 0,
             1, 0, 0,
             0, 0, 0
      };
   }

And my bind method:
1  
2  
3  
4  
public void bindTexture(int texID) {
      texture.bind();
      GL11.glBindTexture(GL11.GL_TEXTURE_2D, texID);
   }

What could I be doing wrong?

Offline Vermeer

JGO Coder


Medals: 16



« Reply #26 - Posted 2013-03-23 18:56:50 »

Hi. Will post code In my thread as asked.

But......texture coordinates only have 2 values, uv. Or(s,t)
You you putting 3 in?

The co-ordinaries are 2d for textures.
Online opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #27 - Posted 2013-03-23 18:57:34 »

Oh wow I am... how stupid of me Tongue Thanks for the code!

Online opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #28 - Posted 2013-03-24 17:49:58 »

So I tried to tackle textures today. I have a simple texture that looks like this:


However, when I apply the texture to the cubes, it looks like this:


Obviously I did something very wrong. I basically load the texture up using Slick, create a buffer that holds 2 * 3 * 6 * 4096 (vertex size, amount of vertices per face, faces, number of blocks in a chunk)  bytes or whatever you measure that in, bind the texture and put the data into the buffer. I then render it out. Here's the relevant code:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
public class BaseBlock {
     
   public static final int OFFSET = 1;

   private BlockType type;
   private Texture texture;
   private int x, z, y;
   private boolean isActive;

   public BaseBlock(BlockType type, int x, int z, int y, boolean isActive) {
      this.setType(type);
      this.x = x;
      this.z = z;
      this.y = y;
      this.setActive(isActive);
      try {
         this.texture = TextureLoader.getTexture("PNG", new FileInputStream(new File(type.tex_loc)));
      } catch (FileNotFoundException e) {
         System.err.println("Texture Location Not Found");
      } catch (IOException e) {
         System.err.println("Texture Not Loaded Correctly");
      }
   }

   public void bindTexture() {
      texture.bind();
   }

   public static float[] getQuadRenderCoords(int x, int z, int y, int offSet) {
      return new float[] { x, z, y,
                      x + offSet, z, y,
                      x + offSet, z, y + offSet,
                      x, z, y + offSet,
                     
                      x, z, y + offSet,
                      x + offSet, z, y + offSet,
                      x + offSet, z + offSet, y + offSet,
                      x, z + offSet, y + offSet,
                     
                      x + offSet, z, y,
                      x + offSet, z + offSet, y,
                      x + offSet, z + offSet, y + offSet,
                      x + offSet, z, y + offSet,
                     
                      x, z + offSet, y,
                      x, z, y,
                      x, z, y + offSet,
                      x, z + offSet, y + offSet,
                     
                      x, z + offSet, y + offSet,
                      x + offSet, z + offSet, y + offSet,
                      x + offSet, z + offSet, y,
                      x, z + offSet, y,
                     
                      x, z + offSet, y,
                      x + offSet, z + offSet, y,
                      x + offSet, z, y,
                      x, z, y };
   }
   
   public static float[] getQuadTextureCoords(){
      return new float[]{
             0, 0,
             1, 0,
             1, 1,
             0, 1,
             
             0, 0,
             1, 0,
             1, 1,
             0, 1,
             
             0, 0,
             1, 0,
             1, 1,
             0, 1,
             
             0, 0,
             1, 0,
             1, 1,
             0, 1,
             
             0, 0,
             1, 0,
             1, 1,
             0, 1,
             
             0, 0,
             1, 0,
             1, 1,
             0, 1,
             
      };
   }


Part of my chunk class:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
public BaseChunk(int startX, int startZ, int startY, boolean isChunkActive) {
      this.startX = startX;
      this.startZ = startZ;
      this.startY = startY;
      BaseChunk.isChunkActive = isChunkActive;

      vHandle = BufferUtils.createFloatBuffer(vertSize * vertAmount * faceAmount * blockAmount);
      tHandle = BufferUtils.createFloatBuffer(texSize * vertAmount * faceAmount * blockAmount);
   }

   public void fillChunkWith(BlockType type) {
      isChunkActive = true;
      System.out.println(startX);
      for (int x = startX; x < CHUNK_SIZE; x++) {
         for (int z = startZ; z < CHUNK_SIZE; z++) {
            for (int y = 0; y < CHUNK_SIZE; y++) {
               setBlock(type, x, z, y);
            }
         }
      }
      rebuildChunk(startX, startZ, startY);
   }

   public void rebuildChunk(int startX, int startZ, int startY) {
      boolean render;
      isChunkActive = true;
      int x = startX;
      int z = startZ;
      int y = startY;
      for (x = startX; x < CHUNK_SIZE; x++) {
         for (z = startZ; z < CHUNK_SIZE; z++) {
            for (y = startY; y < CHUNK_SIZE; y++) {
               render = checkFaces(x, z, y);
               if (render) {
                  vHandle.put(BaseBlock.getQuadRenderCoords(x, z, y, BaseBlock.OFFSET));
                  tHandle.put(BaseBlock.getQuadTextureCoords());
                  blocks[x][z][y].bindTexture();
               }
            }
         }
      }
      vHandle.flip();
      tHandle.flip();
      vboV = genBuffer(vboV);
      vboT = genBuffer(vboT);
      bindBuffer(vboV, vHandle);
      bindBuffer(vboT, tHandle);
      render();
   }

Then how I render:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
public void bindBuffer(int vboV, FloatBuffer vHandle) {
      GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboV);
      GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vHandle, GL15.GL_STATIC_DRAW);
     
      GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboT);
      GL15.glBufferData(GL15.GL_ARRAY_BUFFER, tHandle, GL15.GL_STATIC_DRAW);
   }

   public int genBuffer(int id) {
      return id = GL15.glGenBuffers();
   }

   public void render() {
      GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboV);
      glVertexPointer(vertSize, GL_FLOAT, 0, 0L);
     
      GL15.glBindBuffer(GL15.GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, vboT);
      glTexCoordPointer(2, GL_FLOAT, 0, 0L);

      glEnableClientState(GL_VERTEX_ARRAY);
      glEnableClientState(GL_TEXTURE_COORD_ARRAY);

      glPushMatrix();
      glDrawArrays(GL_QUADS, 0, vertSize * vertAmount * faceAmount * currentBlockCount);
      glPopMatrix();
     
      glDisableClientState(GL_VERTEX_ARRAY);
      glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   }

Could it be because I didn't wrap the texture? Is the texture not the right resolution? Its 16 * 16, but the block size is currently set at 1.

Online opiop65

JGO Kernel


Medals: 154
Projects: 7
Exp: 3 years


JumpButton Studios


« Reply #29 - Posted 2013-03-24 18:21:49 »

I figured one thing out, I changed this:
1  
glTexCoordPointer(2, GL_FLOAT, 0, 0L);

to this:
1  
glTexCoordPointer(3, GL_FLOAT, 0, 0L);

But now only one side of the blocks have textures. When I render out a skybox in immediate mode with the same texture coords, it works fine. So whats wrong with my VBO?

Pages: [1] 2
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

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

The first screenshot will be displayed as a thumbnail.

CopyableCougar4 (14 views)
2014-08-22 19:31:30

atombrot (28 views)
2014-08-19 09:29:53

Tekkerue (25 views)
2014-08-16 06:45:27

Tekkerue (23 views)
2014-08-16 06:22:17

Tekkerue (15 views)
2014-08-16 06:20:21

Tekkerue (22 views)
2014-08-16 06:12:11

Rayexar (61 views)
2014-08-11 02:49:23

BurntPizza (39 views)
2014-08-09 21:09:32

BurntPizza (31 views)
2014-08-08 02:01:56

Norakomi (37 views)
2014-08-06 19:49:38
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!