[Solved] Render to Texture

Started by Jameth13, March 22, 2014, 21:36:52

Previous topic - Next topic

Jameth13

Hi,

I am trying to render a texture so that it can be reused.

Currently I am drawing using:
for (Tuple2Int point: list){
	GL11.glBegin(GL11.GL_POINTS);
	GL11.glColor3f(1, 1, 1);
	GL11.glVertex2f(point.getX(), point.getY());
	GL11.glEnd();
	
}


Is there any way I can draw these points to a texture so that I can draw them again without using this loop and GL_POINTS?
I am looping through 640000 points so it is quite costly.


Thanks,
James

matanui159

Two suggestions:

  • use a vertex buffer object (vbo). They are just an array of vertices which you can draw latter. You can also use normals, colors and texCoords
  • use a frame buffer object (fbo). I haven't looked that much into these but you can draw on them. But I don't think you can convert it to a texture. But you can still draw on them and use them later.
Hopefully this helps :)
ALGORITHM
A word used by programmers when they do not want to explain what they did.

WEE :)

Jameth13

Thanks, matanui159!


I have learned to used VBO and have successfully drawn a triangle.

Here's my code:
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;

import java.nio.FloatBuffer;

public class VBO {
	
	public static void main(String[] args) {
		try {
			Display.setDisplayMode(new DisplayMode(800, 600));
			Display.setTitle("VBO");
			Display.create();
		} catch (LWJGLException e) {
			e.printStackTrace();
			Display.destroy();
			System.exit(0);
		}
		
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, Display.getWidth(), 0, Display.getHeight(), 1, -1);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
		GL11.glLoadIdentity();
		
		
		final int numVertices = 3;
		final int sizeVertex = 2;
		final int sizeColor = 3;
		
		FloatBuffer vertexData = BufferUtils.createFloatBuffer(numVertices * sizeVertex);
		vertexData.put(new float[]{200f, 200f,  400f, 400f,  400f, 200f});
		vertexData.flip();
		
		FloatBuffer colorData = BufferUtils.createFloatBuffer(numVertices * sizeColor);
		colorData.put(new float[]{1f, 0f, 0f,  0f, 1f, 0f,  0f, 0f, 1f});
		colorData.flip();
		
		int vboVertexHandle = GL15.glGenBuffers();
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboVertexHandle);
		GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertexData, GL15.GL_STATIC_DRAW);
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
		
		int vboColorHandle = GL15.glGenBuffers();
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboColorHandle);
		GL15.glBufferData(GL15.GL_ARRAY_BUFFER, colorData, GL15.GL_STATIC_DRAW);
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

		while (!Display.isCloseRequested()) {
			
			GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
			
			GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboVertexHandle);
			GL11.glVertexPointer(sizeVertex, GL11.GL_FLOAT, 0, 0L);
			
			GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboColorHandle);
			GL11.glColorPointer(sizeColor, GL11.GL_FLOAT, 0, 0L);
			
			GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
			GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
			GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, numVertices);
			GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
			GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
			
			Display.update();
			Display.sync(60);
			
		}

		GL15.glDeleteBuffers(vboVertexHandle);
		GL15.glDeleteBuffers(vboColorHandle);

		Display.destroy();
		System.exit(0);
		
	}
	
}


But when I try to replace it with this, I can't see any points.
final int numVertices = 1;
		final int sizeVertex = 2;
		final int sizeColor = 3;
		
		FloatBuffer vertexData = BufferUtils.createFloatBuffer(numVertices * sizeVertex);
		vertexData.put(new float[]{200f, 200f});
		vertexData.flip();
		
		FloatBuffer colorData = BufferUtils.createFloatBuffer(numVertices * sizeColor);
		colorData.put(new float[]{1f, 0f, 0f});
		colorData.flip();


I suspect it might be trying to draw something of size zero but I'm not sure how to fix that.

quew8

QuoteI suspect it might be trying to draw something of size zero but I'm not sure how to fix that.

If the drawing mode is still "GL_TRIANGLES" then that won't draw anything because you need 3 vertices per triangle. If it is "GL_POINTS" then you can change the diameter of the point with the glPointSize() function (http://www.opengl.org/sdk/docs/man2/xhtml/glPointSize.xml) but the diameter can't be 0 so I this won't stop anything from being drawn.

Quoteuse a frame buffer object (fbo). I haven't looked that much into these but you can draw on them. But I don't think you can convert it to a texture. But you can still draw on them and use them later.

@matanui159 is right in that you can draw on them but is wrong (kind of) in that they can be converted to a texture. Essentially a FBO is a thing you draw to which decides where the colour data actually goes. The default FBO sends the data to the screen buffer from where it gets sent to the monitor but you can create your own FBOs backed by OpenGL texture objects. You can use the texture as normal but whenever you have the FBO bound then anything you draw gets drawn to the texture rather than the screen.

There is a pretty good tutorial about them on the LWJGL wiki which does everything but explain what they are as I recall. So get it in your head what they are and what they do then read through that tutorial if you want to work with them.

Jameth13

QuoteIf the drawing mode is still "GL_TRIANGLES" then that won't draw anything because you need 3 vertices per triangle.

I never noticed the "GL_TRIANGLES". Thank you so much!