/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

  1. package org.newdawn.slick.opengl.renderer;
  2. import java.nio.DoubleBuffer;
  3. import java.nio.FloatBuffer;
  4. import org.lwjgl.BufferUtils;
  5. import org.lwjgl.opengl.GL11;
  6. /**
  7. * A renderer that caches all operations into an array, creates an opengl vertex array when
  8. * required and spits the data down to the card in batch mode
  9. *
  10. * @author kevin
  11. */
  12. public class VAOGLRenderer extends ImmediateModeOGLRenderer {
  13. /** The tolerance to rendering immediate */
  14. private static final int TOLERANCE = 20;
  15. /** Indicates there is no current geometry buffer */
  16. public static final int NONE = -1;
  17. /** The maximum number of vertices draw in one batch */
  18. public static final int MAX_VERTS = 5000;
  19. /** The type of the geometry array currently being built - i.e. GL_QUADS */
  20. private int currentType = NONE;
  21. /** The last colour applied */
  22. private float[] color = new float[] {1f,1f,1f,1f};
  23. /** The last texture applied */
  24. private float[] tex = new float[] {0f,0f};
  25. /** The index of the next vertex to be created */
  26. private int vertIndex;
  27. /** The vertex data cached */
  28. private float[] verts = new float[MAX_VERTS*3];
  29. /** The vertex colour data cached */
  30. private float[] cols = new float[MAX_VERTS*4];
  31. /** The vertex texture coordiante data cached */
  32. private float[] texs = new float[MAX_VERTS*3];
  33. /** The buffer used to pass the vertex data to the card */
  34. private FloatBuffer vertices = BufferUtils.createFloatBuffer(MAX_VERTS * 3);
  35. /** The buffer used to pass the vertex color data to the card */
  36. private FloatBuffer colors = BufferUtils.createFloatBuffer(MAX_VERTS * 4);
  37. /** The buffer used to pass the vertex texture coordinate data to the card */
  38. private FloatBuffer textures = BufferUtils.createFloatBuffer(MAX_VERTS * 2);
  39. /** The stack for entering list creation mode - when we're creating a list we can't use our VAs */
  40. private int listMode = 0;
  41. /**
  42. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#initDisplay(int, int)
  43. */
  44. public void initDisplay(int width, int height) {
  45. super.initDisplay(width, height);
  46. startBuffer();
  47. GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
  48. GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
  49. GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
  50. }
  51. /**
  52. * Start a new buffer for a vertex array
  53. */
  54. private void startBuffer() {
  55. vertIndex = 0;
  56. }
  57. /**
  58. * Flush the currently cached data down to the card
  59. */
  60. private void flushBuffer() {
  61. if (vertIndex == 0) {
  62. return;
  63. }
  64. if (currentType == NONE) {
  65. return;
  66. }
  67. if (vertIndex < TOLERANCE) {
  68. GL11.glBegin(currentType);
  69. for (int i=0;i<vertIndex;i++) {
  70. GL11.glColor4f(cols[(i*4)+0], cols[(i*4)+1], cols[(i*4)+2], cols[(i*4)+3]);
  71. GL11.glTexCoord2f(texs[(i*2)+0], texs[(i*2)+1]);
  72. GL11.glVertex3f(verts[(i*3)+0], verts[(i*3)+1], verts[(i*3)+2]);
  73. }
  74. GL11.glEnd();
  75. currentType = NONE;
  76. return;
  77. }
  78. vertices.clear();
  79. colors.clear();
  80. textures.clear();
  81. vertices.put(verts,0,vertIndex*3);
  82. colors.put(cols,0,vertIndex*4);
  83. textures.put(texs,0,vertIndex*2);
  84. vertices.flip();
  85. colors.flip();
  86. textures.flip();
  87. GL11.glVertexPointer(3,0,vertices);
  88. GL11.glColorPointer(4,0,colors);
  89. GL11.glTexCoordPointer(2,0,textures);
  90. GL11.glDrawArrays(currentType, 0, vertIndex);
  91. currentType = NONE;
  92. }
  93. /**
  94. * Apply the current buffer and restart it
  95. */
  96. private void applyBuffer() {
  97. if (listMode > 0) {
  98. return;
  99. }
  100. if (vertIndex != 0) {
  101. flushBuffer();
  102. startBuffer();
  103. }
  104. super.glColor4f(color[0], color[1], color[2], color[3]);
  105. }
  106. /**
  107. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#flush()
  108. */
  109. public void flush() {
  110. super.flush();
  111. applyBuffer();
  112. }
  113. /**
  114. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glBegin(int)
  115. */
  116. public void glBegin(int geomType) {
  117. if (listMode > 0) {
  118. super.glBegin(geomType);
  119. return;
  120. }
  121. if (currentType != geomType) {
  122. applyBuffer();
  123. currentType = geomType;
  124. }
  125. }
  126. /**
  127. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glColor4f(float, float, float, float)
  128. */
  129. public void glColor4f(float r, float g, float b, float a) {
  130. a *= alphaScale;
  131. color[0] = r;
  132. color[1] = g;
  133. color[2] = b;
  134. color[3] = a;
  135. if (listMode > 0) {
  136. super.glColor4f(r,g,b,a);
  137. return;
  138. }
  139. }
  140. /**
  141. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glEnd()
  142. */
  143. public void glEnd() {
  144. if (listMode > 0) {
  145. super.glEnd();
  146. return;
  147. }
  148. }
  149. /**
  150. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glTexCoord2f(float, float)
  151. */
  152. public void glTexCoord2f(float u, float v) {
  153. if (listMode > 0) {
  154. super.glTexCoord2f(u,v);
  155. return;
  156. }
  157. tex[0] = u;
  158. tex[1] = v;
  159. }
  160. /**
  161. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glVertex2f(float, float)
  162. */
  163. public void glVertex2f(float x, float y) {
  164. if (listMode > 0) {
  165. super.glVertex2f(x,y);
  166. return;
  167. }
  168. glVertex3f(x,y,0);
  169. }
  170. /**
  171. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glVertex3f(float, float, float)
  172. */
  173. public void glVertex3f(float x, float y, float z) {
  174. if (listMode > 0) {
  175. super.glVertex3f(x,y,z);
  176. return;
  177. }
  178. verts[(vertIndex*3)+0] = x;
  179. verts[(vertIndex*3)+1] = y;
  180. verts[(vertIndex*3)+2] = z;
  181. cols[(vertIndex*4)+0] = color[0];
  182. cols[(vertIndex*4)+1] = color[1];
  183. cols[(vertIndex*4)+2] = color[2];
  184. cols[(vertIndex*4)+3] = color[3];
  185. texs[(vertIndex*2)+0] = tex[0];
  186. texs[(vertIndex*2)+1] = tex[1];
  187. vertIndex++;
  188. if (vertIndex > MAX_VERTS - 50) {
  189. if (isSplittable(vertIndex, currentType)) {
  190. int type = currentType;
  191. applyBuffer();
  192. currentType = type;
  193. }
  194. }
  195. }
  196. /**
  197. * Check if the geometry being created can be split at the current index
  198. *
  199. * @param count The current index
  200. * @param type The type of geometry being built
  201. * @return True if the geometry can be split at the current index
  202. */
  203. private boolean isSplittable(int count, int type) {
  204. switch (type) {
  205. case GL11.GL_QUADS:
  206. return count % 4 == 0;
  207. case GL11.GL_TRIANGLES:
  208. return count % 3 == 0;
  209. case GL11.GL_LINE:
  210. return count % 2 == 0;
  211. }
  212. return false;
  213. }
  214. /**
  215. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glBindTexture(int, int)
  216. */
  217. public void glBindTexture(int target, int id) {
  218. applyBuffer();
  219. super.glBindTexture(target, id);
  220. }
  221. /**
  222. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glBlendFunc(int, int)
  223. */
  224. public void glBlendFunc(int src, int dest) {
  225. applyBuffer();
  226. super.glBlendFunc(src, dest);
  227. }
  228. /**
  229. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glCallList(int)
  230. */
  231. public void glCallList(int id) {
  232. applyBuffer();
  233. super.glCallList(id);
  234. }
  235. /**
  236. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glClear(int)
  237. */
  238. public void glClear(int value) {
  239. applyBuffer();
  240. super.glClear(value);
  241. }
  242. /**
  243. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glClipPlane(int, java.nio.DoubleBuffer)
  244. */
  245. public void glClipPlane(int plane, DoubleBuffer buffer) {
  246. applyBuffer();
  247. super.glClipPlane(plane, buffer);
  248. }
  249. /**
  250. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glColorMask(boolean, boolean, boolean, boolean)
  251. */
  252. public void glColorMask(boolean red, boolean green, boolean blue, boolean alpha) {
  253. applyBuffer();
  254. super.glColorMask(red, green, blue, alpha);
  255. }
  256. /**
  257. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glDisable(int)
  258. */
  259. public void glDisable(int item) {
  260. applyBuffer();
  261. super.glDisable(item);
  262. }
  263. /**
  264. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glEnable(int)
  265. */
  266. public void glEnable(int item) {
  267. applyBuffer();
  268. super.glEnable(item);
  269. }
  270. /**
  271. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glLineWidth(float)
  272. */
  273. public void glLineWidth(float width) {
  274. applyBuffer();
  275. super.glLineWidth(width);
  276. }
  277. /**
  278. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glPointSize(float)
  279. */
  280. public void glPointSize(float size) {
  281. applyBuffer();
  282. super.glPointSize(size);
  283. }
  284. /**
  285. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glPopMatrix()
  286. */
  287. public void glPopMatrix() {
  288. applyBuffer();
  289. super.glPopMatrix();
  290. }
  291. /**
  292. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glPushMatrix()
  293. */
  294. public void glPushMatrix() {
  295. applyBuffer();
  296. super.glPushMatrix();
  297. }
  298. /**
  299. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glRotatef(float, float, float, float)
  300. */
  301. public void glRotatef(float angle, float x, float y, float z) {
  302. applyBuffer();
  303. super.glRotatef(angle, x, y, z);
  304. }
  305. /**
  306. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glScalef(float, float, float)
  307. */
  308. public void glScalef(float x, float y, float z) {
  309. applyBuffer();
  310. super.glScalef(x, y, z);
  311. }
  312. /**
  313. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glScissor(int, int, int, int)
  314. */
  315. public void glScissor(int x, int y, int width, int height) {
  316. applyBuffer();
  317. super.glScissor(x, y, width, height);
  318. }
  319. /**
  320. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glTexEnvi(int, int, int)
  321. */
  322. public void glTexEnvi(int target, int mode, int value) {
  323. applyBuffer();
  324. super.glTexEnvi(target, mode, value);
  325. }
  326. /**
  327. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glTranslatef(float, float, float)
  328. */
  329. public void glTranslatef(float x, float y, float z) {
  330. applyBuffer();
  331. super.glTranslatef(x, y, z);
  332. }
  333. /**
  334. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glEndList()
  335. */
  336. public void glEndList() {
  337. listMode--;
  338. super.glEndList();
  339. }
  340. /**
  341. * @see org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer#glNewList(int, int)
  342. */
  343. public void glNewList(int id, int option) {
  344. listMode++;
  345. super.glNewList(id, option);
  346. }
  347. /**
  348. * @see org.newdawn.slick.opengl.renderer.SGL#getCurrentColor()
  349. */
  350. public float[] getCurrentColor() {
  351. return color;
  352. }
  353. /**
  354. * @see org.newdawn.slick.opengl.renderer.SGL#glLoadMatrix(java.nio.FloatBuffer)
  355. */
  356. public void glLoadMatrix(FloatBuffer buffer) {
  357. flushBuffer();
  358. super.glLoadMatrix(buffer);
  359. }
  360. }