Prechádzať zdrojové kódy

solve issue 1555 (add API to determine max line width) (#1643)

* add glGetFloat() to the GL interface

* add getMaxLineWidth() to the Renderer interface

* add a simple test for getMaxLineWidth()

* bugfix:  core profile overrides GL_ALIASED_LINE_WIDTH_RANGE

* GLRenderer:  delete 2 debug printlns

* TestLineWidth:  refactor the line-drawing code into a new method
Stephen Gold 3 rokov pred
rodič
commit
3ccc5183cd

+ 7 - 1
jme3-android/src/main/java/com/jme3/renderer/android/AndroidGL.java

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2020 jMonkeyEngine
+ * Copyright (c) 2009-2021 jMonkeyEngine
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -317,6 +317,12 @@ public class AndroidGL implements GL, GL2, GLES_30, GLExt, GLFbo {
         return GLES20.glGetError();
     }
 
+    @Override
+    public void glGetFloat(int parameterId, FloatBuffer storeValues) {
+        checkLimit(storeValues);
+        GLES20.glGetFloatv(parameterId, storeValues);
+    }
+
     @Override
     public void glGetInteger(int pname, IntBuffer params) {
         checkLimit(params);

+ 7 - 0
jme3-core/src/main/java/com/jme3/renderer/Renderer.java

@@ -486,6 +486,13 @@ public interface Renderer {
      */
     public int getDefaultAnisotropicFilter();
 
+    /**
+     * Determine the maximum allowed width for lines.
+     *
+     * @return the maximum width (in pixels)
+     */
+    public float getMaxLineWidth();
+
     /**
      * Test whether images with the sRGB flag will be linearized when read by a
      * shader.

+ 11 - 0
jme3-core/src/main/java/com/jme3/renderer/opengl/GL.java

@@ -45,6 +45,7 @@ import java.nio.ShortBuffer;
  */
 public interface GL {
 
+    public static final int GL_ALIASED_LINE_WIDTH_RANGE = 0x846E;
     public static final int GL_ALPHA = 0x1906;
     public static final int GL_ALWAYS = 0x207;
     public static final int GL_ARRAY_BUFFER = 0x8892;
@@ -97,6 +98,7 @@ public interface GL {
     public static final int GL_LINEAR_MIPMAP_NEAREST = 0x2701;
     public static final int GL_LINES = 0x1;
     public static final int GL_LINE_LOOP = 0x2;
+    public static final int GL_LINE_SMOOTH = 0xB20;
     public static final int GL_LINE_STRIP = 0x3;
     public static final int GL_LINK_STATUS = 0x8B82;
     public static final int GL_LUMINANCE = 0x1909;
@@ -829,6 +831,15 @@ public interface GL {
      */
     public int glGetError();
 
+    /**
+     * Determine the current single-precision floating-point value(s) of the
+     * specified parameter.
+     *
+     * @param parameterId which parameter
+     * @param storeValues storage for the value(s)
+     */
+    public void glGetFloat(int parameterId, FloatBuffer storeValues);
+
     /**
      * <p><a target="_blank" href="http://docs.gl/gl4/glGetIntegerv">Reference Page</a></p>
      *

+ 25 - 0
jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java

@@ -81,6 +81,7 @@ public final class GLRenderer implements Renderer {
     private static final Pattern GLVERSION_PATTERN = Pattern.compile(".*?(\\d+)\\.(\\d+).*");
 
     private final ByteBuffer nameBuf = BufferUtils.createByteBuffer(250);
+    private final FloatBuffer floatBuf16 = BufferUtils.createFloatBuffer(16);
     private final StringBuilder stringBuf = new StringBuilder(250);
     private final IntBuffer intBuf1 = BufferUtils.createIntBuffer(1);
     private final IntBuffer intBuf16 = BufferUtils.createIntBuffer(16);
@@ -3325,6 +3326,30 @@ public final class GLRenderer implements Renderer {
         return this.defaultAnisotropicFilter;
     }
 
+    /**
+     * Determine the maximum allowed width for lines.
+     *
+     * @return the maximum width (in pixels)
+     */
+    @Override
+    public float getMaxLineWidth() {
+        // Since neither JMonkeyEngine nor LWJGL ever enables GL_LINE_SMOOTH,
+        // all lines are aliased, but just in case...
+        assert !gl.glIsEnabled(GL.GL_LINE_SMOOTH);
+
+        // When running with OpenGL 3.2+ core profile,
+        // compatibility features such as multipixel lines aren't available.
+        if (caps.contains(Caps.CoreProfile)) {
+            return 1f;
+        }
+
+        floatBuf16.clear();
+        gl.glGetFloat(GL.GL_ALIASED_LINE_WIDTH_RANGE, floatBuf16);
+        float result = floatBuf16.get(1);
+
+        return result;
+    }
+
     /**
      * Test whether images with the sRGB flag will be linearized when read by a
      * shader.

+ 10 - 0
jme3-core/src/main/java/com/jme3/system/NullRenderer.java

@@ -252,6 +252,16 @@ public class NullRenderer implements Renderer {
     public void setDefaultAnisotropicFilter(int level) {
     }
 
+    /**
+     * Determine the maximum allowed width for lines.
+     *
+     * @return the maximum width (in pixels)
+     */
+    @Override
+    public float getMaxLineWidth() {
+        return Float.MAX_VALUE;
+    }
+
     @Override
     public boolean getAlphaToCoverage() {
         return false;

+ 103 - 0
jme3-examples/src/main/java/jme3test/renderer/TestLineWidth.java

@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2021 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package jme3test.renderer;
+
+import com.jme3.app.SimpleApplication;
+import com.jme3.font.BitmapFont;
+import com.jme3.font.BitmapText;
+import com.jme3.material.Material;
+import com.jme3.material.Materials;
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Mesh;
+import com.jme3.scene.shape.Line;
+import com.jme3.system.AppSettings;
+
+/**
+ * Display the renderer's maximum line width.
+ *
+ * @author Stephen Gold [email protected]
+ */
+public class TestLineWidth extends SimpleApplication {
+
+    public static void main(String... args) {
+        TestLineWidth app = new TestLineWidth();
+        AppSettings set = new AppSettings(true);
+        set.setRenderer(AppSettings.LWJGL_OPENGL2);
+        app.setSettings(set);
+        app.start();
+    }
+
+    @Override
+    public void simpleInitApp() {
+        /*
+         * Generate a message to report (1) which renderer is selected
+         * and (2) the maximum line width.
+         */
+        String rendererName = settings.getRenderer();
+        float maxWidth = renderer.getMaxLineWidth();
+        String message = String.format(
+                "using %s renderer%nmaximum line width = %.1f pixel%s",
+                rendererName, maxWidth, (maxWidth == 1f) ? "" : "s");
+        /*
+         * Display the message, centered near the top of the display.
+         */
+        BitmapFont font = assetManager.loadFont("Interface/Fonts/Default.fnt");
+        BitmapText text = new BitmapText(font, false);
+        text.setSize(font.getCharSet().getRenderedSize());
+        text.setText(message);
+        float leftX = (cam.getWidth() - text.getLineWidth()) / 2;
+        float topY = cam.getHeight();
+        text.setLocalTranslation(leftX, topY, 0f);
+        guiNode.attachChild(text);
+        /*
+         * Display a vertical green line on the left side of the display.
+         */
+        float lineWidth = Math.min(maxWidth, leftX);
+        drawVerticalLine(lineWidth, leftX / 2, ColorRGBA.Green);
+    }
+
+    private void drawVerticalLine(float lineWidth, float x, ColorRGBA color) {
+        Material material = new Material(assetManager, Materials.UNSHADED);
+        material.setColor("Color", color.clone());
+        material.getAdditionalRenderState().setLineWidth(lineWidth);
+
+        float viewportHeight = cam.getHeight();
+        Vector3f startLocation = new Vector3f(x, 0.1f * viewportHeight, 0f);
+        Vector3f endLocation = new Vector3f(x, 0.9f * viewportHeight, 0f);
+        Mesh wireMesh = new Line(startLocation, endLocation);
+        Geometry wire = new Geometry("wire", wireMesh);
+        wire.setMaterial(material);
+        guiNode.attachChild(wire);
+    }
+}

+ 18 - 1
jme3-ios/src/main/java/com/jme3/renderer/ios/IosGL.java

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2020 jMonkeyEngine
+ * Copyright (c) 2009-2021 jMonkeyEngine
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -52,6 +52,7 @@ import java.nio.ShortBuffer;
  */
 public class IosGL implements GL, GL2, GLES_30, GLExt, GLFbo {
     
+    private final float[] tmpFloatArray = new float[16];
     private final int[] temp_array = new int[16];
     private final IntBuffer tmpBuff = BufferUtils.createIntBuffer(1);
     
@@ -100,6 +101,15 @@ public class IosGL implements GL, GL2, GLES_30, GLExt, GLFbo {
         return remain;
     }
     
+    private void fromArray(int n, float[] array, FloatBuffer buffer) {
+        if (buffer.remaining() < n) { 
+            throw new BufferOverflowException();
+        }
+        int pos = buffer.position();
+        buffer.put(array, 0, n);
+        buffer.position(pos);
+    }
+    
     private void fromArray(int n, int[] array, IntBuffer buffer) {
         if (buffer.remaining() < n) { 
             throw new BufferOverflowException();
@@ -355,6 +365,13 @@ public class IosGL implements GL, GL2, GLES_30, GLExt, GLFbo {
         return JmeIosGLES.glGetError();
     }
 
+    @Override
+    public void glGetFloat(int parameterId, FloatBuffer storeValues) {
+        checkLimit(storeValues);
+        JmeIosGLES.glGetFloatv(parameterId, tmpFloatArray, 0);
+        fromArray(storeValues.remaining(), tmpFloatArray, storeValues);
+    }
+
     @Override
     public void glGetInteger(int pname, IntBuffer params) {
         checkLimit(params);

+ 1 - 0
jme3-ios/src/main/java/com/jme3/renderer/ios/JmeIosGLES.java

@@ -193,6 +193,7 @@ public class JmeIosGLES {
 	public static native int glGetAttribLocation(int program, String name);
 	public static native void glGetBoolean(int pname, ByteBuffer params);
 	public static native int glGetError();
+	public static native void glGetFloatv (int pname, float[] params, int offset);
 	public static native void glGetFramebufferAttachmentParameteriv(int target, int attachment, int pname, int[] params, int offset);
 	public static native void glGetIntegerv (int pname, int[] params, int offset);
 	public static native String glGetProgramInfoLog(int program);

+ 7 - 1
jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java

@@ -290,7 +290,13 @@ public final class LwjglGL implements GL, GL2, GL3, GL4 {
     public int glGetError() {
         return GL11.glGetError();
     }
-    
+
+    @Override
+    public void glGetFloat(int parameterId, FloatBuffer storeValues) {
+        checkLimit(storeValues);
+        GL11.glGetFloat(parameterId, storeValues);
+    }
+
     @Override
     public void glGetInteger(int param1, IntBuffer param2) {
         checkLimit(param2);

+ 7 - 1
jme3-lwjgl3/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2020 jMonkeyEngine
+ * Copyright (c) 2009-2021 jMonkeyEngine
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -319,6 +319,12 @@ public class LwjglGL extends LwjglRender implements GL, GL2, GL3, GL4 {
         return GL11.glGetError();
     }
 
+    @Override
+    public void glGetFloat(int parameterId, FloatBuffer storeValues) {
+        checkLimit(storeValues);
+        GL11.glGetFloatv(parameterId, storeValues);
+    }
+
     @Override
     public void glGetInteger(final int pname, final IntBuffer params) {
         checkLimit(params);