/*********************************************************************** * mt4j Copyright (c) 2008 - 2009, C.Ruff, Fraunhofer-Gesellschaft All rights reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * ***********************************************************************/ package org.mt4j.components.visibleComponents.shapes; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.util.ArrayList; import java.util.List; import org.mt4j.util.PlatformUtil; import org.mt4j.util.math.Tools3D; import org.mt4j.util.math.ToolsBuffers; import org.mt4j.util.math.ToolsGeometry; import org.mt4j.util.math.Vertex; import org.mt4j.util.opengl.GL10; import org.mt4j.util.opengl.GL11; import org.mt4j.util.opengl.GL11Plus; import org.mt4j.util.opengl.GLStencilUtil; import processing.core.PApplet; import processing.core.PGraphics; /** * This class can only be used with OpenGL! * <br>This class can be used to draw concave, non-simple * polygons using the stencil buffer. * * @author Christopher Ruff */ public class MTStencilPolygon extends MTPolygon { /** The pa. */ private PApplet pa; /** The min max. */ private float[] minMax; /** The min x. */ private float minX; /** The min y. */ private float minY; /** The max x. */ private float maxX; /** The max y. */ private float maxY; /** The contours. */ private List<Vertex[]> contours; /** * Instantiates a new mT stencil polygon. * * @param vertices the vertices * @param pApplet the applet * @deprecated constructor will be deleted! Please use the constructor with the PApplet instance as the first parameter. */ public MTStencilPolygon(Vertex[] vertices, PApplet pApplet) { this(pApplet, vertices); } /** * Instantiates a new mT stencil polygon. * @param pApplet the applet * @param vertices the vertices */ public MTStencilPolygon(PApplet pApplet, Vertex[] vertices) { super(pApplet, vertices); ArrayList<Vertex[]> contours = new ArrayList<Vertex[]>(); contours.add(vertices); this.contours = contours; this.init(pa, vertices, contours); } /** * Instantiates a new mT stencil polygon. * * @param innerVertices the inner vertices * @param contours the contours * @param pApplet the applet * @deprecated constructor will be deleted! Please use the constructor with the PApplet instance as the first parameter. */ public MTStencilPolygon(Vertex[] innerVertices, ArrayList<Vertex[]> contours, PApplet pApplet) { this(pApplet, innerVertices, contours); } /** * The Constructor. * @param pApplet the applet * @param innerVertices the vertices used for picking and other calculations, its best to use the biggest contour for this * @param contours the contour(s) of the shape */ public MTStencilPolygon(PApplet pApplet, Vertex[] innerVertices, ArrayList<Vertex[]> contours) { super(pApplet, innerVertices); this.init(pApplet, innerVertices, contours); } /** * Inits the. * @param pApplet the applet * @param innerVertices the inner vertices * @param contours the contours */ private void init(PApplet pApplet, Vertex[] innerVertices, ArrayList<Vertex[]> contours){ this.pa = this.getRenderer(); this.contours = contours; //This class may only be used with opengl anyway! this.setUseDirectGL(true); this.setDrawSmooth(true); //Convert BezierVertices to regular Vertices //SEGMENTS CONRTOLS THE DETAIL OF THE BEZIER CURVE APPROXIMATION int segments = 12; //TODO let the user do that beforehand? Vertex[] allVerts = ToolsGeometry.createVertexArrFromBezierArr(innerVertices, segments); this.setVertices(allVerts); //Replace beziervertices in the SUB-PATHS (outlines) of the glyphs with many calculated regular vertices //The subpaths are used to draw the outline this.contours = ToolsGeometry.createVertexArrFromBezierVertexArrays(contours, segments); reCalcMinMax(); this.setStrokeWeight(1.0f); // use? // this.setEnableTesselation(true); this.createContourAndStencilQuadBuffers(); } private ArrayList<FloatBuffer> contoursInfos; private FloatBuffer stencilQuad; private void createContourAndStencilQuadBuffers(){ contoursInfos = new ArrayList<FloatBuffer>(); for (Vertex[] v : this.contours) { FloatBuffer buff = ToolsBuffers.generateVertexBuffer(v); contoursInfos.add(buff); } Vertex[] quadVertices = new Vertex[]{ new Vertex(minX, minY, 0.0f), new Vertex(maxX, minY, 0.0f), new Vertex(maxX, maxY, 0.0f), new Vertex(minX, maxY, 0.0f) }; this.stencilQuad = ToolsBuffers.generateVertexBuffer(quadVertices); } /** * Re calc min max. */ private void reCalcMinMax(){ minMax = ToolsGeometry.getMinXYMaxXY(this.getVerticesLocal()); minX = minMax[0]-5; minY = minMax[1]-5; maxX = minMax[2]+5; maxY = minMax[3]+5; } /** * NOTE: this also sets the contours to one and uses the new * vertices as the only contour! If you want to set other countours * use the setContours or setVerticesAndContours method!. * * @param vertices the vertices */ @Override public void setVertices(Vertex[] vertices) { super.setVertices(vertices); reCalcMinMax(); this.contours = new ArrayList<Vertex[]>(); this.contours.add(vertices); createContourAndStencilQuadBuffers(); } /** * Sets new outlines for this stencil polygon. * This is a separate method, because when you want * to ouline polygons with holes, you have to have separate, * not connected outline arrays. * * @param contours the contours */ public void setNewContours(ArrayList<Vertex[]> contours){ this.contours = contours; this.setMatricesDirty(true); createContourAndStencilQuadBuffers(); } /** * Sets the new vertices and contours. * * @param vertices the vertices * @param contours the contours */ public void setNewVerticesAndContours(Vertex[] vertices, ArrayList<Vertex[]> contours){ this.contours = contours; setVertices(vertices); reCalcMinMax(); createContourAndStencilQuadBuffers(); } /** * Just draws the character without applying its own local matrix, * useful when another components want to draw this component. * * @param gl the gl */ public void drawComponent(GL10 gl) { if (isUseDirectGL()){ if (isUseDisplayList()){ int[] displayListIDs = this.getGeometryInfo().getDisplayListIDs(); if (!this.isNoFill() && displayListIDs[0] != -1) // gl.glCallList(displayListIDs[0]); //Draw fill ((GL11Plus)gl).glCallList(displayListIDs[0]); //Draw fill if (!this.isNoStroke() && displayListIDs[1] != -1) // gl.glCallList(displayListIDs[1]); //Draw outline ((GL11Plus)gl).glCallList(displayListIDs[1]); //Draw outline }else{ drawPureGL(gl); } } } @Override public void drawComponent(PGraphics g) { if (isUseDirectGL()){ // GL gl=((PGraphicsOpenGL)this.getRenderer().g).beginGL(); GL10 gl = PlatformUtil.beginGL(); drawComponent(gl); // ((PGraphicsOpenGL)this.getRenderer().g).endGL(); PlatformUtil.endGL(); } } /** * Draw pure gl. * * @param gl the gl */ private void drawPureGL(GL10 gl){ FloatBuffer vertBuff = this.getGeometryInfo().getVertBuff(); FloatBuffer colorBuff = this.getGeometryInfo().getColorBuff(); FloatBuffer strokeColBuff = this.getGeometryInfo().getStrokeColBuff(); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_COLOR_ARRAY); GL11 gl11 = PlatformUtil.getGL11(); //TODO check if 1.1 available? if (this.isUseVBOs()){ gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, this.getGeometryInfo().getVBOVerticesName()); gl11.glVertexPointer(3, GL10.GL_FLOAT, 0, 0); gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, this.getGeometryInfo().getVBOColorName()); gl11.glColorPointer(4, GL10.GL_FLOAT, 0, 0); }else{ gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertBuff); gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuff); } //Normals if (this.getGeometryInfo().isContainsNormals()){ gl.glEnableClientState(GL10.GL_NORMAL_ARRAY); if (this.isUseVBOs()){ gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, this.getGeometryInfo().getVBONormalsName()); gl11.glNormalPointer(GL10.GL_FLOAT, 0, 0); }else{ gl.glNormalPointer(GL10.GL_FLOAT, 0, this.getGeometryInfo().getNormalsBuff()); } } // /* if (!this.isNoFill()){ /* /////////////////////// // Draw Into Stencil // /////////////////////// gl.glClearStencil(0); gl.glColorMask(false,false,false,false); gl.glDisable(GL.GL_BLEND); gl.glDepthMask(false);//remove..? //Enable stencilbuffer gl.glEnable(GL.GL_STENCIL_TEST); // gl.glStencilMask (0x01); gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_INVERT); gl.glStencilFunc (GL.GL_ALWAYS, 0, ~0); //Draw into stencil gl.glDrawArrays(GL.GL_TRIANGLE_FAN, 0, vertBuff.capacity()/3); if (this.getGeometryInfo().isContainsNormals()){ gl.glDisableClientState(GL.GL_NORMAL_ARRAY); } ////////////////////// // Draw fill Overlay// ////////////////////// gl.glDepthMask(true); gl.glColorMask(true, true, true, true); gl.glEnable (GL.GL_BLEND); gl.glStencilOp (GL.GL_ZERO, GL.GL_ZERO, GL.GL_ZERO); gl.glStencilFunc(GL.GL_EQUAL, 0x01, 0x01); if (useGradient){ gl.glBegin (GL.GL_QUADS); gl.glColor4f(x1R, x1G, x1B, x1A); gl.glVertex3d (minX, minY, 0.0); gl.glColor4f(x2R, x2G, x2B, x2A); gl.glVertex3d (maxX, minY, 0.0); gl.glColor4f(x3R, x3G, x3B, x3A); gl.glVertex3d (maxX, maxY, 0.0); gl.glColor4f(x4R, x4G, x4B, x4A); gl.glVertex3d (minX, maxY, 0.0); gl.glEnd (); }else{ gl.glColor4d (colorBuff.get(0), colorBuff.get(1), colorBuff.get(2), colorBuff.get(3)); gl.glBegin (GL.GL_QUADS); gl.glVertex3d (minX, minY, 0.0); gl.glVertex3d (maxX, minY, 0.0); gl.glVertex3d (maxX, maxY, 0.0); gl.glVertex3d (minX, maxY, 0.0); gl.glEnd (); } gl.glDisable (GL.GL_STENCIL_TEST); */ /////////////////////// // Draw Into Stencil // /////////////////////// // GLStencilUtil.getInstance().beginDrawClipShape(gl); if (GLStencilUtil.getInstance().isClipActive() && PlatformUtil.getGL11Plus() != null){ // gl.glPushAttrib(GL.GL_STENCIL_BUFFER_BIT); ((PlatformUtil.getGL11Plus())).glPushAttrib(GL10.GL_STENCIL_BUFFER_BIT); }else{ //Enable stencilbuffer gl.glEnable(GL10.GL_STENCIL_TEST); gl.glClearStencil(GLStencilUtil.stencilValueStack.peek()); gl.glClear(GL10.GL_STENCIL_BUFFER_BIT); } // gl.glPushAttrib(GL.GL_STENCIL_TEST); // gl.glDisable(GL.GL_STENCIL_TEST); // gl.glClearStencil(GLStencilUtil.getInstance().stencilValueStack.peek()); // gl.glClearStencil(0); // gl.glClear(GL.GL_STENCIL_BUFFER_BIT); gl.glColorMask(false,false,false,false); gl.glDisable(GL10.GL_BLEND); gl.glDepthMask(false);//remove..? // gl.glStencilMask (0x01); gl.glStencilOp(GL10.GL_KEEP, GL10.GL_KEEP, GL10.GL_INVERT); gl.glStencilFunc (GL10.GL_ALWAYS, 0, ~0); // gl.glStencilFunc (GL.GL_ALWAYS, GLStencilUtil.getInstance().stencilValueStack.peek(), ~GLStencilUtil.getInstance().stencilValueStack.peek()); //Draw into stencil gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, vertBuff.capacity()/3); if (this.getGeometryInfo().isContainsNormals()){ gl.glDisableClientState(GL10.GL_NORMAL_ARRAY); } ////////////////////// // Draw fill Overlay// ////////////////////// gl.glDepthMask(true); gl.glColorMask(true, true, true, true); gl.glEnable (GL10.GL_BLEND); gl.glStencilOp (GL10.GL_KEEP, GL10.GL_KEEP, GL10.GL_REPLACE); // gl.glStencilOp (GL.GL_ZERO, GL.GL_REPLACE, GL.GL_REPLACE); // gl.glStencilOp (GL.GL_KEEP, GL.GL_KEEP, GL.GL_ZERO); // gl.glStencilOp (GL.GL_ZERO, GL.GL_ZERO, GL.GL_ZERO); //Org // gl.glStencilFunc(GL.GL_EQUAL, 0x01, 0x01); //org // if (GLStencilUtil.getInstance().isClipActive()){ gl.glStencilFunc(GL10.GL_NOTEQUAL, GLStencilUtil.stencilValueStack.peek(), GLStencilUtil.stencilValueStack.peek()); // gl.glStencilFunc(GL.GL_NOTEQUAL, 0x01, 0x01); // }else{ // gl.glStencilFunc(GL.GL_EQUAL, GLStencilUtil.getInstance().stencilValueStack.peek(), GLStencilUtil.getInstance().stencilValueStack.peek()); // } //Draw quad over everything -> only where the stencil value is right, it will be drawn // gl.glColor4f (colorBuff.get(0), colorBuff.get(1), colorBuff.get(2), colorBuff.get(3)); // gl.glBegin (GL.GL_QUADS); // gl.glVertex3d (minX, minY, 0.0); // gl.glVertex3d (maxX, minY, 0.0); // gl.glVertex3d (maxX, maxY, 0.0); // gl.glVertex3d (minX, maxY, 0.0); //gl.glEnd (); if (this.isUseVBOs()){ gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0); } gl.glVertexPointer(3, GL10.GL_FLOAT, 0, stencilQuad); gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, stencilQuad.capacity()/3); if (GLStencilUtil.getInstance().isClipActive()){ if (PlatformUtil.getGL11Plus() != null){ //gl.glPopAttrib(); PlatformUtil.getGL11Plus().glPopAttrib(); }else{ gl.glStencilFunc(GL10.GL_EQUAL, GLStencilUtil.stencilValueStack.peek(), GLStencilUtil.stencilValueStack.peek()); gl.glStencilOp(GL10.GL_KEEP, GL10.GL_KEEP, GL10.GL_KEEP); } }else{ gl.glDisable (GL10.GL_STENCIL_TEST); } } ////////////////////////////// // Draw aliased outlines // ////////////////////////////// if (!isNoStroke()){ if (this.isUseVBOs()){ gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, this.getGeometryInfo().getVBOStrokeColorName()); gl11.glColorPointer(4, GL10.GL_FLOAT, 0, 0); }else{ gl.glColorPointer(4, GL10.GL_FLOAT, 0, strokeColBuff); } // gl.glDepthMask(false); //FIXME enable? disable? // // Draw aliased off-pixels to real // gl.glEnable (GL.GL_BLEND); // gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); // // gl.glStencilOp (GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP); // gl.glStencilFunc (GL.GL_EQUAL, 0x00, 0x01); //THIS IS THE ORIGINAL! // gl.glEnable(GL.GL_LINE_SMOOTH); //FIXME TEST Tools3D.setLineSmoothEnabled(gl, true); gl.glLineWidth(this.getStrokeWeight()); short lineStipple = this.getLineStipple(); if (lineStipple != 0 && PlatformUtil.getGL11Plus() != null){ PlatformUtil.getGL11Plus().glLineStipple(1, lineStipple); gl.glEnable(GL11Plus.GL_LINE_STIPPLE); } //DRAW // gl.glDrawElements(GL.GL_LINE_STRIP, indexBuff.capacity(), GL.GL_UNSIGNED_INT, indexBuff); // gl.glDrawArrays(GL.GL_LINE_STRIP, 0, vertexArr.length); /////TEST/// //TODO make vertex pointer arrays? gl.glColor4f (strokeColBuff.get(0), strokeColBuff.get(1), strokeColBuff.get(2), strokeColBuff.get(3)); // for (Vertex[] outline : contours){ // gl.glBegin (GL.GL_LINE_STRIP); // for (Vertex vertex : outline) // gl.glVertex3f (vertex.getX(), vertex.getY(), vertex.getZ()); // gl.glEnd(); // } if (this.isUseVBOs()){ gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0); } for (FloatBuffer outline : contoursInfos){ gl.glVertexPointer(3, GL10.GL_FLOAT, 0, outline); gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, outline.capacity()/3); } // gl.glDisable (GL.GL_LINE_SMOOTH); //FIXME TEST Tools3D.setLineSmoothEnabled(gl, false); if (lineStipple != 0){ gl.glDisable(GL11Plus.GL_LINE_STIPPLE); } } // gl.glDisable (GL.GL_STENCIL_TEST); // gl.glDepthMask(true); //Disable client states gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisableClientState(GL10.GL_COLOR_ARRAY); // if (this.isUseVBOs()){ // gl11.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); // gl11.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0); // } } @Override //TODO JUST COMPILE DrawPureGL() into a list!? public void generateDisplayLists() { super.generateDisplayLists(); // this.getGeometryInfo().setDisplayListIDs(generateStencilDisplayList( // pa, this.getGeometryInfo().getVertBuff(), this.getGeometryInfo().getTexBuff(), this.getGeometryInfo().getColorBuff(), this.getGeometryInfo().getStrokeColBuff(), // this.getGeometryInfo().getIndexBuff(),true, this.getStrokeWeight(), this.getVerticesLocal(), contours)); } /** * Generate stencil display list. * * @param pa the pa * @param vertBuff the vert buff * @param tbuff the tbuff * @param colorBuff the color buff * @param strokeColBuff the stroke col buff * @param indexBuff the index buff * @param drawSmooth the draw smooth * @param strokeWeight the stroke weight * @param vertexArr the vertex arr * @param outLines the out lines * * @return the int[] */ private int[] generateStencilDisplayList(PApplet pa, FloatBuffer vertBuff, FloatBuffer tbuff, FloatBuffer colorBuff, FloatBuffer strokeColBuff, IntBuffer indexBuff, boolean drawSmooth, float strokeWeight, Vertex[] vertexArr, List<Vertex[]> outLines) { return genStencilDisplayListGradient(pa, vertBuff, tbuff, colorBuff, strokeColBuff, indexBuff, drawSmooth, strokeWeight, vertexArr, outLines // , 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, false ); } /** * Gen stencil display list gradient. * <p><b>NOTE</b>: the openGL context has to be valid at the time of calling this method. * * @param pa the pa * @param vertBuff the vert buff * @param tbuff the tbuff * @param colorBuff the color buff * @param strokeColBuff the stroke col buff * @param indexBuff the index buff * @param drawSmooth the draw smooth * @param strokeWeight the stroke weight * @param vertexArr the vertex arr * @param outLines the out lines * @param x1R the x1 r * @param x1G the x1 g * @param x1B the x1 b * @param x1A the x1 a * @param x2R the x2 r * @param x2G the x2 g * @param x2B the x2 b * @param x2A the x2 a * @param x3R the x3 r * @param x3G the x3 g * @param x3B the x3 b * @param x3A the x3 a * @param x4R the x4 r * @param x4G the x4 g * @param x4B the x4 b * @param x4A the x4 a * @param useGradient the use gradient * * @return the int[] */ private int[] genStencilDisplayListGradient(PApplet pa, FloatBuffer vertBuff, FloatBuffer tbuff, FloatBuffer colorBuff, FloatBuffer strokeColBuff, IntBuffer indexBuff, boolean drawSmooth, float strokeWeight, Vertex[] vertexArr, List<Vertex[]> outLines // ,float x1R, float x1G, float x1B, float x1A, float x2R, float x2G, float x2B, float x2A, // float x3R, float x3G, float x3B, float x3A, float x4R, float x4G, float x4B, float x4A, // boolean useGradient ) { // GL gl=((PGraphicsOpenGL)pa.g).beginGL(); GL10 gl = PlatformUtil.beginGL(); GL11Plus gl11Plus = PlatformUtil.getGL11Plus(); /* //Unbind any VBOs first gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, 0); gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, 0); */ //Generate new list IDs int[] returnVal = new int[2]; int listIDFill = gl11Plus.glGenLists(1); if (listIDFill == 0){ System.err.println("Failed to create display list"); returnVal[0] = -1; returnVal[1] = -1; return returnVal; } int listIDOutline = gl11Plus.glGenLists(1); if (listIDOutline == 0){ System.err.println("Failed to create display list"); returnVal[0] = -1; returnVal[1] = -1; return returnVal; } float[] minMax = ToolsGeometry.getMinXYMaxXY(vertexArr); float minX = minMax[0]-10; float minY = minMax[1]-10; float maxX = minMax[2]+10; float maxY = minMax[3]+10; gl.glColor4f (0.0f, 0.0f, 0.0f, 1.0f); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_COLOR_ARRAY); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertBuff); gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuff); //Using the strokecolor buffer strokecolor AND fill! //Generate List gl11Plus.glNewList(listIDFill, GL11Plus.GL_COMPILE); ///////////////////////////////////// // Clear stencil and disable color // // Draw with STENCIL // ///////////////////////////////////// // /* gl.glClearStencil(0); gl.glColorMask(false,false,false,false); gl.glDisable(GL10.GL_BLEND); gl.glDepthMask(false);//remove..? //FIXME do this for non-zero rule? // gl.glColorMask(true,true,true,true); // gl.glEnable (GL.GL_BLEND); // gl.glDepthMask(true);//remove..? //Enable stencilbuffer gl.glEnable(GL10.GL_STENCIL_TEST); // gl.glStencilMask (0x01); gl.glStencilOp(GL10.GL_KEEP, GL10.GL_KEEP, GL10.GL_INVERT); gl.glStencilFunc (GL10.GL_ALWAYS, 0, ~0); //Stecilfunc bestimmt ob in den stencil geschrieben wird oder nicht //1.param: die vergleichsart der werte, //2.param: reference value, wird bei op reingeschrieben bei replace(?) //3.prama: mask //ref is & anded with mask and the result with the value in the stencil buffer //mask is & with ref, mask is & stencil => vergleich // gl.glStencilFunc(GL.GL_ALWAYS, 0x1, 0x1); // gl.glStencilOp(GL.GL_KEEP, GL.GL_INVERT, GL.GL_INVERT); //TODO notice, "stencilOP" zum wert in stencilbuffer reinschreiben //"stencilfunc" vergleicht framebuffer mit stencilbuffer und macht stencilOP wenn bedingung stimmt gl.glColor4f (colorBuff.get(0), colorBuff.get(1), colorBuff.get(2), colorBuff.get(3)); //DRAW //FIXME why does this not work? if (indexBuff == null){ gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, vertBuff.capacity()/3); }else{ gl.glDrawElements(GL10.GL_TRIANGLE_FAN, indexBuff.capacity(), GL10.GL_UNSIGNED_SHORT, indexBuff); } // gl.glBegin (GL.GL_TRIANGLE_FAN); // for (int i = 0; i < vertexArr.length; i++) { // Vertex vertex = vertexArr[i]; // gl.glVertex3f (vertex.getX(), vertex.getY(), vertex.getZ()); // } // gl.glEnd(); // gl.glDrawArrays(GL.GL_TRIANGLE_FAN, 0, vertBuff.capacity()/3); // */ ////////////////////////////////////// gl.glDepthMask(true); gl.glEnable (GL10.GL_BLEND); gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); ////////////////////// // Draw fill // ////////////////////// // /* gl.glColorMask(true, true, true, true); gl.glEnable (GL10.GL_BLEND); gl.glStencilOp (GL10.GL_ZERO, GL10.GL_ZERO, GL10.GL_ZERO); //org gl.glStencilFunc(GL10.GL_EQUAL, 0x01, 0x01); // gl.glStencilOp (GL.GL_KEEP, GL.GL_REPLACE, GL.GL_ZERO); // gl.glStencilFunc(GL.GL_EQUAL, 0x01, 0x01); // if (useGradient){ // gl.glBegin (GL.GL_QUADS); // gl.glColor4f(x1R, x1G, x1B, x1A); // gl.glVertex3d (minX, minY, 0.0); // gl.glColor4f(x2R, x2G, x2B, x2A); // gl.glVertex3d (maxX, minY, 0.0); // gl.glColor4f(x3R, x3G, x3B, x3A); // gl.glVertex3d (maxX, maxY, 0.0); // gl.glColor4f(x4R, x4G, x4B, x4A); // gl.glVertex3d (minX, maxY, 0.0); // gl.glEnd (); // }else{ // gl.glBegin (GL.GL_QUADS); // gl.glVertex3d (minX, minY, 0.0); // gl.glVertex3d (maxX, minY, 0.0); // gl.glVertex3d (maxX, maxY, 0.0); // gl.glVertex3d (minX, maxY, 0.0); // gl.glEnd (); // } gl.glVertexPointer(3, GL10.GL_FLOAT, 0, stencilQuad); gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, stencilQuad.capacity()/3); // */ //////////////////////////////////// // gl.glDepthMask(true); //Disabled to avoid too many state switches, gl.glDisable (GL10.GL_STENCIL_TEST); //Disabled to avoid too many state switches gl11Plus.glEndList(); returnVal[0] = listIDFill; ////////////////////////////// // Draw aliased outline // ////////////////////////////// gl.glColorPointer(4, GL10.GL_FLOAT, 0, strokeColBuff); gl11Plus.glNewList(listIDOutline, GL11Plus.GL_COMPILE); // gl.glEnable(GL.GL_STENCIL_TEST); // gl.glColorMask(true, true, true, true); // gl.glDepthMask(false); //FIXME enable? disable? // // Draw aliased off-pixels to real // gl.glEnable (GL.GL_BLEND); // gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); // /* // gl.glStencilOp (GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP); // gl.glStencilFunc (GL.GL_EQUAL, 0x00, 0x01); //THIS IS THE ORIGINAL! // gl.glStencilOp (GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP); // gl.glStencilFunc (GL.GL_EQUAL, 0x00, ~1); // gl.glEnable(GL.GL_LINE_SMOOTH); //FIXME TEST Tools3D.setLineSmoothEnabled(gl, true); gl.glLineWidth(strokeWeight); //DRAW // gl.glDrawElements(GL.GL_LINE_STRIP, indexBuff.capacity(), GL.GL_UNSIGNED_INT, indexBuff); // gl.glDrawArrays(GL.GL_LINE_STRIP, 0, vertexArr.length); /////TEST/// //TODO make vertex pointer arrays? gl.glColor4f (strokeColBuff.get(0), strokeColBuff.get(1), strokeColBuff.get(2), strokeColBuff.get(3)); // for (Vertex[] outline : outLines){ // gl.glBegin (GL.GL_LINE_STRIP); // for (Vertex vertex : outline){ // gl.glVertex3f (vertex.getX(), vertex.getY(), vertex.getZ()); // } // gl.glEnd(); // } for (FloatBuffer outline : contoursInfos){ gl.glVertexPointer(3, GL10.GL_FLOAT, 0, outline); gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, outline.capacity()/3); } //// // gl.glDisable (GL.GL_LINE_SMOOTH); //FIXME TEST Tools3D.setLineSmoothEnabled(gl, false); ////////////////////////////////// // */ // gl.glDisable (GL.GL_STENCIL_TEST); // gl.glDepthMask(true); gl11Plus.glEndList(); returnVal[1] = listIDOutline; //Disable client states gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisableClientState(GL10.GL_COLOR_ARRAY); // ((PGraphicsOpenGL)pa.g).endGL(); PlatformUtil.endGL(); //////////////// return returnVal; } /** * returns the vertex arrays which shape the outline of the character. * * @return the contours */ public List<Vertex[]> getContours(){ return this.contours; } /** * Gets the max x. * * @return the max x */ public float getMaxX() { return maxX; } /** * Gets the max y. * * @return the max y */ public float getMaxY() { return maxY; } /** * Gets the min x. * * @return the min x */ public float getMinX() { return minX; } /** * Gets the min y. * * @return the min y */ public float getMinY() { return minY; } }