/src/minecraft/org/newdawn/slick/opengl/renderer/VAOGLRenderer.java
https://github.com/copyliu/Spoutcraft_CJKPatch · Java · 417 lines · 237 code · 57 blank · 123 comment · 23 complexity · 03dc6463e90986ef2d870dabea7080aa MD5 · raw file
- package org.newdawn.slick.opengl.renderer;
- import java.nio.DoubleBuffer;
- import java.nio.FloatBuffer;
- import org.lwjgl.BufferUtils;
- import org.lwjgl.opengl.GL11;
- /**
- * A renderer that caches all operations into an array, creates an opengl vertex array when
- * required and spits the data down to the card in batch mode
- *
- * @author kevin
- */
- public class VAOGLRenderer extends ImmediateModeOGLRenderer {
- /** The tolerance to rendering immediate */
- private static final int TOLERANCE = 20;
- /** Indicates there is no current geometry buffer */
- public static final int NONE = -1;
- /** The maximum number of vertices draw in one batch */
- public static final int MAX_VERTS = 5000;
-
- /** The type of the geometry array currently being built - i.e. GL_QUADS */
- private int currentType = NONE;
- /** The last colour applied */
- private float[] color = new float[] {1f,1f,1f,1f};
- /** The last texture applied */
- private float[] tex = new float[] {0f,0f};
- /** The index of the next vertex to be created */
- private int vertIndex;
-
- /** The vertex data cached */
- private float[] verts = new float[MAX_VERTS*3];
- /** The vertex colour data cached */
- private float[] cols = new float[MAX_VERTS*4];
- /** The vertex texture coordiante data cached */
- private float[] texs = new float[MAX_VERTS*3];
-
- /** The buffer used to pass the vertex data to the card */
- private FloatBuffer vertices = BufferUtils.createFloatBuffer(MAX_VERTS * 3);
- /** The buffer used to pass the vertex color data to the card */
- private FloatBuffer colors = BufferUtils.createFloatBuffer(MAX_VERTS * 4);
- /** The buffer used to pass the vertex texture coordinate data to the card */
- private FloatBuffer textures = BufferUtils.createFloatBuffer(MAX_VERTS * 2);
-
- /** The stack for entering list creation mode - when we're creating a list we can't use our VAs */
- private int listMode = 0;
-
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#initDisplay(int, int)
- */
- public void initDisplay(int width, int height) {
- super.initDisplay(width, height);
-
- startBuffer();
- GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
- GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
- GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
- }
- /**
- * Start a new buffer for a vertex array
- */
- private void startBuffer() {
- vertIndex = 0;
- }
-
- /**
- * Flush the currently cached data down to the card
- */
- private void flushBuffer() {
- if (vertIndex == 0) {
- return;
- }
- if (currentType == NONE) {
- return;
- }
-
- if (vertIndex < TOLERANCE) {
- GL11.glBegin(currentType);
- for (int i=0;i<vertIndex;i++) {
- GL11.glColor4f(cols[(i*4)+0], cols[(i*4)+1], cols[(i*4)+2], cols[(i*4)+3]);
- GL11.glTexCoord2f(texs[(i*2)+0], texs[(i*2)+1]);
- GL11.glVertex3f(verts[(i*3)+0], verts[(i*3)+1], verts[(i*3)+2]);
- }
- GL11.glEnd();
- currentType = NONE;
- return;
- }
- vertices.clear();
- colors.clear();
- textures.clear();
-
- vertices.put(verts,0,vertIndex*3);
- colors.put(cols,0,vertIndex*4);
- textures.put(texs,0,vertIndex*2);
-
- vertices.flip();
- colors.flip();
- textures.flip();
-
- GL11.glVertexPointer(3,0,vertices);
- GL11.glColorPointer(4,0,colors);
- GL11.glTexCoordPointer(2,0,textures);
-
- GL11.glDrawArrays(currentType, 0, vertIndex);
- currentType = NONE;
- }
-
- /**
- * Apply the current buffer and restart it
- */
- private void applyBuffer() {
- if (listMode > 0) {
- return;
- }
-
- if (vertIndex != 0) {
- flushBuffer();
- startBuffer();
- }
-
- super.glColor4f(color[0], color[1], color[2], color[3]);
- }
-
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#flush()
- */
- public void flush() {
- super.flush();
-
- applyBuffer();
- }
-
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glBegin(int)
- */
- public void glBegin(int geomType) {
- if (listMode > 0) {
- super.glBegin(geomType);
- return;
- }
-
- if (currentType != geomType) {
- applyBuffer();
- currentType = geomType;
- }
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glColor4f(float, float, float, float)
- */
- public void glColor4f(float r, float g, float b, float a) {
- a *= alphaScale;
-
- color[0] = r;
- color[1] = g;
- color[2] = b;
- color[3] = a;
-
- if (listMode > 0) {
- super.glColor4f(r,g,b,a);
- return;
- }
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glEnd()
- */
- public void glEnd() {
- if (listMode > 0) {
- super.glEnd();
- return;
- }
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glTexCoord2f(float, float)
- */
- public void glTexCoord2f(float u, float v) {
- if (listMode > 0) {
- super.glTexCoord2f(u,v);
- return;
- }
-
- tex[0] = u;
- tex[1] = v;
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glVertex2f(float, float)
- */
- public void glVertex2f(float x, float y) {
- if (listMode > 0) {
- super.glVertex2f(x,y);
- return;
- }
-
- glVertex3f(x,y,0);
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glVertex3f(float, float, float)
- */
- public void glVertex3f(float x, float y, float z) {
- if (listMode > 0) {
- super.glVertex3f(x,y,z);
- return;
- }
-
- verts[(vertIndex*3)+0] = x;
- verts[(vertIndex*3)+1] = y;
- verts[(vertIndex*3)+2] = z;
- cols[(vertIndex*4)+0] = color[0];
- cols[(vertIndex*4)+1] = color[1];
- cols[(vertIndex*4)+2] = color[2];
- cols[(vertIndex*4)+3] = color[3];
- texs[(vertIndex*2)+0] = tex[0];
- texs[(vertIndex*2)+1] = tex[1];
- vertIndex++;
-
- if (vertIndex > MAX_VERTS - 50) {
- if (isSplittable(vertIndex, currentType)) {
- int type = currentType;
- applyBuffer();
- currentType = type;
- }
- }
- }
- /**
- * Check if the geometry being created can be split at the current index
- *
- * @param count The current index
- * @param type The type of geometry being built
- * @return True if the geometry can be split at the current index
- */
- private boolean isSplittable(int count, int type) {
- switch (type) {
- case GL11.GL_QUADS:
- return count % 4 == 0;
- case GL11.GL_TRIANGLES:
- return count % 3 == 0;
- case GL11.GL_LINE:
- return count % 2 == 0;
- }
-
- return false;
- }
-
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glBindTexture(int, int)
- */
- public void glBindTexture(int target, int id) {
- applyBuffer();
- super.glBindTexture(target, id);
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glBlendFunc(int, int)
- */
- public void glBlendFunc(int src, int dest) {
- applyBuffer();
- super.glBlendFunc(src, dest);
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glCallList(int)
- */
- public void glCallList(int id) {
- applyBuffer();
- super.glCallList(id);
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glClear(int)
- */
- public void glClear(int value) {
- applyBuffer();
- super.glClear(value);
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glClipPlane(int, java.nio.DoubleBuffer)
- */
- public void glClipPlane(int plane, DoubleBuffer buffer) {
- applyBuffer();
- super.glClipPlane(plane, buffer);
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glColorMask(boolean, boolean, boolean, boolean)
- */
- public void glColorMask(boolean red, boolean green, boolean blue, boolean alpha) {
- applyBuffer();
- super.glColorMask(red, green, blue, alpha);
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glDisable(int)
- */
- public void glDisable(int item) {
- applyBuffer();
- super.glDisable(item);
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glEnable(int)
- */
- public void glEnable(int item) {
- applyBuffer();
- super.glEnable(item);
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glLineWidth(float)
- */
- public void glLineWidth(float width) {
- applyBuffer();
- super.glLineWidth(width);
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glPointSize(float)
- */
- public void glPointSize(float size) {
- applyBuffer();
- super.glPointSize(size);
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glPopMatrix()
- */
- public void glPopMatrix() {
- applyBuffer();
- super.glPopMatrix();
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glPushMatrix()
- */
- public void glPushMatrix() {
- applyBuffer();
- super.glPushMatrix();
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glRotatef(float, float, float, float)
- */
- public void glRotatef(float angle, float x, float y, float z) {
- applyBuffer();
- super.glRotatef(angle, x, y, z);
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glScalef(float, float, float)
- */
- public void glScalef(float x, float y, float z) {
- applyBuffer();
- super.glScalef(x, y, z);
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glScissor(int, int, int, int)
- */
- public void glScissor(int x, int y, int width, int height) {
- applyBuffer();
- super.glScissor(x, y, width, height);
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glTexEnvi(int, int, int)
- */
- public void glTexEnvi(int target, int mode, int value) {
- applyBuffer();
- super.glTexEnvi(target, mode, value);
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glTranslatef(float, float, float)
- */
- public void glTranslatef(float x, float y, float z) {
- applyBuffer();
- super.glTranslatef(x, y, z);
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glEndList()
- */
- public void glEndList() {
- listMode--;
- super.glEndList();
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glNewList(int, int)
- */
- public void glNewList(int id, int option) {
- listMode++;
- super.glNewList(id, option);
- }
- /**
- * @see org.newdawn.slick.opengl.renderer.SGL#getCurrentColor()
- */
- public float[] getCurrentColor() {
- return color;
- }
-
- /**
- * @see org.newdawn.slick.opengl.renderer.SGL#glLoadMatrix(java.nio.FloatBuffer)
- */
- public void glLoadMatrix(FloatBuffer buffer) {
- flushBuffer();
- super.glLoadMatrix(buffer);
- }
- }