Source Code Cross Referenced for OGLGraphics2D.java in  » Apache-Harmony-Java-SE » org-package » org » apache » harmony » awt » gl » opengl » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Apache Harmony Java SE » org package » org.apache.harmony.awt.gl.opengl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
0003:         *  contributor license agreements.  See the NOTICE file distributed with
0004:         *  this work for additional information regarding copyright ownership.
0005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
0006:         *  (the "License"); you may not use this file except in compliance with
0007:         *  the License.  You may obtain a copy of the License at
0008:         *
0009:         *     http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         *  Unless required by applicable law or agreed to in writing, software
0012:         *  distributed under the License is distributed on an "AS IS" BASIS,
0013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         *  See the License for the specific language governing permissions and
0015:         *  limitations under the License.
0016:         */
0017:        /**
0018:         * @author Oleg V. Khaschansky
0019:         * @version $Revision$
0020:         */package org.apache.harmony.awt.gl.opengl;
0021:
0022:        import org.apache.harmony.awt.gl.CommonGraphics2D;
0023:        import org.apache.harmony.awt.gl.MultiRectArea;
0024:        import org.apache.harmony.awt.gl.Utils;
0025:        import org.apache.harmony.awt.gl.Surface;
0026:        import org.apache.harmony.awt.gl.font.FontManager;
0027:        import org.apache.harmony.awt.gl.render.NullBlitter;
0028:        import org.apache.harmony.awt.wtk.NativeWindow;
0029:        import org.apache.harmony.awt.nativebridge.Int32Pointer;
0030:        import org.apache.harmony.awt.nativebridge.NativeBridge;
0031:        import org.apache.harmony.misc.accessors.LockedArray;
0032:
0033:        import java.awt.*;
0034:        import java.awt.geom.AffineTransform;
0035:        import java.awt.geom.Rectangle2D;
0036:        import java.awt.geom.Point2D;
0037:        import java.awt.font.GlyphVector;
0038:        import java.util.Arrays;
0039:        import java.math.BigInteger;
0040:
0041:        public final class OGLGraphics2D extends CommonGraphics2D {
0042:
0043:            private static final int[] BLEND_RULE_MAPPING_SRC_PREMULT = new int[] {
0044:                    -1, // No rule
0045:                    GLDefs.GL_ZERO, // 1, Clear
0046:                    GLDefs.GL_ONE, // 2, Src
0047:                    GLDefs.GL_ONE, // 3, SrcOver
0048:                    GLDefs.GL_ONE_MINUS_DST_ALPHA, // 4, DstOver
0049:                    GLDefs.GL_DST_ALPHA, // 5, SrcIn
0050:                    GLDefs.GL_ZERO, // 6, DstIn
0051:                    GLDefs.GL_ONE_MINUS_DST_ALPHA, // 7, SrcOut
0052:                    GLDefs.GL_ZERO, // 8, DstOut
0053:                    GLDefs.GL_ZERO, // 9, Dst
0054:                    GLDefs.GL_DST_ALPHA, // 10, SrcAtop
0055:                    GLDefs.GL_ONE_MINUS_DST_ALPHA, // 11, DstAtop
0056:                    GLDefs.GL_ONE_MINUS_DST_ALPHA // 11, Xor
0057:            };
0058:
0059:            private static final int[] BLEND_RULE_MAPPING_DST = new int[] { -1, // No rule
0060:                    GLDefs.GL_ZERO, // 1, Clear
0061:                    GLDefs.GL_ZERO, // 2, Src
0062:                    GLDefs.GL_ONE_MINUS_SRC_ALPHA, // 3, SrcOver
0063:                    GLDefs.GL_ONE, // 4, DstOver
0064:                    GLDefs.GL_ZERO, // 5, SrcIn
0065:                    GLDefs.GL_SRC_ALPHA, // 6, DstIn
0066:                    GLDefs.GL_ZERO, // 7, SrcOut
0067:                    GLDefs.GL_ONE_MINUS_SRC_ALPHA, // 8, DstOut
0068:                    GLDefs.GL_ONE, // 9, Dst
0069:                    GLDefs.GL_ONE_MINUS_SRC_ALPHA, // 10, SrcAtop
0070:                    GLDefs.GL_SRC_ALPHA, // 11, DstAtop
0071:                    GLDefs.GL_ONE_MINUS_SRC_ALPHA // 11, Xor
0072:            };
0073:
0074:            private static final boolean[] HAVE_MAPPING_NO_PREMULT = new boolean[] {
0075:                    false, // No rule
0076:                    true, // 1, Clear
0077:                    true, // 2, Src
0078:                    true, // 3, SrcOver
0079:                    false, // 4, DstOver
0080:                    false, // 5, SrcIn
0081:                    true, // 6, DstIn
0082:                    false, // 7, SrcOut
0083:                    true, // 8, DstOut
0084:                    true, // 9, Dst
0085:                    false, // 10, SrcAtop
0086:                    false, // 11, DstAtop
0087:                    false // 11, Xor
0088:            };
0089:
0090:            private static final int[] BLEND_RULE_MAPPING_SRC_NO_PREMULT = new int[] {
0091:                    -1, // No rule
0092:                    GLDefs.GL_ZERO, // 1, Clear
0093:                    GLDefs.GL_SRC_ALPHA, // 2, Src
0094:                    GLDefs.GL_SRC_ALPHA, // 3, SrcOver
0095:                    -1, // 4, DstOver
0096:                    -1, // 5, SrcIn
0097:                    GLDefs.GL_ZERO, // 6, DstIn
0098:                    -1, // 7, SrcOut
0099:                    GLDefs.GL_ZERO, // 8, DstOut
0100:                    GLDefs.GL_ZERO, // 9, Dst
0101:                    -1, // 10, SrcAtop
0102:                    -1, // 11, DstAtop
0103:                    -1 // 11, Xor
0104:            };
0105:
0106:            private static final int[] BLEND_RULE_MAPPING_DST_NO_ALPHA = new int[] {
0107:                    -1, // No rule
0108:                    GLDefs.GL_ZERO, // 1, Clear
0109:                    GLDefs.GL_ZERO, // 2, Src
0110:                    GLDefs.GL_ZERO, // 3, SrcOver
0111:                    GLDefs.GL_ONE, // 4, DstOver
0112:                    GLDefs.GL_ZERO, // 5, SrcIn
0113:                    GLDefs.GL_ONE, // 6, DstIn
0114:                    GLDefs.GL_ZERO, // 7, SrcOut
0115:                    GLDefs.GL_ZERO, // 8, DstOut
0116:                    GLDefs.GL_ONE, // 9, Dst
0117:                    GLDefs.GL_ZERO, // 10, SrcAtop
0118:                    GLDefs.GL_ONE, // 11, DstAtop
0119:                    GLDefs.GL_ZERO, // 11, Xor
0120:            };
0121:
0122:            private static final GL gl = GL.getInstance();
0123:
0124:            private final double[] javaTransformMx = new double[6];
0125:            private final double[] glTransformMx = new double[16];
0126:
0127:            private OGLContextManager ctxmgr;
0128:            //private long oglContext;
0129:
0130:            private NativeWindow nwin;
0131:            Rectangle winBounds; // Cached native window bounds
0132:
0133:            // Can't use transform from CommonGraphics, want to get all mra's untransformed
0134:            private AffineTransform glTransform = new AffineTransform();
0135:
0136:            private final byte fgRgba[] = new byte[4];
0137:            boolean opaqueColor = true;
0138:            private float acAlpha = 1.0f;
0139:
0140:            private boolean oglPaint = true;
0141:            private boolean texPaint = false;
0142:            private boolean nativeLines = true;
0143:            private boolean scalingTransform = false;
0144:
0145:            private short stipplePattern;
0146:            private int stippleFactor;
0147:
0148:            /**
0149:             * gradTexName is a 2 pixel 1d texture object, used to draw gradient.
0150:             */
0151:            private int gradTexName = 0;
0152:            /**
0153:             * gradObjectPlane is used for 1d texture coordinates generation
0154:             * when gradient paint is enabled
0155:             */
0156:            private double gradObjectPlane[];
0157:            private boolean isGPCyclic;
0158:
0159:            private long oshdc = 0; // device context for windows offscreen image
0160:
0161:            public OGLGraphics2D(NativeWindow nwin, int tx, int ty,
0162:                    MultiRectArea clip) {
0163:                if (nwin instanceof  OGLVolatileImage.OGLOffscreenWindow) {
0164:                    OGLVolatileImage.OGLOffscreenWindow offWin = (OGLVolatileImage.OGLOffscreenWindow) nwin;
0165:                    oshdc = offWin.getHdc();
0166:                }
0167:
0168:                this .nwin = nwin;
0169:
0170:                ctxmgr = (OGLContextManager) getDeviceConfiguration();
0171:                //long oglContext = ctxmgr.getOGLContext();
0172:
0173:                // Get the viewport (=native window) width and height
0174:                winBounds = nwin.getBounds();
0175:
0176:                if (clip != null) {
0177:                    Rectangle bounds = clip.getBounds();
0178:                    dstSurf = new OGLSurface(bounds.width, bounds.height, this );
0179:                } else {
0180:                    dstSurf = new OGLSurface(winBounds.width, winBounds.height,
0181:                            this );
0182:                }
0183:
0184:                makeCurrent();
0185:
0186:                resetBounds();
0187:
0188:                // Apply the translation
0189:                gl.glLoadIdentity();
0190:                glTransform = AffineTransform.getTranslateInstance(tx, ty);
0191:                gl.glTranslated(tx, ty, 0);
0192:
0193:                // Super class constructor sets untransformed clip
0194:                setTransformedClip(clip);
0195:
0196:                origPoint = new Point(tx, ty);
0197:
0198:                blitter = OGLBlitter.getInstance();
0199:
0200:                if (!FontManager.IS_FONTLIB) {
0201:                    jtr = new OGLTextRenderer();
0202:                }
0203:            }
0204:
0205:            public OGLGraphics2D(NativeWindow nwin, int tx, int ty, int width,
0206:                    int height) {
0207:                this (nwin, tx, ty, new MultiRectArea(new Rectangle(width,
0208:                        height)));
0209:            }
0210:
0211:            @Override
0212:            public Graphics create() {
0213:                OGLGraphics2D res = new OGLGraphics2D(nwin, 0, 0, dstSurf
0214:                        .getWidth(), dstSurf.getHeight());
0215:
0216:                copyInternalFields(res);
0217:
0218:                // Have to copy transform and clip explicitly, since we use opengl transforms
0219:                res.setTransform(new AffineTransform(glTransform));
0220:                if (clip == null) {
0221:                    res.setTransformedClip(null);
0222:                } else {
0223:                    res.setTransformedClip(new MultiRectArea(clip));
0224:                }
0225:
0226:                return res;
0227:            }
0228:
0229:            @Override
0230:            public void finalize() {
0231:                super .finalize();
0232:                try {
0233:                    EventQueue.invokeAndWait(new Runnable() {
0234:                        public void run() {
0235:                            dispose();
0236:                        }
0237:                    });
0238:                } catch (Exception e) {
0239:                    e.printStackTrace(); // Something bad happened
0240:                }
0241:            }
0242:
0243:            @Override
0244:            public GraphicsConfiguration getDeviceConfiguration() {
0245:                GraphicsEnvironment env = GraphicsEnvironment
0246:                        .getLocalGraphicsEnvironment();
0247:                return env.getDefaultScreenDevice().getDefaultConfiguration();
0248:            }
0249:
0250:            @Override
0251:            public void copyArea(int x, int y, int width, int height, int dx,
0252:                    int dy) {
0253:                makeCurrent();
0254:
0255:                gl.glPixelZoom(1, 1);
0256:
0257:                // Raster position could be outside of the viewport, use glBitmap
0258:                gl.glRasterPos2i(0, 0);
0259:                gl.glBitmap(0, 0, 0, 0, x + dx, -y - dy - height, 0);
0260:
0261:                x += glTransform.getTranslateX() + 0.5;
0262:                y += glTransform.getTranslateY() + 0.5;
0263:
0264:                gl.glCopyPixels(x, winBounds.height - y - height, width,
0265:                        height, GLDefs.GL_COLOR);
0266:                gl.glFlush();
0267:                getSurface().updateScene();
0268:            }
0269:
0270:            @Override
0271:            public void setPaint(Paint paint) {
0272:                if (paint == null)
0273:                    return;
0274:
0275:                super .setPaint(paint);
0276:
0277:                makeCurrent();
0278:
0279:                if (paint instanceof  Color) {
0280:                    deactivateTexturePaint();
0281:                    deactivateGradientPaint();
0282:                    setColor((Color) paint);
0283:                    oglPaint = true;
0284:                    texPaint = false;
0285:                } else if (paint instanceof  GradientPaint) {
0286:                    deactivateTexturePaint();
0287:                    activateGradientPaint((GradientPaint) paint);
0288:                    oglPaint = true;
0289:                    texPaint = false;
0290:                } else if (paint instanceof  TexturePaint) {
0291:                    deactivateGradientPaint();
0292:                    activateTexturePaint((TexturePaint) paint);
0293:                    oglPaint = true;
0294:                    texPaint = true;
0295:                } else {
0296:                    deactivateTexturePaint();
0297:                    deactivateGradientPaint();
0298:                    oglPaint = false;
0299:                    texPaint = false;
0300:                }
0301:            }
0302:
0303:            void resetPaint() {
0304:                if (gradTexName != 0) {
0305:                    deactivateTexturePaint();
0306:                    reactivateGradientPaint();
0307:                } else {
0308:                    setPaint(paint);
0309:                }
0310:            }
0311:
0312:            @Override
0313:            public void setColor(Color color) {
0314:                if (color == null) {
0315:                    return;
0316:                }
0317:
0318:                super .setColor(color);
0319:
0320:                makeCurrent();
0321:
0322:                // Set gl color
0323:                int val = color.getRGB();
0324:                fgRgba[0] = (byte) ((val >> 16) & 0xFF);
0325:                fgRgba[1] = (byte) ((val >> 8) & 0xFF);
0326:                fgRgba[2] = (byte) (val & 0xFF);
0327:                fgRgba[3] = (byte) ((val >> 24) & 0xFF);
0328:
0329:                // Need to premultiply alpha
0330:                if ((fgRgba[3] & 0xFF) != 0xFF || acAlpha != 1.0f) {
0331:                    float alpha = (fgRgba[3] & 0xFF) / 255.0f;
0332:                    fgRgba[0] = (byte) ((fgRgba[0] & 0xFF) * acAlpha * alpha + 0.5);
0333:                    fgRgba[1] = (byte) ((fgRgba[1] & 0xFF) * acAlpha * alpha + 0.5);
0334:                    fgRgba[2] = (byte) ((fgRgba[2] & 0xFF) * acAlpha * alpha + 0.5);
0335:                    // Also use acAlpha
0336:                    fgRgba[3] = (byte) ((fgRgba[3] & 0xFF) * acAlpha + 0.5);
0337:                }
0338:
0339:                LockedArray lColor = Utils.arraccess.lockArrayShort(fgRgba);
0340:                gl.glColor4ubv(lColor.getAddress());
0341:                lColor.release();
0342:
0343:                // If color becomes translucent, probably need to enable blending
0344:                if (opaqueColor != ((fgRgba[3] & 0xFF) == 0xFF)) {
0345:                    opaqueColor = (fgRgba[3] & 0xFF) == 0xFF;
0346:                    checkComposite();
0347:                }
0348:
0349:                // And, finally, update paint
0350:                if (texPaint) {
0351:                    deactivateTexturePaint();
0352:                    texPaint = false;
0353:                } else if (gradTexName != 0) {
0354:                    deactivateGradientPaint();
0355:                }
0356:                paint = color;
0357:                oglPaint = true;
0358:            }
0359:
0360:            @Override
0361:            public void dispose() {
0362:                super .dispose();
0363:                /*
0364:                if (oglContext != 0) {
0365:                    ctxmgr.destroyOGLContext(oglContext);
0366:                    oglContext = 0;
0367:                }*/
0368:            }
0369:
0370:            final void makeCurrent() {
0371:                long oglContext = ctxmgr.getOGLContext(nwin.getId(), oshdc);
0372:                ctxmgr.makeCurrent(oglContext, nwin.getId(), oshdc);
0373:                OGLContextValidator.validateContext(this );
0374:            }
0375:
0376:            private int[] createVertexArray(MultiRectArea mra) {
0377:                int rect[] = mra.rect;
0378:                int resSize = (rect[0] - 1) << 1;
0379:
0380:                int[] res = null;
0381:
0382:                if (resSize > 0) {
0383:                    //int resSize = nRects*8;
0384:                    int rectOffset = 1;
0385:                    res = new int[resSize];
0386:                    for (int i = 0; i < resSize; i += 8, rectOffset += 4) {
0387:                        // Left, top
0388:                        res[i] = rect[rectOffset];
0389:                        res[i + 1] = rect[rectOffset + 1];
0390:                        // Right, top
0391:                        res[i + 2] = rect[rectOffset + 2] + 1;
0392:                        res[i + 3] = rect[rectOffset + 1];
0393:                        // Right, bottom
0394:                        res[i + 4] = rect[rectOffset + 2] + 1;
0395:                        res[i + 5] = rect[rectOffset + 3] + 1;
0396:                        // Left, bottom
0397:                        res[i + 6] = rect[rectOffset];
0398:                        res[i + 7] = rect[rectOffset + 3] + 1;
0399:                    }
0400:                }
0401:
0402:                return res;
0403:            }
0404:
0405:            @Override
0406:            protected void fillMultiRectAreaColor(MultiRectArea mra) {
0407:                makeCurrent();
0408:
0409:                if (((mra.rect[0] - 1)) > 0) { // Have something to draw
0410:                    int vertices[] = createVertexArray(mra);
0411:                    LockedArray lVertices = Utils.arraccess
0412:                            .lockArrayShort(vertices);
0413:
0414:                    gl.glVertexPointer(2, GLDefs.GL_INT, 0, lVertices
0415:                            .getAddress());
0416:
0417:                    // At least one configuration (ATI MOBILITY FIRE GL T2 card on win32) has
0418:                    // problems with the large arrays, so workaround is used when
0419:                    // the number of vertices exceeds 1024
0420:                    if (vertices.length < 2048) {
0421:                        gl
0422:                                .glDrawArrays(GLDefs.GL_QUADS, 0,
0423:                                        vertices.length / 2);
0424:                    } else {
0425:                        int iters = vertices.length / 2048;
0426:                        for (int i = 0; i < iters; i++) {
0427:                            gl.glDrawArrays(GLDefs.GL_QUADS, i * 1024, 1024);
0428:                        }
0429:                        gl.glDrawArrays(GLDefs.GL_QUADS, iters * 1024,
0430:                                (vertices.length % 2048) / 2);
0431:                    }
0432:
0433:                    lVertices.release();
0434:                }
0435:
0436:                gl.glFlush();
0437:                getSurface().updateScene();
0438:            }
0439:
0440:            @Override
0441:            public void drawString(String str, float x, float y) {
0442:                makeCurrent();
0443:
0444:                if (paint instanceof  Color) {
0445:                    AffineTransform at = (AffineTransform) glTransform.clone();
0446:                    jtr.drawString(this , str, x, y);
0447:                    setTransform(at);
0448:                } else {
0449:                    this .fill(font.createGlyphVector(
0450:                            this .getFontRenderContext(), str).getOutline(x, y));
0451:                }
0452:
0453:                gl.glFlush();
0454:                getSurface().updateScene();
0455:            }
0456:
0457:            @Override
0458:            public void drawGlyphVector(GlyphVector gv, float x, float y) {
0459:                makeCurrent();
0460:
0461:                if (paint instanceof  Color) {
0462:                    AffineTransform at = (AffineTransform) glTransform.clone();
0463:                    jtr.drawGlyphVector(this , gv, x, y);
0464:                    setTransform(at);
0465:                } else {
0466:                    this .fill(gv.getOutline(x, y));
0467:                }
0468:
0469:                gl.glFlush();
0470:                getSurface().updateScene();
0471:            }
0472:
0473:            @Override
0474:            protected void setTransformedClip(MultiRectArea clip) {
0475:                super .setTransformedClip(clip);
0476:                //if (oglContext != 0) {
0477:                if (ctxmgr != null) {
0478:                    makeCurrent();
0479:
0480:                    if (clip == null) { // Disable clip
0481:                        gl.glDisable(GLDefs.GL_STENCIL_TEST);
0482:                        gl.glDisable(GLDefs.GL_SCISSOR_TEST);
0483:
0484:                    } else if (clip.rect[0] < 5) { // Emplty clip, no drwing allowed
0485:                        gl.glDisable(GLDefs.GL_STENCIL_TEST);
0486:                        gl.glEnable(GLDefs.GL_SCISSOR_TEST);
0487:                        gl.glScissor(0, 0, 0, 0);
0488:
0489:                    } else if (clip.rect[0] == 5) { // Define scissor box - have only one clip rect
0490:                        gl.glDisable(GLDefs.GL_STENCIL_TEST);
0491:                        gl.glEnable(GLDefs.GL_SCISSOR_TEST);
0492:
0493:                        // Need to transform clip origin, since ogl transform
0494:                        // is not applied by glScissor
0495:                        // Probably should be (int) (glTransform.getTranslateX() + 0.5)
0496:                        // but this gives a 1 pixel error with swing scrolling
0497:                        int tx = (int) (glTransform.getTranslateX());
0498:                        int ty = (int) (glTransform.getTranslateY());
0499:
0500:                        gl.glScissor(clip.rect[1] + tx, winBounds.height
0501:                                - clip.rect[4] - 1 - ty, clip.rect[3]
0502:                                - clip.rect[1] + 1, clip.rect[4] - clip.rect[2]
0503:                                + 1);
0504:                    } else { // Several clip rects, use stencil
0505:
0506:                        gl.glDisable(GLDefs.GL_SCISSOR_TEST);
0507:                        gl.glEnable(GLDefs.GL_STENCIL_TEST);
0508:
0509:                        gl.glClear(GLDefs.GL_STENCIL_BUFFER_BIT);
0510:
0511:                        gl.glColorMask((byte) GLDefs.GL_FALSE,
0512:                                (byte) GLDefs.GL_FALSE, (byte) GLDefs.GL_FALSE,
0513:                                (byte) GLDefs.GL_FALSE);
0514:                        gl.glStencilFunc(GLDefs.GL_ALWAYS, 0x1, 0x1);
0515:                        gl.glStencilOp(GLDefs.GL_REPLACE, GLDefs.GL_REPLACE,
0516:                                GLDefs.GL_REPLACE);
0517:
0518:                        // Draw the clip area into the stencil buffer
0519:                        fillMultiRectAreaColor(clip);
0520:
0521:                        gl.glColorMask((byte) GLDefs.GL_TRUE,
0522:                                (byte) GLDefs.GL_TRUE, (byte) GLDefs.GL_TRUE,
0523:                                (byte) GLDefs.GL_TRUE);
0524:                        gl.glStencilFunc(GLDefs.GL_EQUAL, 0x1, 0x1);
0525:                        gl.glStencilOp(GLDefs.GL_KEEP, GLDefs.GL_KEEP,
0526:                                GLDefs.GL_KEEP);
0527:                    }
0528:                }
0529:            }
0530:
0531:            @Override
0532:            public void setTransform(AffineTransform transform) {
0533:                // If transform is scaling drop native lines and use rasterizer
0534:                if ((transform.getType() & AffineTransform.TYPE_MASK_SCALE) != 0) {
0535:                    scalingTransform = true;
0536:                } else {
0537:                    scalingTransform = false;
0538:                }
0539:
0540:                //if (oglContext != 0) {
0541:                if (ctxmgr != null) {
0542:                    double clipTranslationX = -transform.getTranslateX()
0543:                            + glTransform.getTranslateX();
0544:                    double clipTranslationY = -transform.getTranslateY()
0545:                            + glTransform.getTranslateY();
0546:
0547:                    this .glTransform = transform;
0548:
0549:                    if (clip != null) {
0550:                        clip.translate(Math.round((float) clipTranslationX),
0551:                                Math.round((float) clipTranslationY));
0552:                    }
0553:
0554:                    makeCurrent();
0555:                    gl.glLoadIdentity();
0556:
0557:                    switch (transform.getType()) {
0558:                    case AffineTransform.TYPE_TRANSLATION: {
0559:                        gl.glTranslated(transform.getTranslateX(), transform
0560:                                .getTranslateY(), 0);
0561:                        break;
0562:                    }
0563:
0564:                    case AffineTransform.TYPE_GENERAL_SCALE:
0565:                    case AffineTransform.TYPE_UNIFORM_SCALE: {
0566:                        gl.glScaled(transform.getScaleX(), transform
0567:                                .getScaleY(), 0);
0568:                        break;
0569:                    }
0570:
0571:                    case AffineTransform.TYPE_IDENTITY:
0572:                        break;
0573:
0574:                    default: {
0575:                        transform.getMatrix(javaTransformMx);
0576:                        Arrays.fill(glTransformMx, 0);
0577:                        glTransformMx[0] = javaTransformMx[0];
0578:                        glTransformMx[1] = javaTransformMx[1];
0579:                        glTransformMx[4] = javaTransformMx[2];
0580:                        glTransformMx[5] = javaTransformMx[3];
0581:                        glTransformMx[12] = javaTransformMx[4];
0582:                        glTransformMx[13] = javaTransformMx[5];
0583:                        glTransformMx[10] = 1;
0584:                        glTransformMx[15] = 1;
0585:
0586:                        LockedArray lMx = Utils.arraccess
0587:                                .lockArrayShort(glTransformMx);
0588:                        gl.glLoadMatrixd(lMx.getAddress());
0589:                        lMx.release();
0590:                    }
0591:                    }
0592:
0593:                    // Fix line rasterization
0594:                    gl.glTranslated(0.375, 0.375, 0);
0595:
0596:                    // Update paint if it is TexturePaint or GradientPaint
0597:                    if (texPaint || gradTexName != 0) {
0598:                        resetPaint();
0599:                    }
0600:                }
0601:            }
0602:
0603:            @Override
0604:            public Shape getClip() {
0605:                if (clip == null) {
0606:                    return null;
0607:                }
0608:
0609:                MultiRectArea res = new MultiRectArea(clip);
0610:                return res;
0611:            }
0612:
0613:            @Override
0614:            public Rectangle getClipBounds() {
0615:                if (clip == null) {
0616:                    return null;
0617:                }
0618:
0619:                Rectangle res = (Rectangle) clip.getBounds().clone();
0620:                return res;
0621:            }
0622:
0623:            @Override
0624:            public AffineTransform getTransform() {
0625:                return (AffineTransform) glTransform.clone();
0626:            }
0627:
0628:            @Override
0629:            public void rotate(double theta) {
0630:                glTransform.rotate(theta);
0631:                setTransform(glTransform);
0632:            }
0633:
0634:            @Override
0635:            public void rotate(double theta, double x, double y) {
0636:                glTransform.rotate(theta, x, y);
0637:                setTransform(glTransform);
0638:            }
0639:
0640:            @Override
0641:            public void scale(double sx, double sy) {
0642:                glTransform.scale(sx, sy);
0643:                setTransform(glTransform);
0644:            }
0645:
0646:            @Override
0647:            public void shear(double shx, double shy) {
0648:                glTransform.shear(shx, shy);
0649:                setTransform(glTransform);
0650:            }
0651:
0652:            @Override
0653:            public void transform(AffineTransform at) {
0654:                AffineTransform newTransform = (AffineTransform) glTransform
0655:                        .clone();
0656:                newTransform.concatenate(at);
0657:                setTransform(newTransform);
0658:            }
0659:
0660:            @Override
0661:            public void translate(double tx, double ty) {
0662:                AffineTransform newTransform = (AffineTransform) glTransform
0663:                        .clone();
0664:                newTransform.translate(tx, ty);
0665:                setTransform(newTransform);
0666:            }
0667:
0668:            @Override
0669:            public void translate(int tx, int ty) {
0670:                AffineTransform newTransform = (AffineTransform) glTransform
0671:                        .clone();
0672:                newTransform.translate(tx, ty);
0673:                setTransform(newTransform);
0674:            }
0675:
0676:            @Override
0677:            public void clipRect(int x, int y, int width, int height) {
0678:                MultiRectArea mra = new MultiRectArea(x, y, x + width - 1, y
0679:                        + height - 1);
0680:
0681:                if (clip == null) {
0682:                    setTransformedClip(mra);
0683:                } else {
0684:                    clip.intersect(mra);
0685:                    setTransformedClip(clip);
0686:                }
0687:            }
0688:
0689:            @Override
0690:            public void fillRect(int x, int y, int width, int height) {
0691:                if (oglPaint) {
0692:                    makeCurrent();
0693:                    gl.glRectd(x, y, x + width, y + height);
0694:                    gl.glFlush();
0695:                } else {
0696:                    super .fillRect(x, y, width, height);
0697:                }
0698:
0699:                getSurface().updateScene();
0700:            }
0701:
0702:            @Override
0703:            public void drawLine(int x1, int y1, int x2, int y2) {
0704:                if (nativeLines && !scalingTransform && oglPaint) {
0705:                    makeCurrent();
0706:
0707:                    int vertices[] = new int[4];
0708:                    vertices[0] = x1;
0709:                    vertices[1] = y1;
0710:                    vertices[2] = x2;
0711:                    vertices[3] = y2;
0712:
0713:                    LockedArray lVertices = Utils.arraccess
0714:                            .lockArrayShort(vertices);
0715:                    gl.glVertexPointer(2, GLDefs.GL_INT, 0, lVertices
0716:                            .getAddress());
0717:                    gl.glDrawArrays(GLDefs.GL_LINES, 0, vertices.length / 2);
0718:                    lVertices.release();
0719:
0720:                    gl.glFlush();
0721:                } else {
0722:                    super .drawLine(x1, y1, x2, y2);
0723:                }
0724:
0725:                getSurface().updateScene();
0726:            }
0727:
0728:            private final void resetClip() {
0729:                setTransformedClip(clip);
0730:            }
0731:
0732:            private final void resetColor() {
0733:                setColor(fgColor);
0734:            }
0735:
0736:            private final void resetTransform() {
0737:                setTransform(glTransform);
0738:            }
0739:
0740:            private final void resetBounds() {
0741:                // Set viewport and projection
0742:                // Always set the viewport to the whole window
0743:                gl.glViewport(0, 0, winBounds.width, winBounds.height);
0744:
0745:                gl.glMatrixMode(GLDefs.GL_PROJECTION);
0746:                gl.glLoadIdentity();
0747:                gl.gluOrtho2D(0, winBounds.width, winBounds.height, 0);
0748:
0749:                gl.glMatrixMode(GLDefs.GL_MODELVIEW);
0750:            }
0751:
0752:            private static class OGLContextValidator {
0753:                private static final ThreadLocal<OGLGraphics2D> localCurrentGraphics = new ThreadLocal<OGLGraphics2D>();
0754:
0755:                private static final void validateContext(OGLGraphics2D g) {
0756:                    OGLGraphics2D lastGraphics = localCurrentGraphics.get();
0757:
0758:                    if (lastGraphics == null) {
0759:                        // No graphics was used before in the current thread, so
0760:                        // opengl context of this thread should be initialized first
0761:
0762:                        // Single-buffered
0763:                        gl.glDrawBuffer(GLDefs.GL_FRONT);
0764:                        gl.glReadBuffer(GLDefs.GL_FRONT);
0765:
0766:                        gl.glEnableClientState(GLDefs.GL_VERTEX_ARRAY);
0767:                        gl.glDisable(GLDefs.GL_DITHER);
0768:
0769:                        localCurrentGraphics.set(g);
0770:
0771:                        if (g.blitter instanceof  NullBlitter) {
0772:                            // Called from constructor, skipping validation.
0773:                            // Everything will be done in the constructor.
0774:                            return;
0775:                        }
0776:                        // New context in the thread, but old graphics from other thread,
0777:                        // have to validate all.
0778:                        g.resetBounds();
0779:                        g.resetColor();
0780:                        g.resetTransform();
0781:                        g.resetClip();
0782:                        g.checkComposite();
0783:                        g.resetStroke();
0784:                        g.resetPaint();
0785:                        return;
0786:                    } else if (g == lastGraphics) { // Should have all the attributes in place
0787:                        return;
0788:                    }
0789:
0790:                    localCurrentGraphics.set(g);
0791:
0792:                    if (!g.winBounds.equals(lastGraphics.winBounds)) {
0793:                        g.resetBounds();
0794:                    }
0795:
0796:                    if (!g.fgColor.equals(lastGraphics.fgColor)) {
0797:                        g.resetColor();
0798:                    }
0799:
0800:                    boolean transformDiffers = !g.glTransform
0801:                            .equals(lastGraphics.glTransform);
0802:                    if (transformDiffers) {
0803:                        g.resetTransform();
0804:                    }
0805:
0806:                    if (g.clip == null) {
0807:                        if (lastGraphics.clip != null) {
0808:                            g.resetClip();
0809:                        }
0810:                    } else if (!g.clip.equals(lastGraphics.clip)
0811:                            || transformDiffers) {
0812:                        g.resetClip();
0813:                    }
0814:
0815:                    if (!g.composite.equals(lastGraphics.composite)) {
0816:                        g.checkComposite();
0817:                    }
0818:
0819:                    if (!g.stroke.equals(lastGraphics.stroke)) {
0820:                        g.resetStroke();
0821:                    }
0822:
0823:                    if (!g.paint.equals(lastGraphics.paint)) {
0824:                        g.resetPaint();
0825:                    }
0826:                }
0827:            }
0828:
0829:            @Override
0830:            public void setComposite(Composite composite) {
0831:                super .setComposite(composite);
0832:
0833:                makeCurrent();
0834:                checkComposite();
0835:            }
0836:
0837:            /**
0838:             * NOTE - caller should call makeCurrent() before calling this method
0839:             */
0840:            final void checkComposite() {
0841:                if (composite instanceof  AlphaComposite) {
0842:                    AlphaComposite ac = (AlphaComposite) composite;
0843:                    acAlpha = ac.getAlpha();
0844:
0845:                    if (ac.getAlpha() == 1
0846:                            && opaqueColor
0847:                            && (ac.getRule() == AlphaComposite.SRC_OVER || ac
0848:                                    .getRule() == AlphaComposite.SRC)) {
0849:                        gl.glDisable(GLDefs.GL_BLEND);
0850:                    } else {
0851:                        enableAlphaComposite(ac, true, true);
0852:                        //gl.glEnable(GLDefs.GL_BLEND);
0853:                    }
0854:
0855:                    if (ac.getAlpha() != 1) {
0856:                        setColor(bgColor);
0857:                    }
0858:                } else {
0859:                    acAlpha = 1.0f;
0860:                }
0861:            }
0862:
0863:            /**
0864:             * NOTE - caller should call makeCurrent() before calling this method
0865:             * @param ac
0866:             * @param srcPremult
0867:             * @param srcHasAlpha
0868:             * @return true if caller should not premultiply the source, false otherwise
0869:             */
0870:            final static boolean enableAlphaComposite(AlphaComposite ac,
0871:                    boolean srcPremult, boolean srcHasAlpha) {
0872:                float acAlpha = ac.getAlpha();
0873:                int acRule = ac.getRule();
0874:
0875:                int srcFactor;
0876:                int dstFactor;
0877:                int alphaFactor = BLEND_RULE_MAPPING_SRC_PREMULT[acRule];
0878:
0879:                boolean needPremultiply = false;
0880:
0881:                if (srcHasAlpha) {
0882:                    if (srcPremult || !HAVE_MAPPING_NO_PREMULT[acRule]) {
0883:                        srcFactor = BLEND_RULE_MAPPING_SRC_PREMULT[acRule];
0884:                        if (!srcPremult) { // Caller should premultiply the source
0885:                            needPremultiply = true;
0886:                        }
0887:                    } else {
0888:                        srcFactor = BLEND_RULE_MAPPING_SRC_NO_PREMULT[acRule];
0889:                    }
0890:                    dstFactor = BLEND_RULE_MAPPING_DST[acRule];
0891:                } else {
0892:                    srcFactor = BLEND_RULE_MAPPING_SRC_PREMULT[acRule];
0893:
0894:                    if (srcFactor == GLDefs.GL_ONE && acAlpha == 1) {
0895:                        gl.glDisable(GLDefs.GL_BLEND);
0896:                        return true;
0897:                    }
0898:
0899:                    dstFactor = BLEND_RULE_MAPPING_DST_NO_ALPHA[acRule];
0900:                }
0901:
0902:                gl.glEnable(GLDefs.GL_BLEND);
0903:
0904:                if (srcFactor == alphaFactor) {
0905:                    gl.glBlendFunc(srcFactor, dstFactor);
0906:                } else {
0907:                    gl.glBlendFuncSeparate(srcFactor, dstFactor, alphaFactor,
0908:                            dstFactor);
0909:                }
0910:
0911:                // Setup alpha scaling for the case when alpha in AlphaComposite != 1
0912:                gl.glPixelTransferf(GLDefs.GL_ALPHA_SCALE, acAlpha);
0913:                if (srcPremult || needPremultiply) {
0914:                    gl.glPixelTransferf(GLDefs.GL_RED_SCALE, acAlpha);
0915:                    gl.glPixelTransferf(GLDefs.GL_GREEN_SCALE, acAlpha);
0916:                    gl.glPixelTransferf(GLDefs.GL_BLUE_SCALE, acAlpha);
0917:                } else {
0918:                    gl.glPixelTransferf(GLDefs.GL_RED_SCALE, 1);
0919:                    gl.glPixelTransferf(GLDefs.GL_GREEN_SCALE, 1);
0920:                    gl.glPixelTransferf(GLDefs.GL_BLUE_SCALE, 1);
0921:                }
0922:
0923:                return needPremultiply;
0924:            }
0925:
0926:            final OGLSurface getSurface() {
0927:                return (OGLSurface) dstSurf;
0928:            }
0929:
0930:            void readPixels(int x, int y, int w, int h, Object buffer,
0931:                    boolean topToBottom) {
0932:                // Save current graphics to restore current context after returning pixels
0933:                OGLGraphics2D currGraphics = OGLContextValidator.localCurrentGraphics
0934:                        .get();
0935:                makeCurrent();
0936:                /*
0937:                 x += glTransform.getTranslateX() + 0.5;
0938:                 y += glTransform.getTranslateY() + 0.5;
0939:                 */
0940:                LockedArray lBuffer = Utils.arraccess.lockArrayShort(buffer);
0941:
0942:                if (topToBottom) {
0943:                    // Need to read scanlines one-by-one to make them go from top to bottom.
0944:                    // OpenGL allows to read from bottom to top only.
0945:                    int sourceRow = winBounds.height - y - 1;
0946:                    for (int i = 0; i < h; i++, sourceRow--) {
0947:                        gl.glPixelStorei(GLDefs.GL_PACK_SKIP_ROWS, i);
0948:                        gl.glReadPixels(x, sourceRow, w, 1, GLDefs.GL_BGRA,
0949:                                GLDefs.GL_UNSIGNED_INT_8_8_8_8_REV, lBuffer
0950:                                        .getAddress());
0951:                    }
0952:                } else {
0953:                    gl.glReadPixels(x, winBounds.height - y - h, w, h,
0954:                            GLDefs.GL_BGRA, GLDefs.GL_UNSIGNED_INT_8_8_8_8_REV,
0955:                            lBuffer.getAddress());
0956:                }
0957:
0958:                lBuffer.release();
0959:
0960:                gl.glPixelStorei(GLDefs.GL_PACK_SKIP_ROWS, 0);
0961:
0962:                if (currGraphics != null && currGraphics != this ) {
0963:                    currGraphics.makeCurrent();
0964:                }
0965:            }
0966:
0967:            @Override
0968:            public void setStroke(Stroke stroke) {
0969:                super .setStroke(stroke);
0970:                if (stroke instanceof  BasicStroke) {
0971:                    BasicStroke bs = (BasicStroke) stroke;
0972:                    if (bs.getLineWidth() <= 1.) {
0973:                        if (bs.getDashArray() != null) {
0974:                            if (setLineStipplePattern(bs.getDashArray(), bs
0975:                                    .getDashPhase())) {
0976:                                nativeLines = true;
0977:                                resetStroke();
0978:                                return;
0979:                            }
0980:                        } else {
0981:                            nativeLines = true;
0982:                            stipplePattern = 0;
0983:                            resetStroke();
0984:                            return;
0985:                        }
0986:                    }
0987:                }
0988:
0989:                nativeLines = false;
0990:                stipplePattern = 0;
0991:            }
0992:
0993:            /**
0994:             * Calculates opengl line stipple parameters from dashArray and dashPhase taken from
0995:             * BasicStroke.
0996:             * @param dashArray - array, taken from BasicStroke
0997:             * @param dashPhase - phase, taken from BasicStroke
0998:             * @return fasle if it is impossible to use glLineStipple, true otherwise.
0999:             */
1000:            private boolean setLineStipplePattern(float dashArray[],
1001:                    float dashPhase) {
1002:                // if there's odd number of elements in the dash array, we repeat it twice
1003:                int longArrLength = dashArray.length % 2 == 0 ? dashArray.length
1004:                        : dashArray.length * 2;
1005:                long longArray[] = new long[longArrLength];
1006:                long longPhase = Math.round(dashPhase);
1007:                BigInteger gcd = BigInteger.valueOf(Math.round(dashArray[0]));
1008:                int sum = 0;
1009:                for (int i = 0; i < longArrLength; i++) {
1010:                    longArray[i] = Math.round(dashArray[i % dashArray.length]);
1011:                    gcd = gcd.gcd(BigInteger.valueOf(longArray[i]));
1012:                    sum += longArray[i];
1013:                }
1014:
1015:                if (dashPhase != 0) {
1016:                    gcd = gcd.gcd(BigInteger.valueOf(longPhase));
1017:                    longPhase /= gcd.longValue();
1018:                }
1019:
1020:                sum /= gcd.longValue();
1021:
1022:                if (sum > 16) {
1023:                    return false;
1024:                }
1025:
1026:                int repeatNum;
1027:
1028:                switch (sum) {
1029:                case 1:
1030:                    repeatNum = 16;
1031:                    break;
1032:                case 2:
1033:                    repeatNum = 8;
1034:                    break;
1035:                case 4:
1036:                    repeatNum = 4;
1037:                    break;
1038:                case 8:
1039:                    repeatNum = 2;
1040:                    break;
1041:                case 16:
1042:                    repeatNum = 1;
1043:                    break;
1044:                default:
1045:                    return false;
1046:                }
1047:
1048:                int intPattern = 0;
1049:                stippleFactor = (int) gcd.longValue();
1050:
1051:                for (int i = 0; i < repeatNum; i++) {
1052:                    for (int j = longArray.length - 1; j >= 0; j--) {
1053:                        long currPatternLen = longArray[j] / stippleFactor;
1054:                        intPattern <<= currPatternLen;
1055:                        if ((j & 0x1) == 0) {
1056:                            intPattern |= (1 << currPatternLen) - 1;
1057:                        }
1058:                    }
1059:                }
1060:
1061:                if (longPhase != 0) { // cyclic shift
1062:                    intPattern = (intPattern >>> longPhase)
1063:                            | (intPattern << (16 - longPhase));
1064:                }
1065:
1066:                stipplePattern = (short) (intPattern & 0xFFFF);
1067:
1068:                return true;
1069:            }
1070:
1071:            /**
1072:             * Validates stroke.
1073:             */
1074:            void resetStroke() {
1075:                if (nativeLines) {
1076:                    // Use opengl only for 1-width lines, don't need to set width
1077:                    if (stipplePattern == 0) {
1078:                        gl.glDisable(GLDefs.GL_LINE_STIPPLE);
1079:                    } else {
1080:                        gl.glEnable(GLDefs.GL_LINE_STIPPLE);
1081:                        gl.glLineStipple(stippleFactor, stipplePattern);
1082:                    }
1083:                } else {
1084:                    gl.glDisable(GLDefs.GL_LINE_STIPPLE);
1085:                }
1086:            }
1087:
1088:            @Override
1089:            public void drawPolygon(Polygon polygon) {
1090:                drawPolygon(polygon.xpoints, polygon.ypoints, polygon.npoints);
1091:            }
1092:
1093:            @Override
1094:            public void drawPolygon(int[] xpoints, int[] ypoints, int npoints) {
1095:                drawPoly(xpoints, ypoints, npoints, true);
1096:            }
1097:
1098:            @Override
1099:            public void drawPolyline(int[] xpoints, int[] ypoints, int npoints) {
1100:                drawPoly(xpoints, ypoints, npoints, false);
1101:            }
1102:
1103:            private final void drawPoly(int[] xpoints, int[] ypoints,
1104:                    int npoints, boolean closed) {
1105:                if (nativeLines && !scalingTransform && oglPaint) {
1106:                    makeCurrent();
1107:
1108:                    int vertices[] = new int[npoints << 1];
1109:                    for (int i = 0; i < npoints; i++) {
1110:                        vertices[i << 1] = xpoints[i];
1111:                        vertices[(i << 1) + 1] = ypoints[i];
1112:                    }
1113:
1114:                    LockedArray lVertices = Utils.arraccess
1115:                            .lockArrayShort(vertices);
1116:                    gl.glVertexPointer(2, GLDefs.GL_INT, 0, lVertices
1117:                            .getAddress());
1118:                    gl.glDrawArrays(closed ? GLDefs.GL_LINE_LOOP
1119:                            : GLDefs.GL_LINE_STRIP, 0, vertices.length / 2);
1120:                    lVertices.release();
1121:
1122:                    gl.glFlush();
1123:                } else {
1124:                    if (closed) {
1125:                        super .drawPolygon(xpoints, ypoints, npoints);
1126:                    } else {
1127:                        super .drawPolyline(xpoints, ypoints, npoints);
1128:                    }
1129:                }
1130:
1131:                getSurface().updateScene();
1132:            }
1133:
1134:            @Override
1135:            public void draw(Shape s) {
1136:                // To get proper rasterization quality need to
1137:                // perform scaling before rasterization
1138:                if (scalingTransform) {
1139:                    s = stroke.createStrokedShape(s);
1140:                    s = glTransform.createTransformedShape(s);
1141:                    gl.glPushMatrix();
1142:                    gl.glLoadIdentity();
1143:                    fillMultiRectArea(jsr.rasterize(s, 0.5));
1144:                    gl.glPopMatrix();
1145:                } else {
1146:                    super .draw(s);
1147:                }
1148:            }
1149:
1150:            void activateTexturePaint(TexturePaint p) {
1151:                Rectangle2D r = p.getAnchorRect();
1152:                /*
1153:                if (r.getX() != 0 || r.getY() != 0) {
1154:                    gl.glPixelStoref(GLDefs.GL_UNPACK_SKIP_PIXELS, (float)r.getX());
1155:                    gl.glPixelStoref(GLDefs.GL_UNPACK_SKIP_ROWS, (float)r.getY());
1156:                }
1157:                 */
1158:                Surface srcSurf = Surface.getImageSurface(p.getImage());
1159:
1160:                int width = (int) r.getWidth();
1161:                int height = (int) r.getHeight();
1162:
1163:                OGLBlitter oglBlitter = (OGLBlitter) blitter;
1164:
1165:                OGLBlitter.OGLTextureParams tp = oglBlitter
1166:                        .blitImg2OGLTexCached(srcSurf, srcSurf.getWidth(),
1167:                                srcSurf.getHeight(), true);
1168:
1169:                gl.glTexParameteri(GLDefs.GL_TEXTURE_2D,
1170:                        GLDefs.GL_TEXTURE_WRAP_S, GLDefs.GL_REPEAT);
1171:                gl.glTexParameteri(GLDefs.GL_TEXTURE_2D,
1172:                        GLDefs.GL_TEXTURE_WRAP_T, GLDefs.GL_REPEAT);
1173:
1174:                gl.glTexGeni(GLDefs.GL_S, GLDefs.GL_TEXTURE_GEN_MODE,
1175:                        GLDefs.GL_OBJECT_LINEAR);
1176:                gl.glTexGeni(GLDefs.GL_T, GLDefs.GL_TEXTURE_GEN_MODE,
1177:                        GLDefs.GL_OBJECT_LINEAR);
1178:
1179:                double sObjPlane[] = new double[4];
1180:                double tObjPlane[] = new double[4];
1181:
1182:                // If texture is power of two, take [0;1]x[0;1] square - this is the texture
1183:                // coordinates range. Then create mapping of anchor rect onto it.
1184:                // For NPOT texture take [0;size/p2size]x[0;size/p2size] square.
1185:                double widthFactor = (double) width / tp.width * tp.p2w;
1186:                double heightFactor = (double) height / tp.height * tp.p2h;
1187:
1188:                sObjPlane[0] = 1. / widthFactor;
1189:                sObjPlane[1] = 0;
1190:                sObjPlane[2] = 0;
1191:                sObjPlane[3] = -r.getX() / widthFactor;
1192:
1193:                tObjPlane[0] = 0;
1194:                tObjPlane[1] = 1. / heightFactor;
1195:                tObjPlane[2] = 0;
1196:                tObjPlane[3] = -r.getY() / heightFactor;
1197:
1198:                LockedArray la = Utils.arraccess.lockArrayShort(sObjPlane);
1199:                gl.glTexGendv(GLDefs.GL_S, GLDefs.GL_OBJECT_PLANE, la
1200:                        .getAddress());
1201:                la.release();
1202:                la = Utils.arraccess.lockArrayShort(tObjPlane);
1203:                gl.glTexGendv(GLDefs.GL_T, GLDefs.GL_OBJECT_PLANE, la
1204:                        .getAddress());
1205:                la.release();
1206:
1207:                gl.glEnable(GLDefs.GL_TEXTURE_GEN_S);
1208:                gl.glEnable(GLDefs.GL_TEXTURE_GEN_T);
1209:
1210:                gl.glEnable(GLDefs.GL_TEXTURE_2D);
1211:            }
1212:
1213:            /*
1214:            static final void reactivateTexturePaint() {
1215:                gl.glEnable(GLDefs.GL_TEXTURE_GEN_S);
1216:                gl.glEnable(GLDefs.GL_TEXTURE_GEN_T);
1217:                gl.glEnable(GLDefs.GL_TEXTURE_2D);
1218:            }
1219:             */
1220:            static final void deactivateTexturePaint() {
1221:                gl.glDisable(GLDefs.GL_TEXTURE_GEN_S);
1222:                gl.glDisable(GLDefs.GL_TEXTURE_GEN_T);
1223:                gl.glDisable(GLDefs.GL_TEXTURE_2D);
1224:            }
1225:
1226:            @Override
1227:            protected void fillMultiRectAreaPaint(MultiRectArea mra) {
1228:                if (oglPaint) {
1229:                    fillMultiRectAreaColor(mra);
1230:                } else {
1231:                    super .fillMultiRectAreaPaint(mra);
1232:                }
1233:            }
1234:
1235:            private final void activateGradientPaint(GradientPaint gp) {
1236:                byte twoPixels[] = new byte[8];
1237:                int val1 = gp.getColor1().getRGB();
1238:                int val2 = gp.getColor2().getRGB();
1239:                twoPixels[0] = (byte) ((val1 >> 16) & 0xFF);
1240:                twoPixels[1] = (byte) ((val1 >> 8) & 0xFF);
1241:                twoPixels[2] = (byte) (val1 & 0xFF);
1242:                twoPixels[3] = (byte) ((val1 >> 24) & 0xFF);
1243:                twoPixels[4] = (byte) ((val2 >> 16) & 0xFF);
1244:                twoPixels[5] = (byte) ((val2 >> 8) & 0xFF);
1245:                twoPixels[6] = (byte) (val2 & 0xFF);
1246:                twoPixels[7] = (byte) ((val2 >> 24) & 0xFF);
1247:
1248:                // Get gradient endpoints in the device space
1249:                Point2D p1 = gp.getPoint1();
1250:                Point2D p2 = gp.getPoint2();
1251:                double x1 = p1.getX();
1252:                double y1 = p1.getY();
1253:                double x2 = p2.getX();
1254:                double y2 = p2.getY();
1255:                /**
1256:                 * Let us denote by a1, a2 and a3 object plane coefficients for texture s coordinate:
1257:                 *      s = a1*x + a2*y + a3
1258:                 * Want to create following mapping for the texture s coordinate:
1259:                 *  x1,y1 -> 0,25
1260:                 *  x2,y2 -> 0,75
1261:                 *  x3,y3 -> 0,25
1262:                 * where (x3-x1,y3-y1) is perpendicular to (x2-x1,y2-y1).
1263:                 * 0,25 and 0,75 are centers of the first and second pixels, where
1264:                 * the color should have the full intensity.
1265:                 * From this have 3 equations for a1, a2 and a3.
1266:                 * They are solved, using cramer's rule in the code below.
1267:                 */
1268:                double x3 = x1 + y2 - y1;
1269:                double y3 = y1 + x1 - x2;
1270:                double d1 = (y3 - y1) * 0.5;
1271:                double d2 = (x1 - x3) * 0.5;
1272:                double d = -((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
1273:                double a1 = d1 / d;
1274:                double a2 = d2 / d;
1275:                double a3 = 0.25 - a1 * x1 - a2 * y1;
1276:
1277:                gradObjectPlane = new double[4];
1278:                gradObjectPlane[0] = a1;
1279:                gradObjectPlane[1] = a2;
1280:                gradObjectPlane[2] = 0;
1281:                gradObjectPlane[3] = a3;
1282:
1283:                // Create 1D texture object
1284:                Int32Pointer texPtr = NativeBridge.getInstance()
1285:                        .createInt32Pointer(1, true);
1286:                gl.glGenTextures(1, texPtr);
1287:                gradTexName = texPtr.get(0);
1288:                gl.glBindTexture(GLDefs.GL_TEXTURE_1D, gradTexName);
1289:                texPtr.free();
1290:                gl.glTexParameteri(GLDefs.GL_TEXTURE_1D,
1291:                        GLDefs.GL_TEXTURE_MAG_FILTER, GLDefs.GL_LINEAR);
1292:                gl.glTexParameteri(GLDefs.GL_TEXTURE_1D,
1293:                        GLDefs.GL_TEXTURE_MIN_FILTER, GLDefs.GL_LINEAR);
1294:                gl.glTexEnvf(GLDefs.GL_TEXTURE_ENV, GLDefs.GL_TEXTURE_ENV_MODE,
1295:                        GLDefs.GL_REPLACE);
1296:
1297:                // Setup texture coordinates generation
1298:                isGPCyclic = gp.isCyclic();
1299:                gl.glTexParameteri(GLDefs.GL_TEXTURE_1D,
1300:                        GLDefs.GL_TEXTURE_WRAP_S, isGPCyclic ? GLDefs.GL_REPEAT
1301:                                : GLDefs.GL_CLAMP_TO_EDGE);
1302:                gl.glTexGeni(GLDefs.GL_S, GLDefs.GL_TEXTURE_GEN_MODE,
1303:                        GLDefs.GL_OBJECT_LINEAR);
1304:                LockedArray la = Utils.arraccess
1305:                        .lockArrayShort(gradObjectPlane);
1306:                gl.glTexGendv(GLDefs.GL_S, GLDefs.GL_OBJECT_PLANE, la
1307:                        .getAddress());
1308:                la.release();
1309:                gl.glEnable(GLDefs.GL_TEXTURE_GEN_S);
1310:
1311:                // Load data into texture
1312:                la = Utils.arraccess.lockArrayShort(twoPixels);
1313:                gl.glTexImage1D(GLDefs.GL_TEXTURE_1D, 0, GLDefs.GL_RGBA, 2, 0,
1314:                        GLDefs.GL_RGBA, GLDefs.GL_UNSIGNED_BYTE, la
1315:                                .getAddress());
1316:                la.release();
1317:
1318:                // Enable 1D texture
1319:                gl.glEnable(GLDefs.GL_TEXTURE_1D);
1320:            }
1321:
1322:            private final void reactivateGradientPaint() {
1323:                gl.glBindTexture(GLDefs.GL_TEXTURE_1D, gradTexName);
1324:                LockedArray la = Utils.arraccess
1325:                        .lockArrayShort(gradObjectPlane);
1326:                gl.glTexGendv(GLDefs.GL_S, GLDefs.GL_OBJECT_PLANE, la
1327:                        .getAddress());
1328:                la.release();
1329:                gl.glTexParameteri(GLDefs.GL_TEXTURE_1D,
1330:                        GLDefs.GL_TEXTURE_WRAP_S, isGPCyclic ? GLDefs.GL_REPEAT
1331:                                : GLDefs.GL_CLAMP_TO_EDGE);
1332:                gl.glEnable(GLDefs.GL_TEXTURE_1D);
1333:            }
1334:
1335:            private final void deactivateGradientPaint() {
1336:                gl.glDisable(GLDefs.GL_TEXTURE_1D);
1337:                if (gradTexName != 0) {
1338:                    OGLBlitter.OGLTextureParams.deleteTexture(gradTexName);
1339:                    gradTexName = 0;
1340:                }
1341:            }
1342:
1343:            /**
1344:             * This method supposes that context is already current and validated.
1345:             * It only changes current read drawable to the drawable of other
1346:             * OGLGraphics2D object. It returnes false if contexts of this OGLGraphics2D
1347:             * and OGLGraphics2D passed in read parameter differs. To provide normal operation
1348:             * after using read drawable caller should restore state by calling makeCurrent().
1349:             * @param read - OGLGraphics2D which provides read drawable
1350:             * @return true on success
1351:             */
1352:            private final boolean setCurrentRead(OGLGraphics2D read) {
1353:                long oglContext = ctxmgr.getOGLContext(nwin.getId(), oshdc);
1354:                if (read.ctxmgr.getOGLContext(read.nwin.getId(), read.oshdc) != oglContext)
1355:                    return false;
1356:
1357:                ctxmgr.makeContextCurrent(oglContext, nwin.getId(), read.nwin
1358:                        .getId(), oshdc, read.oshdc);
1359:                return true;
1360:            }
1361:
1362:            boolean copyArea(int x, int y, int width, int height, int dx,
1363:                    int dy, OGLGraphics2D read, boolean texture) {
1364:                if (!setCurrentRead(read)) {
1365:                    return false;
1366:                }
1367:
1368:                gl.glPixelStoref(GLDefs.GL_UNPACK_SKIP_PIXELS, 0);
1369:                gl.glPixelStoref(GLDefs.GL_UNPACK_SKIP_ROWS, 0);
1370:
1371:                gl.glPixelZoom(1, 1);
1372:
1373:                // Raster position could be outside of the viewport, use glBitmap
1374:                gl.glRasterPos2i(0, 0);
1375:                gl.glBitmap(0, 0, 0, 0, dx, -dy - height, 0);
1376:
1377:                x += read.glTransform.getTranslateX() + 0.5;
1378:                y += read.glTransform.getTranslateY() + 0.5;
1379:
1380:                if (!texture) {
1381:                    gl.glCopyPixels(x, read.winBounds.height - y - height,
1382:                            width, height, GLDefs.GL_COLOR);
1383:                    gl.glFlush();
1384:
1385:                } else {
1386:                    gl.glCopyTexSubImage2D(GLDefs.GL_TEXTURE_2D, 0, 0, 0, x,
1387:                            read.winBounds.height - y - height, width, height);
1388:                }
1389:
1390:                getSurface().updateScene();
1391:
1392:                makeCurrent();
1393:                return true;
1394:            }
1395:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.