Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8118051

ES2: Texture.update() calculates source rect incorrectly

XMLWordPrintable

      I have a Prism image and want to flush part of that image to a texture. I use one of the Texture.update() methods, the one that allows to specify source rectangle. When srcx==srcy==0, I get the expected result. If however srcy>0, wrong part of the image is flushed.

      Below is the test, mostly boilerplate code, the essential method is renderImagePart(). It uses a 237x1256 image (http://static.groupon.ru/images/layout-s57f8f82d95.png , you may want to open it in a browser to see what happens). The part I'm interested in is the green-roofed house close to the bottom. What I get instead is some part of the image about one-third from the top.

      This bug occurs with ES2 pipeline both on Windows and Mac, D3D works fine.


      import com.sun.javafx.geom.BaseBounds;
      import com.sun.javafx.geom.transform.BaseTransform;
      import com.sun.javafx.iio.ImageFrame;
      import com.sun.javafx.iio.ImageStorage;
      import com.sun.javafx.iio.common.ImageTools;
      import com.sun.javafx.jmx.MXNodeAlgorithm;
      import com.sun.javafx.jmx.MXNodeAlgorithmContext;
      import com.sun.javafx.sg.PGNode;
      import com.sun.javafx.sg.prism.NGGroup;
      import com.sun.prism.Graphics;
      import com.sun.prism.GraphicsPipeline;
      import com.sun.prism.Image;
      import com.sun.prism.ImageFormatTool;
      import com.sun.prism.ResourceFactory;
      import com.sun.prism.Texture;
      import java.io.InputStream;
      import java.nio.Buffer;
      import javafx.application.Application;
      import javafx.scene.Group;
      import javafx.scene.Node;
      import javafx.scene.Scene;
      import javafx.stage.Stage;


      public class PrismImagePart extends Application {
          final int X = 0;
          final int Y = 776;
          final int WIDTH = 100;
          final int HEIGHT = 100;
              
          class CustomNode extends Node {
          
              @Override public Object impl_processMXNode(MXNodeAlgorithm alg, MXNodeAlgorithmContext ctx) {
                  return null;
              }

              @Override protected PGNode impl_createPGNode() {
                  return new NGCustomNode();
              }

              @Override public BaseBounds impl_computeGeomBounds(BaseBounds bounds, BaseTransform tx) {
                  bounds.deriveWithNewBounds(0, 0, 0, WIDTH, HEIGHT, 0);
                  tx.transform(bounds, bounds);
                  return bounds;
              }

              @Override protected boolean impl_computeContains(double localX, double localY) {
                  return true;
              }
          }
          
          class NGCustomNode extends NGGroup {

              @Override public boolean hasOverlappingContents() {
                  return false;
              }
              
              @Override protected void renderContent(Graphics g) {
                  renderImagePart(g);
              }

              void renderImagePart(Graphics g) {
                  try {
                      // create an instance of com.sun.prism.Image
                      InputStream in = ImageTools.createInputStream("http://static.groupon.ru/images/layout-s57f8f82d95.png");
                      ImageFrame[] frames = ImageStorage.loadAll(in, null, 0, 0, true, false);
                      Image img = ImageFormatTool.convertImageFrame(frames[0]);
                      
                      // dump part of the image into a texture
                      ResourceFactory f = GraphicsPipeline.getDefaultResourceFactory();
                      Texture txt = f.createTexture(img.getPixelFormat(),
                              Texture.Usage.DEFAULT, WIDTH, HEIGHT);
                      Buffer buffer = img.getPixelBuffer();
                      buffer.rewind();
                      txt.update(buffer, img.getPixelFormat(), 0, 0, X, Y, WIDTH, HEIGHT,
                              img.getScanlineStride(), false);

                      // render the texture
                      g.drawTexture(txt,
                              0, 0, WIDTH, HEIGHT,
                              0, 0, WIDTH, HEIGHT);
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              }
              
          }
          
          @Override public void start(Stage stage) {
              stage.setScene(new Scene(new Group(new CustomNode())));
              stage.sizeToScene();
              stage.show();
          }
          
          public static void main(String[] args) {
              launch();
          }
      }

            kprazdnikwse Kirill.Prazdnikov (Inactive)
            peterz Peter Zhelezniakov
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported: