Hello everyone!
I just made a immediate-mode style Vertex-Array drawer, and thought some of you might find it useful.
Here it is (Only depency is LWJGL):
import java.nio.FloatBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
/**
This class is distributed under the WTFPL-License!
Do with it what you want!
Its free!
**/
public class ImmediateDrawerVA {
public static final ImmediateDrawerVA tessellator = new ImmediateDrawerVA();
FloatBuffer vertexBuffer;
FloatBuffer colorBuffer;
FloatBuffer textureBuffer;
int vertexCount = 0;
int drawMode = -1;
float r = 1;
float g = 1;
float b = 1;
float offX = 0;
float offY = 0;
float offZ = 0;
float s = 0;
float t = 0;
boolean useColor = false;
boolean useUV = false;
boolean isDrawing = false;
private ImmediateDrawerVA(){
this.vertexBuffer = BufferUtils.createFloatBuffer(1024 * 1024);
this.colorBuffer = BufferUtils.createFloatBuffer(1024 * 1024);
this.textureBuffer = BufferUtils.createFloatBuffer(1024 * 1024);
this.reset();
}
/**
* Starts drawing.
*
* @param mode The OpenGL Geometry Mode to use for this draw.
* @throws RuntimeException If the ImmediateDrawer was already drawing.
**/
public void startDrawing(int mode){
if(this.isDrawing)
throw new RuntimeException("Tessellator is already drawing!");
this.reset();
this.drawMode = mode;
this.isDrawing = true;
}
/**
* Sets the UV-Coordinates for the next vertex to draw. (Has to be called in between start/stop!)
**/
public void setUV(float u, float v){
this.s = u;
this.t = v;
this.useUV = true;
}
/**
* Sets the Color for the next vertex to draw. (Has to be called in between start/stop!)
**/
public void setColor(float r,float g,float b){
this.r = r;
this.g = g;
this.b = b;
this.useColor = true;
}
/**
* Sets the Position-Offset for the next vertex to draw. (Has to be called in between start/stop!)
**/
public void setVertexOffset(float x, float y, float z){
this.offX = x;
this.offY = y;
this.offZ = z;
}
/**
* Draws a vertex with a UV-Coordinate. (Has to be called in between start/stop!)
*
* @param x The x-position of the vertex.
* @param y The y-position of the vertex.
* @param z The z-position of the vertex.
*
* @param u The u-texCoord of the vertex.
* @param v The v-texCoord of the vertex.
**/
public void drawVertWithUV(float x, float y, float z, float u, float v){
this.setUV(u,v);
this.drawVert(x,y,z);
}
/**
* Draws a vertex. (Has to be called in between start/stop!)
*
* @param x The x-position of the vertex.
* @param y The y-position of the vertex.
* @param z The z-position of the vertex.
**/
public void drawVert(float x, float y, float z){
this.vertexBuffer.put(x + this.offX);
this.vertexBuffer.put(y + this.offY);
this.vertexBuffer.put(z + this.offZ);
this.colorBuffer.put(this.r);
this.colorBuffer.put(this.g);
this.colorBuffer.put(this.b);
this.textureBuffer.put(this.s);
this.textureBuffer.put(this.t);
this.vertexCount++;
}
/**
* Stops drawing.
**/
public void stopDrawing(){
if(this.vertexCount == 0){
this.reset();
return;
}
this.vertexBuffer.rewind();
this.colorBuffer.rewind();
this.textureBuffer.rewind();
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glVertexPointer(3, /* stride */3 << 2, this.vertexBuffer);
if(this.useColor){
GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
GL11.glColorPointer(3, /* stride */3 << 2, this.colorBuffer);
}
if(this.useUV){
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL11.glTexCoordPointer(2, /* stride */2 << 2, this.textureBuffer);
}
GL11.glDrawArrays(this.drawMode, 0, this.vertexCount);
GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
if(this.useColor)
GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
if(this.useUV)
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
this.reset();
}
// Do NOT call this method directly!
private void reset() {
this.vertexCount = 0;
this.drawMode = -1;
this.offX = 0;
this.offY = 0;
this.offZ = 0;
this.r = 1;
this.g = 1;
this.b = 1;
this.s = 0;
this.t = 0;
this.useColor = false;
this.useUV = false;
this.isDrawing = false;
this.vertexBuffer.clear();
this.colorBuffer.clear();
this.textureBuffer.clear();
}
/**
* Returns true if this tessellator is drawing, false if not.
**/
public boolean isDrawing() {
return this.isDrawing;
}
}
And this is how you use it:
ImmediateDrawerVA tess = ImmediateDrawerVA.instance;
tess.startDrawing(GL11.GL_QUADS);
tess.setColor(1, 1, 1);
tess.drawVertWithUV(0, 0, 0, 0, 0);
tess.drawVertWithUV(1, 0, 0, 0, 0);
tess.setColor(0, 0, 0);
tess.drawVertWithUV(1, 1, 0, 0, 0);
tess.drawVertWithUV(0, 1, 0, 0, 0);
tess.stopDrawing();
This class should work instantly and without any problems.
Its mostly useful to LWJGL newbies and everyone who is wondering how the heck to use these Vertex-Array’s.
If I made some mistake in the rendering code, or you find a bug, please tell me, as I want to use this class in my applications.
- Longor1996