/** * Establish the OpenGL state needed to draw text. * * @param dc the current draw context. */ protected void beginDrawing(DrawContext dc) { GL gl = dc.getGL(); int attrMask = GL.GL_DEPTH_BUFFER_BIT // for depth test, depth mask and depth func | GL.GL_TRANSFORM_BIT // for modelview and perspective | GL.GL_VIEWPORT_BIT // for depth range | GL.GL_CURRENT_BIT // for current color | GL.GL_COLOR_BUFFER_BIT // for alpha test func and ref, and blend | GL.GL_DEPTH_BUFFER_BIT // for depth func | GL.GL_ENABLE_BIT; // for enable/disable changes this.BEogsh.pushAttrib(gl, attrMask); if (!dc.isPickingMode()) { gl.glEnable(GL.GL_BLEND); OGLUtil.applyBlending(gl, false); } // Do not depth buffer the label. (Labels beyond the horizon are culled above.) gl.glDisable(GL.GL_DEPTH_TEST); gl.glDepthMask(false); // The image is drawn using a parallel projection. this.BEogsh.pushProjectionIdentity(gl); gl.glOrtho( 0d, dc.getView().getViewport().width, 0d, dc.getView().getViewport().height, -1d, 1d); this.BEogsh.pushModelviewIdentity(gl); }
protected void applyColor(DrawContext dc, java.awt.Color color, double opacity) { if (dc.isPickingMode()) return; double finalOpacity = opacity * (color.getAlpha() / 255.0); GL2 gl = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility. OGLUtil.applyColor(gl, color, finalOpacity, true); }
protected void beginRendering(DrawContext dc, OGLStackHandler stackHandler) { if (dc == null) { String message = Logging.getMessage("nullValue.DrawContextIsNull"); Logging.logger().fine(message); throw new IllegalArgumentException(message); } GL2 gl = dc.getGL(); int attribMask = GL2.GL_COLOR_BUFFER_BIT // for alpha test func and ref, blend func | GL2.GL_CURRENT_BIT // for current color | GL2.GL_ENABLE_BIT // for enable/disable | GL2.GL_LINE_BIT // for line width | GL2.GL_TRANSFORM_BIT; // for matrix mode stackHandler.pushAttrib(gl, attribMask); stackHandler.pushTextureIdentity(gl); stackHandler.pushProjectionIdentity(gl); java.awt.Rectangle viewport = dc.getView().getViewport(); gl.glOrtho( viewport.x, viewport.x + viewport.width, viewport.y, viewport.y + viewport.height, -1, 1); stackHandler.pushModelviewIdentity(gl); // Enable the alpha test. gl.glEnable(GL2.GL_ALPHA_TEST); gl.glAlphaFunc(GL2.GL_GREATER, 0.0f); // Enable blending in premultiplied color mode. gl.glEnable(GL2.GL_BLEND); OGLUtil.applyBlending(gl, true); gl.glDisable(GL2.GL_CULL_FACE); gl.glDisable(GL2.GL_DEPTH_TEST); gl.glDisable(GL2.GL_LIGHTING); gl.glDisable(GL2.GL_TEXTURE_2D); }
/** * Greedy Mesher algorithm, made with <a * href="http://0fps.net/2012/06/30/meshing-in-a-minecraft-game/">This article</a> * * @param c Chunk to mesh * @param holder list of models to hold the quads */ public static Model Greedy(Chunk c) { // Position of the new quad's bottom left corner int[] position = new int[3]; // Allows us to select a new voxel to merge depending on the dimension // we're evaluating int[] offset = new int[3]; // Positioning offsets int[] xOffset = new int[3]; int[] yOffset = new int[3]; int u, v; List<float[]> floatdata = new LinkedList<float[]>(); List<int[]> indices = new LinkedList<int[]>(); int[] dimentions = new int[] {Chunk.CHUNK_SIZE, World.WORLD_HEIGHT, Chunk.CHUNK_SIZE}; Voxel[] mask; // the mask index int n; // Buffer variables Voxel tmp1, tmp2; // Quad size, used for tiling textures int width, height; boolean back = true, b = false; while (b != back) { // d = x or y or z for (int d = 0; d < 3; d++) { position[0] = position[1] = position[2] = 0; offset[0] = offset[1] = offset[2] = 0; offset[d] = 1; position[d] = -1; u = (d + 1) % 3; v = (d + 2) % 3; // we'll iterate once per direction (6 times) mask = new Voxel[dimentions[u] * dimentions[v]]; while (position[d] < dimentions[d]) { n = 0; for (position[v] = 0; position[v] < dimentions[v]; position[v]++) { for (position[u] = 0; position[u] < dimentions[u]; position[u]++) { tmp1 = (position[d] >= 0) ? c.getAt(position[0], position[1], position[2]) : null; tmp2 = (position[d] < dimentions[d] - 1) ? c.getAt( position[0] + offset[0], position[1] + offset[1], position[2] + offset[2]) : null; // if the two voxels can be merged, we add null to // the mesh mask otherwise we add the actual voxel. mask[n++] = (tmp1 != null && tmp2 != null && tmp1.canBeMerged(tmp2)) ? null : (back ? tmp1 : tmp2); } } // We increment the current voxel (face) to compute position[d]++; n = 0; for (int j = 0; j < dimentions[v]; j++) { int i = 0; while (i < dimentions[u]) { if (mask[n] != null) { for (width = 1; (i + width) < dimentions[u] && mask[n + width] != null && mask[n + width].canBeMerged(mask[n]); width++) { // No code, the point of this loop is to get // the right width value for the mesh } outerloop: for (height = 1; j + height < dimentions[v]; height++) { for (int k = 0; k < width; k++) { // calculate the right height value for // the given width if (mask[n + k + height * dimentions[u]] == null || !(mask[n + k + height * dimentions[u]].canBeMerged(mask[n]))) { break outerloop; } } } // if the voxel isn't visible we don't create a // mesh for it if (mask[n].isOpaque() && mask[n].isVisible()) { // Relative positions, will be multiplied to // make a voxel later position[u] = i; position[v] = j; xOffset[0] = xOffset[1] = xOffset[2] = 0; xOffset[u] = width; yOffset[0] = yOffset[1] = yOffset[2] = 0; yOffset[v] = height; CreateQuad( new Vector3f(position[0], position[1], position[2]), new Vector3f( position[0] + xOffset[0], position[1] + xOffset[1], position[2] + xOffset[2]), new Vector3f( position[0] + xOffset[0] + yOffset[0], position[1] + xOffset[1] + yOffset[1], position[2] + xOffset[2] + yOffset[2]), new Vector3f( position[0] + yOffset[0], position[1] + yOffset[1], position[2] + yOffset[2]), back, width, height, mask[n].getColor(), floatdata, indices); } // Reset mask and increase counters for (int l = 0; l < height; l++) { for (int k = 0; k < width; k++) { mask[n + k + l * dimentions[u]] = null; } } // go to the next "line" i += width; n += width; } else { // go to the next quad i++; n++; } } } } } back = back & b; b = !b; } float[] vertices = new float[floatdata.size() * 12 / 2]; float[] colors = new float[floatdata.size() * 12 / 2]; int[] finalIndices = new int[indices.size() * 6]; for (int k = 0; k < floatdata.size(); k++) { if (k % 2 == 0) { for (int i = 0; i < floatdata.get(k).length; i++) { vertices[k / 2 * 12 + i] = floatdata.get(k)[i]; } } else { for (int i = 0; i < floatdata.get(k).length; i++) { colors[k / 2 * 12 + i] = floatdata.get(k)[i]; } } } for (int j = 0; j < indices.size(); j++) { finalIndices[j * 6] = indices.get(j)[0]; finalIndices[j * 6 + 1] = indices.get(j)[1]; finalIndices[j * 6 + 2] = indices.get(j)[2]; finalIndices[j * 6 + 3] = indices.get(j)[3]; finalIndices[j * 6 + 4] = indices.get(j)[4]; finalIndices[j * 6 + 5] = indices.get(j)[5]; } return OGLUtil.createMeshVAO(vertices, vertices, colors, finalIndices); }
protected void applyColor(DrawContext dc, java.awt.Color color, double opacity) { if (dc.isPickingMode()) return; double finalOpacity = opacity * (color.getAlpha() / 255.0); OGLUtil.applyColor(dc.getGL(), color, finalOpacity, true); }