Texture and intervaling VBO

Started by Akinesis, April 21, 2014, 14:53:53

Previous topic - Next topic

Akinesis

Hello every one, first of all i shouèld apologize for my inglish. I'm french an still fighting with the language of shakespeare.

The reason i came here is that i have a problem with opengl's VBO and intervaling triangles coordinates with texture coordinates.

The class file i'm going to show you is a desperate attempt to make the things work. In did i am working on a more lager project of voxel base game ben since i try implementing VBO ... nothing works anymore. So i made a separate class which should draw a simple triangle and apply a texture on it.

If someone could take a look at my code an tell me what am i doing wrong (probably a lot), i would be very grateful.

package triangle;

import static org.lwjgl.opengl.GL11.GL_BLEND;
import static org.lwjgl.opengl.GL11.GL_CULL_FACE;
import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST;
import static org.lwjgl.opengl.GL11.GL_MODELVIEW;
import static org.lwjgl.opengl.GL11.GL_NEAREST;
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
import static org.lwjgl.opengl.GL11.GL_PROJECTION;
import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
import static org.lwjgl.opengl.GL11.glBlendFunc;
import static org.lwjgl.opengl.GL11.glDrawArrays;
import static org.lwjgl.opengl.GL11.glEnable;
import static org.lwjgl.opengl.GL11.glLoadIdentity;
import static org.lwjgl.opengl.GL11.glMatrixMode;
import static org.lwjgl.opengl.GL11.glRotatef;
import static org.lwjgl.opengl.GL11.glTexParameteri;
import static org.lwjgl.opengl.GL11.glTranslatef;
import static org.lwjgl.util.glu.GLU.gluPerspective;

import java.io.IOException;
import java.nio.FloatBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.util.vector.Vector3f;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;

public class Triangles {

	private Texture texture;
	private FloatBuffer textureData;
	private Vector3f position, rotation;
	private int vboVertexHandleChunk;
	private FloatBuffer interleavedBuffer;
	private int floatByteSize = 4;
	private int positionFloatCount = 3;
	private int floatsPerVertex = positionFloatCount*2;
	private int vertexFloatSizeInBytes = floatByteSize * floatsPerVertex;
	private int texId;

	public Triangles(){
		this.initDisplay();
		this.openGL();
		position = new Vector3f(0f, 0, 0);
		rotation = new Vector3f(0, 0, 0);
	}

	public static void main(String[] args) {
		Triangles test = new Triangles();
		test.openImage();

		test.renderLoop();

	}

	private void openGL(){
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(50, 800/600, 0.01f, 20);
		glMatrixMode(GL_MODELVIEW);	
		glEnable(GL_DEPTH_TEST);
		glEnable(GL_CULL_FACE);
		glEnable(GL_TEXTURE_2D);
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glLoadIdentity();


	}

	public void initDisplay(){
		try{
			Display.setResizable(true);
			Display.setDisplayMode(new DisplayMode((int)800, (int)600));
			Display.setTitle("Dino Survive");
			Display.create();
		} catch (LWJGLException e) {
			e.printStackTrace();
			Display.destroy();
			System.exit(1);
		}

		Mouse.setGrabbed(false);
	}

	private void renderLoop(){
		genCubes();
		genTexture();
		
		genVBO();
		
		while(!Display.isCloseRequested()){
		
			useView();
			input();
			drawCube();
			 
			Display.sync(60);
			Display.update();
		}

		Display.destroy();
	}

	private void openImage(){
		try {
			texture = TextureLoader.getTexture("PNG",
					ResourceLoader.getResourceAsStream("../DinoSurvive/res/text.png"));
		} catch (IOException e) {
			e.printStackTrace();
		}

		textureData = BufferUtils.createFloatBuffer(3 * 2);
		textureData.put(this.genTex());
		textureData.flip();
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	}

	private float[] genOne(){
		return new float[]{
				//south
				0, 0, 3,
				-1, 0, 3,
				-1, -1, 3};			
	}

	private float[] genTex(){
		return new float[]{
				//south
				0.03125f+0, 0.03125f+0,
				0.03125f+0, 0+0,
				0+0, 0.03125f+0};
	}

	private void useView(){
		glRotatef(rotation.x, 1, 0, 0);
		glRotatef(rotation.y, 0, 1, 0);
		glRotatef(rotation.z, 0, 0, 1);
		glTranslatef(position.x, position.y, position.z);
		System.out.println(position);
	}

	private void input(){
		float mouseDX = Mouse.getDX() * 1 * 0.16f;
		float mouseDY = Mouse.getDY() * 1 * 0.16f;

		//mouvement de la souris
		if(Mouse.isGrabbed()){
			if (rotation.y + mouseDX >= 360) {
				rotation.y = (rotation.y + mouseDX - 360);
			} else if (rotation.y + mouseDX < 0) {
				rotation.y = (360 - rotation.y + mouseDX);
			} else {
				rotation.y += mouseDX;
			}if (rotation.x - mouseDY >= -85 && rotation.x - mouseDY <= 85) {
				rotation.x += -mouseDY;
			} else if (rotation.x - mouseDY < -85) {
				rotation.x = -85;
			} else if (rotation.x - mouseDY > 85) {
				rotation.x = 85;
			}
		}

		while(Keyboard.next()){
			if(Keyboard.isKeyDown(Keyboard.KEY_RETURN)){
				Mouse.setGrabbed(!Mouse.isGrabbed());
			}
		}
	}

	private void genVBO(){
		vboVertexHandleChunk = GL15.glGenBuffers();
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboVertexHandleChunk);
		GL15.glBufferData(GL15.GL_ARRAY_BUFFER, interleavedBuffer, GL15.GL_STATIC_DRAW);

		// -- Now we can split our interleaved data over 2 attribute lists
		// First up is our positional information in list 0
		GL20.glVertexAttribPointer(0, positionFloatCount, GL11.GL_FLOAT, false,
				vertexFloatSizeInBytes, 0);

		// Second is our texture information in list 1, for this we also need the offset
		int byteOffset = floatByteSize * positionFloatCount;
		GL20.glVertexAttribPointer(1, positionFloatCount, GL11.GL_FLOAT, false,
				vertexFloatSizeInBytes, byteOffset);

		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
		GL30.glBindVertexArray(0);

	}

	private void genCubes(){
		interleavedBuffer = BufferUtils.createFloatBuffer(3*2+9);
		interleavedBuffer.put(this.genOne());
		interleavedBuffer.put(this.genTex());
		interleavedBuffer.flip();
	}
	
	private void genTexture(){
		texId = GL11.glGenTextures();
		GL13.glActiveTexture(GL13.GL_TEXTURE0);
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, texId);
		
		// All RGB bytes are aligned to each other and each component is 1 byte
		GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
		
		// Setup the ST coordinate system
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
	}
	
	
	
	private void drawCube(){
		GL13.glActiveTexture(GL13.GL_TEXTURE0);
		GL11.glBindTexture(GL11.GL_TEXTURE_2D, texId);
		
		GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboVertexHandleChunk);
		glDrawArrays(GL_TRIANGLES, 0, 3*3+2*3);
		
		GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
	}

}

abcdef

I have no idea what your error is but looking at your vertex attrib code things look to be wrong

You have

GL20.glVertexAttribPointer(0, positionFloatCount, GL11.GL_FLOAT, false,vertexFloatSizeInBytes, 0);
int byteOffset = floatByteSize * positionFloatCount;
GL20.glVertexAttribPointer(1, positionFloatCount, GL11.GL_FLOAT, false,vertexFloatSizeInBytes, byteOffset);

I don't think you understand the variables here

The first parameter is the id which you reference in your shader. You have the right values here.
The second parameter is the size of the parameter, in your case this is 3 for the vertex (x,y,x) and 2 for the texture coordinate (s,t), you have the positionFloatCount and this is wrong.
The third parameter describes the the type for the data, you have the right value here.
The forth parameter says whether you want to normalise the data (which you don't most of the time)
The fifth parameter is the offset which says where in the data to start finding this data. It looks to me that vertex data starts at 0 and the texture coordinates start at 9 because your data is tightly packed. If it wan't tightly packed you you provide the offset for where the data is per stride.
The sixth parameter is stride, if the data is tightly packed then this should be 0 (Tightly packed = V V V T T T (V=Vertex T=Tecture Coordinate), non tightly packed would be V T V T V T)

So I'd change

GL20.glVertexAttribPointer(0, positionFloatCount, GL11.GL_FLOAT, false,vertexFloatSizeInBytes, 0); to
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false,0, 0);

and

GL20.glVertexAttribPointer(1, positionFloatCount, GL11.GL_FLOAT, false,vertexFloatSizeInBytes, byteOffset); to
GL20.glVertexAttribPointer(1, 2, GL11.GL_FLOAT, false,9, 0);

Akinesis

Hi !

First of all, thank you for the answer, you've help me to understand a little bit more on the VBO and it's now a little less messy. I've tried what you suggest and still nothing is happening (the display appear but nothing on it, just the infinite black screen of my despair).

Considering it's bytebuffer, should i not multiply by 4 (the size of a float in bytes) ?

Thank you again for taking the time the respond to me.

abcdef

You also don't clear the depth and color bits during the render cycle

You don't have a shader that can intepret what indexes 0 and 1 are in your vertex attrib pointer and that can take your texture and render it.

There is quite a lot wrong and probably more that my quick second look :) I'd recommend reading some opengl tutorials to learn how the flow works and what you need to fill in to get things to work.