Interleaved VBO problems.

So I got this code. I get black screen as my output. When I render with immediate rendering mode, works nice and all that. With this code, I get black screen.


			int size = assets.size();
			int vertices = 4;
			int vertexSize = 2;
			int textureSize = 2;
			int colorSize = 4;

			int overallSize = size * (vertices * (vertexSize + textureSize + colorSize));

			FloatBuffer buffer = BufferUtils.createFloatBuffer(overallSize);

			for (Asset asset : assets) {

				// class Asset contains: float x, y, width, height, px, py, rot; Sprite sprite; Color color;
				
				Rect rect = new Rect(asset.x, asset.y, asset.width, asset.height); // contains 4 vertices, 8 points. x0, y0, x1, y1, x2, y2, x3, y3
				rect.rotate(asset.rot, new vec2(asset.px, asset.py));

				Sprite sprite = asset.sprite; // contains: int width, height; SpriteSheet sheet;
				
				//SpriteSheet is basically a class which contains texture handle.
				
				float x0 = (1f / sprite.sheet.width) * sprite.width * sprite.x; // Texture position x0
				float y0 = (1f / sprite.sheet.height) * sprite.height * sprite.y; // Texture position y0

				float x1 = (1f / sprite.sheet.width) * sprite.width * (sprite.x + 1); // Texture position x1
				float y1 = (1f / sprite.sheet.height) * sprite.height * (sprite.y + 1); // Texture position y1

				Color color = asset.color; // contains r,g,b,a floats.
				
				
				
				buffer.put(rect.x0).put(rect.y0);
				buffer.put(x0).put(y0);
				buffer.put(color.r).put(color.g).put(color.b).put(color.a);
				
				buffer.put(rect.x1).put(rect.y1);
				buffer.put(x1).put(y0);
				buffer.put(color.r).put(color.g).put(color.b).put(color.a);
				
				buffer.put(rect.x2).put(rect.y2);
				buffer.put(x1).put(y1);
				buffer.put(color.r).put(color.g).put(color.b).put(color.a);
				
				buffer.put(rect.x3).put(rect.y3);
				buffer.put(x0).put(y1);
				buffer.put(color.r).put(color.g).put(color.b).put(color.a);
				
			}

			for (Asset asset : assets) {
				
			}

			for (Asset asset : assets) {
				
			}

			SpriteSheet.sheet.bind(); // Bind the texture.
			
			glBindBuffer(target, handle);
			glBufferData(target, buffer, GL_STATIC_DRAW);

			glEnableClientState(GL_VERTEX_ARRAY);
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glEnableClientState(GL_COLOR_ARRAY);

//			x1, y1, s1, t1, r1, g1, b1, a1, x2, y2,
			int stride = 8 * 4;
			glVertexPointer(vertexSize, GL_FLOAT, stride, 0L);
			glTexCoordPointer(textureSize, GL_FLOAT, stride, 8L);
			glColorPointer(colorSize, GL_FLOAT, stride, 16L);
			
			glDrawArrays(GL_QUADS, 0, size * vertices);

			glDisableClientState(GL_VERTEX_ARRAY);
			glDisableClientState(GL_TEXTURE_COORD_ARRAY);
			glDisableClientState(GL_COLOR_ARRAY);

I will post a fix if I find it before someone helps me.

Rewind the buffer before sending to OpenGL.


buffer.rewind();

Thanks, forgot that part again… However, it didn’t solve the problem. :’(

Does [icode]assets.size()[/icode] return the amount of assets? Shouldn’t you call [icode]assets.length[/icode] instead? I can’t see an issue otherwise.

It is a List. It is not an array.

Oops that was stupid of me to say. I forgot that lists return the length from size().
I can’t see a problem with your code; I’m pretty sure that it should work. Are you sure that your vertices/texture coordinates are between the ranges -1 and 1?

Well with this rendering code, everything works fine.

			Rect rect = new Rect(x, y, width, height);
			rect.rotate(rotation, new vec2(px, py));

			glColor4f(color.r, color.g, color.b, color.a);

			float x0 = (1f / sprite.sheet.width) * sprite.width * sprite.x;
			float y0 = (1f / sprite.sheet.height) * sprite.height * sprite.y;

			float x1 = (1f / sprite.sheet.width) * sprite.width * (sprite.x + 1);
			float y1 = (1f / sprite.sheet.height) * sprite.height * (sprite.y + 1);

			glTexCoord2f(x0, y0);
			glVertex2f(rect.x0 + xo, rect.y0 + yo);

			glTexCoord2f(x1, y0);
			glVertex2f(rect.x1 + xo, rect.y1 + yo);

			glTexCoord2f(x1, y1);
			glVertex2f(rect.x2 + xo, rect.y2 + yo);

			glTexCoord2f(x0, y1);
			glVertex2f(rect.x3 + xo, rect.y3 + yo);

if you’re saying code looks fine, I will just have to look for some stupid little error :stuck_out_tongue:

Vertex coordinates don’t have to be constrained to -1 - 1. They can be as large as you like.

Yes, but NDCs range from -1 to 1. I assumed the OP wasn’t using glOrtho or managing his own matrices, but if he was and he was ranging his co-ordinates between -1 and 1, maybe that’s his issue.

I can create single VBOs just fine. The problem comes when I try to make an interleaved VBO. Just doesn’t work :’(

I only know some basics about OpenGL, but


glVertexPointer(vertexSize, GL_FLOAT, stride, 0L);
glTexCoordPointer(textureSize, GL_FLOAT, stride, 8L); // 8L should be a pointer to the first vertex in the array
// so it might have to be (first tex coord location * bytes in a float) = (3 * 4) = 12 instead.
glColorPointer(colorSize, GL_FLOAT, stride, 16L); // Same here, should be (5 * 4) = 20 instead

Source: http://www.opengl.org/sdk/docs/man2/xhtml/glVertexPointer.xml

Hope this helps. :smiley:

Best. Post. Ever.

Mike

The stride is the length of the tuple in bytes. So since your tuple is


.... b, a, {x, y, s, t, r, g, b, a}, x, y ....

The number of elements in each tuple is 8 and 4 is the size of a float in bytes. So [icode]stride[/icode] will be 8*4 which is 32. You got it right.

Now let’s see about the [icode]offset[/icode], it’s the location of first vertex in the array. So for your tuple,


// The first ones in your tuple is the vertex info
SO OFFSET IS 0

// Next comes the texture coordinates which start after the two vertex coordinates
SO OFFSET IS 3*4 WHICH IS 12

// Next there are colour coordinates which start after two vertex coordinates
// and two texture coordinates.
SO OFFSET IS 5*4 WHICH IS 20

So you change the following code


glVertexPointer(vertexSize, GL_FLOAT, stride, 0L);
glTexCoordPointer(textureSize, GL_FLOAT, stride, 8L);
glColorPointer(colorSize, GL_FLOAT, stride, 16L);

To the following code.


glVertexPointer(vertexSize, GL_FLOAT, stride, 0L);
glTexCoordPointer(textureSize, GL_FLOAT, stride, 12L);
glColorPointer(colorSize, GL_FLOAT, stride, 20L);

Hope this solves your problem.

Thanks. I really ought to add the shader / vertex-attributes way, one day. :point:

trollwarrior1s offsets and strides are correct. It’s indeed 0,8,16 with a stride of 32. :point: