Renderer(int line) {
      startLine = line;

      if (!scene.antiAliasing) {
        sampled = false;

        samples = Math.max(scene.raysPerPixel, DEBUG_samples);
        // Force it to be a perfect square
        samples = (int) Math.sqrt(samples);
        samples = samples * samples;

        imageSamples = new Double3D[samples];
        for (int i = 0; i < samples; i++) imageSamples[i] = new Double3D(0, 0, 0);

        // Make samples are in the range [0,1]
        Sample.multiJitter(imageSamples, samples);
        // Make samples are in the range [-2,2]
        Sample.cubicSplineFilter(imageSamples, samples);
        // Scale image samples to [-.5,.5] and adjust to worldCoords this should be +-.5 pixels
        // since we're in the middle of a pixel to begin with
        for (int i = 0; i < samples; i++) {
          imageSamples[i].x = widthRatio / 2 * (imageSamples[i].x / 4.0);
          imageSamples[i].y = heightRatio / 2 * (imageSamples[i].y / 4.0);
          // System.out.println("Jitter by: " + imageSamples[i] + " Pixel width: " + widthRatio + "
          // Pixel height: " + heightRatio );
        }
        imageSamples[0].x++;
        imageSamples[0].x--;
      }
    }
예제 #2
0
 private void mouseToWorldCoord(
     int x,
     int y,
     int[] viewport,
     float[] proj,
     Load2Dfloat data,
     Tiledboard board,
     boolean heightctrl) {
   posx = (proj[1] - proj[0]) / viewport[2] * (x - viewport[0]) + proj[0];
   posy = (-proj[3] + proj[2]) / viewport[3] * (y - viewport[1]) + proj[3];
   System.out.println("light " + posx + " " + posy);
   // scene.setlightpos(0, (float)posx, (float)posy);
   double rad = Math.acos(posx / Math.sqrt(posx * posx + posy * posy));
   if (posy < 0) rad = 2 * Math.PI - rad;
   double r = Math.sqrt(32);
   scene.setlightpospolar(0, r, rad);
   scene.setlightdirectionrotate(rad);
   // 高さ自動調整
   // float heighttmp=0;
   // if(heightctrl)heighttmp = mouseToHeight(posx, posy, data, board);
   // scene.setLightCircleLookOutside(posx,posy,height+heighttmp,angle,1,1,scene.lightCount());
   posx = (double) x / viewport[2] * 2 * Math.PI;
   posx = 2 * Math.PI * 0.8;
   // scene.setLightCircleLookInside(posx, height);
 }
    Renderer() {
      xMin = scene.camera.viewportLeft + 0.5;
      xMax = scene.camera.viewportRight;
      yMin = scene.camera.viewportBottom + 0.5;
      yMax = scene.camera.viewportTop;

      if (scene.antiAliasing) {
        samples = Math.max(scene.raysPerPixel, DEBUG_samples);
        // Force it to be a perfect square
        samples = (int) Math.sqrt(samples);
        samples = samples * samples;

        imageSamples = new Double3D[samples];
        for (int i = 0; i < samples; i++) imageSamples[i] = new Double3D(0, 0, 0);

        Sample.multiJitter(imageSamples, samples);

        // Samples are in the range [-2,2]
        Sample.cubicSplineFilter(imageSamples, samples);

        // Scale image samples to [-1,1]
        for (int i = 0; i < samples; i++) {
          imageSamples[i].x = widthRatio * imageSamples[i].x / 2.0;
          imageSamples[i].y = heightRatio * imageSamples[i].y / 2.0;
        }
      }
    }
예제 #4
0
 public void fellipse(Coord c, Coord r, int a1, int a2) {
   st.set(cur2d);
   apply();
   gl.glBegin(GL.GL_TRIANGLE_FAN);
   vertex(c);
   for (int i = a1; i <= a2; i += 5) {
     double a = (i * Math.PI * 2) / 360.0;
     vertex(c.add((int) (Math.cos(a) * r.x), -(int) (Math.sin(a) * r.y)));
   }
   gl.glEnd();
   checkerr();
 }
예제 #5
0
  public void prect(Coord c, Coord ul, Coord br, double a) {
    st.set(cur2d);
    apply();
    gl.glEnable(GL2.GL_POLYGON_SMOOTH);
    gl.glBegin(GL.GL_TRIANGLE_FAN);
    vertex(c);
    vertex(c.add(0, ul.y));
    double p2 = Math.PI / 2;
    all:
    {
      float tc;

      tc = (float) (Math.tan(a) * -ul.y);
      if ((a > p2) || (tc > br.x)) {
        vertex(c.x + br.x, c.y + ul.y);
      } else {
        vertex(c.x + tc, c.y + ul.y);
        break all;
      }

      tc = (float) (Math.tan(a - (Math.PI / 2)) * br.x);
      if ((a > p2 * 2) || (tc > br.y)) {
        vertex(c.x + br.x, c.y + br.y);
      } else {
        vertex(c.x + br.x, c.y + tc);
        break all;
      }

      tc = (float) (-Math.tan(a - Math.PI) * br.y);
      if ((a > p2 * 3) || (tc < ul.x)) {
        vertex(c.x + ul.x, c.y + br.y);
      } else {
        vertex(c.x + tc, c.y + br.y);
        break all;
      }

      tc = (float) (-Math.tan(a - (3 * Math.PI / 2)) * -ul.x);
      if ((a > p2 * 4) || (tc < ul.y)) {
        vertex(c.x + ul.x, c.y + ul.y);
      } else {
        vertex(c.x + ul.x, c.y + tc);
        break all;
      }

      tc = (float) (Math.tan(a) * -ul.y);
      vertex(c.x + tc, c.y + ul.y);
    }
    gl.glEnd();
    gl.glDisable(GL2.GL_POLYGON_SMOOTH);
    checkerr();
  }
예제 #6
0
파일: GOut.java 프로젝트: krvd/hnh_union
 public void fellipse(Coord c, Coord r, int a1, int a2) {
   glcolor();
   texsel(-1);
   gl.glBegin(GL.GL_TRIANGLE_FAN);
   vertex(c);
   for (int i = a1; i < a2; i += 5) {
     double a = (i * Math.PI * 2) / 360.0;
     vertex(c.add((int) (Math.cos(a) * r.x), -(int) (Math.sin(a) * r.y)));
   }
   double a = (a2 * Math.PI * 2) / 360.0;
   vertex(c.add((int) (Math.cos(a) * r.x), -(int) (Math.sin(a) * r.y)));
   gl.glEnd();
   checkerr();
 }
예제 #7
0
 public void configureGL(GL2 gl) {
   gl.glEnable(GL2.GL_FOG);
   gl.glFogi(GL2.GL_FOG_MODE, GL2.GL_LINEAR);
   gl.glFogf(GL2.GL_FOG_DENSITY, 0.25f);
   gl.glFogf(GL2.GL_FOG_START, Math.max(getNearClippingPlane(), fadeOut * 1.0f));
   gl.glFogf(GL2.GL_FOG_END, Math.max(1.1f, fadeOut * 1.1f * getSpawnDistance()));
   gl.glMatrixMode(GL2.GL_PROJECTION);
   gl.glLoadIdentity();
   gl.glFrustumf(-1, 1, -man.vheight(), man.vheight(), getNearClippingPlane(), 128.0f);
   gl.glScalef(2.0f, 2.0f, 1);
   gl.glTranslatef(-0.5f, -man.vheight() / 2.0f, 0);
   gl.glMatrixMode(GL2.GL_MODELVIEW);
   gl.glLoadIdentity();
 }
    boolean transmissionDirection(Ray ray, HitRecord hit, Ray transmission) {
      double n = transmission.r.prevR.n;
      double nt = transmission.r.n;

      Double3D N = hit.normal;
      Double3D D = ray.dir;

      double cosine = -D.dot(N);
      if (n > nt) { // We're inside, so reverse the normal
        N = N.sMult(-1);
        cosine = -D.dot(N);
      }

      double nRatio = n / nt;

      double cosinePSq = 1.0 - nRatio * nRatio * (1.0f - cosine * cosine);

      // check for total internal refraction here
      if (cosinePSq < 0.0f) return false; // total internal refraction
      else {
        // D - N(N.D)
        // Double3D pOne = D.minus( N.sMult(N.dot(D)) ).sMult(nRatio);
        double inside = nRatio * cosine - Math.sqrt(cosinePSq);
        Double3D temp = D.sMult(nRatio).plus(N.sMult(inside)).getUnit();
        transmission.dir.x = temp.x;
        transmission.dir.y = temp.y;
        transmission.dir.z = temp.z;
      }
      return true;
    }
예제 #9
0
  private static void rebound() {
    float f = 0.0f;
    float n = 0.0f;
    float b = 0.0f;
    float t = 0.0f;
    float l = 0.0f;
    float r = 0.0f;

    for (Polygon poly : polygons) {
      poly.recalc();

      if (poly.getMinZ() < f) {
        f = poly.getMinZ();
      }
      if (poly.getMaxZ() > n) {
        n = poly.getMaxZ();
      }
      if (poly.getMinY() < b) {
        b = poly.getMinY();
      }
      if (poly.getMaxY() > t) {
        t = poly.getMaxY();
      }
      if (poly.getMinX() < l) {
        l = poly.getMinX();
      }
      if (poly.getMaxX() > r) {
        r = poly.getMaxX();
      }
    }

    float maxSpan = Math.max(Math.max(f - n, t - b), r - l);

    for (Polygon poly : polygons) {
      for (Point3Df p : poly.getPoints()) {
        p.x = p.x * (2 / maxSpan) - (r + l) / (r - l);
        p.y = p.y * (2 / maxSpan) - (t + b) / (t - b);
        p.z = p.z * (2 / maxSpan) - (n + f) / (n - f);
      }

      poly.recalc();
    }
  }
예제 #10
0
  public void interactionForce(Particle other) {
    // ok, now for the fun stuff...
    Vector3d posDif = new Vector3d();
    posDif.sub(x, other.x);

    Vector3d velDif = new Vector3d();
    velDif.sub(v, other.v);

    double d = posDif.length();
    double dSquared = d * d;

    int m = 6;
    int n = 5;
    double r0 = 2 * PARTICLE_RADIUS;
    double cr = r0;
    double cd = r0;
    double b1 = 1;
    double b2 = b1; // *Math.pow(r0, n-m);
    double sumR = 2 * PARTICLE_RADIUS;
    double sr = 250;
    double sd = 70;

    /*sr = dSquared/(cr*cr*(sumR)*(sumR));
    sd = dSquared/(cd*cd*(sumR)*(sumR));

    sr = Math.max(0, 1 - sr);
    sd = Math.max(0, 1 - sd);*/

    Vector3d f = new Vector3d();
    f.set(posDif);
    f.normalize();

    double sf =
        -sr * (b1 / Math.pow(d / r0, m) - b2 / Math.pow(d / r0, n))
            + sd * (velDif.dot(f) / (d / r0));
    f.scale(sf);
    other.f.add(f);
  }
예제 #11
0
  private void ReduceDualA(double dNumSamples) {
    Texture kTarget = null;
    m_pkRenderer.Resize(
        m_kEntropyOut.GetTarget(0).GetImage().GetBound(0),
        m_kEntropyOut.GetTarget(0).GetImage().GetBound(1));
    m_kEntropyOut.Enable();
    m_pkRenderer.ClearColorDepth();
    // m_pkRenderer.ClearBuffers();
    m_pkRenderer.Draw(m_kEntropyPoints2D);
    m_kEntropyOut.Disable();
    kTarget = m_kEntropyOut.GetTarget(0);

    double dEntropyDual = 0;
    double dOverlap = 0;
    double dEntropyX = 0, dEntropyY = 0;
    if (kTarget != null) {
      int iIndex = 0;
      int iStep = (int) Math.max(1.0, (int) (kTarget.GetImage().GetBytesPerPixel() / 4.0f));
      m_pkRenderer.GetTexImage(kTarget);

      // System.err.println( "Entropy = " + kTarget.GetImage().GetFloatData()[0] + " "
      //        + kTarget.GetImage().GetFloatData()[1] + " "
      //        + kTarget.GetImage().GetFloatData()[2] + " "
      //        + kTarget.GetImage().GetFloatData()[3] );

      for (int i = 0; i < kTarget.GetImage().GetBound(1); i++) {
        for (int j = 0; j < kTarget.GetImage().GetBound(0); j++) {
          dEntropyDual += kTarget.GetImage().GetFloatData()[iIndex];
          dEntropyY += kTarget.GetImage().GetFloatData()[iIndex + 1];
          dEntropyX += kTarget.GetImage().GetFloatData()[iIndex + 2];
          dOverlap += kTarget.GetImage().GetFloatData()[iIndex + 3];
          iIndex += iStep;
        }
      }
    }
    dEntropyX = dEntropyX / dNumSamples;
    dEntropyY = dEntropyY / dNumSamples;

    m_dOverlap = dOverlap;
    m_dHx = dEntropyX;
    m_dHy = dEntropyY;
    m_dHxy = dEntropyDual / dNumSamples;
    // System.err.println( "GPU: " + m_iWidth + " " + dNumSamples + " " + m_dOverlap + " " + m_dHx +
    // " " + m_dHy + " " + m_dHxy );
  }
예제 #12
0
파일: GOut.java 프로젝트: krvd/hnh_union
 public void ftriangle(Coord center, int size) {
   if (size < 1) return;
   double sqrt3 = Math.sqrt(3);
   double Orad = (sqrt3 * size) / 3;
   double Irad = (sqrt3 * size) / 6;
   Coord c1, c2, c3;
   c1 = new Coord(center.x, center.y - (int) Orad);
   c2 = new Coord(center.x + (int) (size / 2) - 1, center.y + (int) Irad);
   c3 = new Coord(center.x - (int) (size / 2) + 1, center.y + (int) Irad);
   glcolor();
   texsel(-1);
   gl.glBegin(GL.GL_TRIANGLE_STRIP);
   vertex(c1);
   vertex(c2);
   vertex(c3);
   gl.glEnd();
   checkerr();
 }
예제 #13
0
  private void calcEntropy() {
    calcEntropy(m_kImageA, m_kImageA.dataSize);

    int nVoxels = m_kImageA.dataSize;
    if (((m_kImageA.nDims < 3) && (m_dOverlap > 1000))
        || ((m_kImageA.nDims == 3) && (m_dOverlap > (0.15 * nVoxels)))) {
      double nRatio = (nVoxels) / m_dOverlap;

      m_dHx = (nRatio * m_dHx) - Math.log(nRatio);
      m_dHy = (nRatio * m_dHy) - Math.log(nRatio);
      m_dHxy = (nRatio * m_dHxy) - Math.log(nRatio);
    } else {
      m_dHx = Math.log(nVoxels);
      m_dHy = Math.log(nVoxels);
      m_dHxy = 2.0 * Math.log(nVoxels);
    }
  }
예제 #14
0
  private void renderOneside(Point2D a, Point2D b, GL gl, double d) {
    gl.glClear(0);
    Vector3D t = new Vector3D(b.x - a.x, 0, b.y - a.y);
    Vector3D n = new Vector3D(0, 1, 0);
    Vector3D cross = n.cross(t);
    gl.glNormal3d(cross.x, cross.y, cross.z);

    // Texture adjustment vars
    double length =
        scale * Math.sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)) / 100 + 0.1;
    double height = scale;

    // draw the 4 points of it
    gl.glBegin(GL.GL_POLYGON);
    gl.glTexCoord2d(0, 0);
    gl.glVertex3d(a.x, d, a.y);
    gl.glTexCoord2d(0, height);
    gl.glVertex3d(a.x, d + 100, a.y);
    gl.glTexCoord2d(length, height);
    gl.glVertex3d(b.x, d + 100, b.y);
    gl.glTexCoord2d(length, 0);
    gl.glVertex3d(b.x, d, b.y);
    gl.glEnd();
  }
예제 #15
0
 /** Returns the distance at which objects should spawn. */
 public float getSpawnDistance() {
   return Math.min(8 * player.getSpeed(), Tunnel.GRID_LENGTH * Tunnel.GSQ_LEN / 2);
 }
예제 #16
0
  private void calcLineMin() {
    m_kImagePointsDual.DetachAllEffects();
    m_kImagePointsDual.AttachEffect(m_kImageLineMinDual);
    boolean bEarly = false;
    Texture kTarget = null;
    OpenGLFrameBuffer kCurrentBracket = m_kBracketOut;
    OpenGLFrameBuffer kNewBracket = m_kBracketNewOut;
    OpenGLFrameBuffer kTempBracket;
    for (int i = 0; i < 100; i++) {
      m_kCalcTransform.SetTexture(kCurrentBracket.GetTarget(0), 0, 0);
      m_kImageLineMinPass2a.SetTexture(kCurrentBracket.GetTarget(0), 0, 0);

      // 1. Create the transform matrix based on the current bracket.
      m_pkRenderer.Resize(
          m_kTransformOut.GetTarget(0).GetImage().GetBound(0),
          m_kTransformOut.GetTarget(0).GetImage().GetBound(1));
      m_kTransformOut.Enable();
      m_pkRenderer.ClearColorDepth();
      // m_pkRenderer.ClearBuffers();
      m_pkRenderer.Draw(m_kTransformPoints);
      m_kTransformOut.Disable();
      /*
      kTarget = m_kTransformOut.GetTarget(0);
      m_pkRenderer.GetTexImage( kTarget );
      for ( int j = 0; j < kTarget.GetImage().GetFloatData().length; j++ )
      {
          System.err.print( kTarget.GetImage().GetFloatData()[j] + " " );
      }
      System.err.println( " " ); */

      // 1. Render all image points w/LineMin1 shaders
      m_pkRenderer.Resize(
          m_kHistogramOutput.GetTarget(0).GetImage().GetBound(0),
          m_kHistogramOutput.GetTarget(0).GetImage().GetBound(1));
      m_kHistogramOutput.Enable();
      m_pkRenderer.ClearColorDepth();
      // m_pkRenderer.ClearBuffers();
      m_pkRenderer.Draw(m_kImagePointsDual);
      m_kHistogramOutput.Disable();

      // 2. Render Histogram points
      m_pkRenderer.Resize(
          m_kHistogramOutputB.GetTarget(0).GetImage().GetBound(0),
          m_kHistogramOutputB.GetTarget(0).GetImage().GetBound(1));
      m_kHistogramOutputB.Enable();
      m_pkRenderer.ClearColorDepth();
      // m_pkRenderer.ClearBuffers();
      m_pkRenderer.Draw(m_kHistogramPoints2D);
      m_kHistogramOutputB.Disable();

      // 3. Render Entropy points w/LineMin1 shader
      m_pkRenderer.Resize(
          m_kEntropyOut.GetTarget(0).GetImage().GetBound(0),
          m_kEntropyOut.GetTarget(0).GetImage().GetBound(1));
      m_kEntropyOut.Enable();
      m_pkRenderer.ClearColorDepth();
      // m_pkRenderer.ClearBuffers();
      m_pkRenderer.Draw(m_kEntropyPoints2D);
      m_kEntropyOut.Disable();

      // 4. Render bracket points w/LineMin2 shader
      m_kBracketPoints.DetachAllEffects();
      m_kBracketPoints.AttachEffect(m_kImageLineMinPass2a);
      m_pkRenderer.Resize(
          kNewBracket.GetTarget(0).GetImage().GetBound(0),
          kNewBracket.GetTarget(0).GetImage().GetBound(1));
      kNewBracket.Enable();
      m_pkRenderer.ClearColorDepth();
      // m_pkRenderer.ClearBuffers();
      m_pkRenderer.Draw(m_kBracketPoints);
      kNewBracket.Disable();
      kTempBracket = kCurrentBracket;
      kCurrentBracket = kNewBracket;
      kNewBracket = kTempBracket;

      if ((i % 6) == 0) {
        // kTarget = m_kBracketOut.GetTarget(0);
        kTarget = kCurrentBracket.GetTarget(0);
        m_pkRenderer.GetTexImage(kTarget);
        /*
        System.err.println("");
        System.err.println("");
        System.err.println( "GPU BracketA = " + kTarget.GetImage().GetFloatData()[0] + " " + kTarget.GetImage().GetFloatData()[1]);
        System.err.println( "GPU BracketB = " + kTarget.GetImage().GetFloatData()[4] + " " + kTarget.GetImage().GetFloatData()[5]);
        System.err.println( "GPU BracketC = " + kTarget.GetImage().GetFloatData()[8] + " " + kTarget.GetImage().GetFloatData()[9]);
        System.err.println( "   " + i + " xNew = " + kTarget.GetImage().GetFloatData()[3] + " yNew = " +
                kTarget.GetImage().GetFloatData()[6]  + " case: " + kTarget.GetImage().GetFloatData()[7] + " " +
                kTarget.GetImage().GetFloatData()[10] + " " +
                kTarget.GetImage().GetFloatData()[11]);
                */
        if ((Math.abs(kTarget.GetImage().GetFloatData()[8] - kTarget.GetImage().GetFloatData()[0])
            <= m_fUnitTolerance)) {
          m_afBracketB[0] = kTarget.GetImage().GetFloatData()[4];
          m_afBracketB[1] = kTarget.GetImage().GetFloatData()[5];
          bEarly = true;
          break;
        }
        if (kTarget.GetImage().GetFloatData()[3] == 0) {
          m_afBracketB[0] = kTarget.GetImage().GetFloatData()[4];
          m_afBracketB[1] = kTarget.GetImage().GetFloatData()[5];
          bEarly = true;
          System.err.println("BREAK EARLY BAD");
          break;
        }
      }
    }
    if (!bEarly) {
      // kTarget = m_kBracketOut.GetTarget(0);
      kTarget = kCurrentBracket.GetTarget(0);
      m_pkRenderer.GetTexImage(kTarget);
      m_afBracketB[0] = kTarget.GetImage().GetFloatData()[4];
      m_afBracketB[1] = kTarget.GetImage().GetFloatData()[5];
      /*
          System.err.println("");
          System.err.println("");
          System.err.println( "GPU BracketA = " + kTarget.GetImage().GetFloatData()[0] + " " + kTarget.GetImage().GetFloatData()[1]);
          System.err.println( "GPU BracketB = " + kTarget.GetImage().GetFloatData()[4] + " " + kTarget.GetImage().GetFloatData()[5]);
          System.err.println( "GPU BracketC = " + kTarget.GetImage().GetFloatData()[8] + " " + kTarget.GetImage().GetFloatData()[9]);
      */
    }
    // System.err.println( m_afBracketB[0] + " " + m_afBracketB[1] );
  }
예제 #17
0
    // iPoint is the point of intersection with the surface.
    DoubleColor shade(Ray ray, HitRecord hit, MaterialCell material, boolean background) {
      DoubleColor color = new DoubleColor(0.0, 0.0, 0.0, 1.0);

      // Add ambient light only once
      color.plus(
          new DoubleColor(
              (double) (lights[0].ambient[0] * material.ka.r),
              (double) (lights[0].ambient[1] * material.ka.g),
              (double) (lights[0].ambient[2] * material.ka.b),
              (double) (lights[0].ambient[3] * material.ka.a)));

      // Assign material color?
      // Local light or directional? If directional then we need to see if it's shining on the
      // object
      if (!background) {
        double d = 2; // L.distanceTo(hit.hitP);

        for (int i = 0; i < lights.length; i++) {
          if (lights[i].lightSwitch == 1) {
            Double3D L =
                new Double3D(
                    (double) lights[i].position[0],
                    (double) lights[i].position[1],
                    (double) lights[i].position[2]);
            L = L.minus(hit.hitP).getUnit();
            Ray shadowRay = new Ray(hit.hitP, L);
            // trace shadow ray to light source

            // Turn shadows on and shadowRay hit nothing
            if (!scene.shadows || shadowTrace(shadowRay)) {
              double LdN = Math.max(0, hit.normal.dot(L));
              if (LdN > 0) {
                // -2(-L.N)N + -L
                Double3D R = hit.normal.sMult(-2 * hit.normal.dot(L.sMult(-1))).plus(L.sMult(-1));
                double RdV = Math.max(0, -R.dot(ray.dir));

                // If the light is free add the diffuse light
                // Intensity (Kd * (LdN) + Ks *(RdV)^(shiny)/(r + k)
                color.plus(
                    new DoubleColor(
                        (double)
                                (lights[i].diffuse[0] * LdN
                                    + lights[i].specular[0] * Math.pow(RdV, material.shiny))
                            / d,
                        (double)
                                (lights[i].diffuse[1] * LdN
                                    + lights[i].specular[1] * Math.pow(RdV, material.shiny))
                            / d,
                        (double)
                                (lights[i].diffuse[2] * LdN
                                    + lights[i].specular[2] * Math.pow(RdV, material.shiny))
                            / d,
                        1.0)); // */
              } // if(LdN > 0)
            } // if(!scene.shadows || shadowTrace(shadowRay))
          } // if(lights[i].lightSwitch == 1){
        } // for

        // Shiny Phong
        // If IdN > 0 then we find a reflection
        // If IdN < 0 then we need -normal
        if (scene.reflections
            && (material.reflectivity.r > 0
                || material.reflectivity.g > 0
                || material.reflectivity.b > 0)) {
          depth++;

          // R = I - 2 * (I.N)N
          Double3D R = new Double3D();
          Double3D I = ray.dir; // .sMult(-1.0);
          Double3D N = hit.normal;
          // double IdN = I.dot(N);

          // if (IdN > 0){
          //	N = N.sMult(-1.0);
          //	IdN = -I.dot(N);
          // }//*/

          R = I.plus(N.sMult(-2.0 * I.dot(N)));

          Ray reflect = new Ray(hit.hitP, R);
          DoubleColor reflection = trace(reflect);

          // Scale by distance?
          // reflection.scale( 1 / reflect.origin().distanceTo(hit.hitP));

          reflection.r = reflection.r * material.reflectivity.r;
          reflection.g = reflection.g * material.reflectivity.g;
          reflection.b = reflection.b * material.reflectivity.b;

          color.plus(reflection);

          depth--;
        }

        if (scene.refractions
            && (material.refractivity.r > 0
                || material.refractivity.g > 0
                || material.refractivity.b > 0)) // */
        {
          depth++;

          Ray refract = new Ray(hit.hitP, ray.dir);

          if (hit.index == ray.r.objectNum) // Hit the object we're already in
          {
            // Pop the n off the stack
            refract.r = ray.r;

            // Swap the refraction indices
            double temp = refract.r.n;
            refract.r.n = refract.r.prevR.n;
            refract.r.prevR.n = temp;
          } else // Otherwise we hit a new object push this n onto the stack and get mat index
          {
            refract.r.prevR = ray.r;
            refract.r.n = material.refractiveIndex;
            refract.r.objectNum = hit.index;
          }

          if (transmissionDirection(ray, hit, refract)) {
            DoubleColor refraction = trace(refract);

            refraction.r = refraction.r * material.refractivity.r;
            refraction.g = refraction.g * material.refractivity.g;
            refraction.b = refraction.b * material.refractivity.b;

            // Scale for distance?
            color.plus(refraction);
          }

          depth--;
        }
      }
      return color;
    }
예제 #18
0
 // utility for contains takes an offset so we can check the two parts of the portal
 public boolean contains(int offset, int x, int y) {
   Edge2D e = new Edge2D(pts2d.get(offset), pts2d.get(offset + 1));
   Point2D pe = e.toLineSpace(new Point(x, y));
   return (pe.getX() > 0 && pe.getX() < 1 && Math.abs(pe.getY()) < EPSILON);
 }
예제 #19
0
 private double getdatafrombuffer(FloatBuffer fb, int index) {
   return Math.sqrt(Math.pow(fb.get(4 * index + 2), 2) + Math.pow(fb.get(4 * index + 3), 2))
       * 0.05;
 }
  private void updateSubImageImpl(
      TextureData data,
      int newTarget,
      int mipmapLevel,
      int dstx,
      int dsty,
      int srcx,
      int srcy,
      int width,
      int height)
      throws GLException {
    GL gl = GLU.getCurrentGL();
    data.setHaveEXTABGR(gl.isExtensionAvailable("GL_EXT_abgr"));
    data.setHaveGL12(gl.isExtensionAvailable("GL_VERSION_1_2"));

    Buffer buffer = data.getBuffer();
    if (buffer == null && data.getMipmapData() == null) {
      // Assume user just wanted to get the Texture object allocated
      return;
    }

    int rowlen = data.getRowLength();
    int dataWidth = data.getWidth();
    int dataHeight = data.getHeight();
    if (data.getMipmapData() != null) {
      // Compute the width, height and row length at the specified mipmap level
      // Note we do not support specification of the row length for
      // mipmapped textures at this point
      for (int i = 0; i < mipmapLevel; i++) {
        width = Math.max(width / 2, 1);
        height = Math.max(height / 2, 1);

        dataWidth = Math.max(dataWidth / 2, 1);
        dataHeight = Math.max(dataHeight / 2, 1);
      }
      rowlen = 0;
      buffer = data.getMipmapData()[mipmapLevel];
    }

    // Clip incoming rectangles to what is available both on this
    // texture and in the incoming TextureData
    if (srcx < 0) {
      width += srcx;
      srcx = 0;
    }
    if (srcy < 0) {
      height += srcy;
      srcy = 0;
    }
    // NOTE: not sure whether the following two are the correct thing to do
    if (dstx < 0) {
      width += dstx;
      dstx = 0;
    }
    if (dsty < 0) {
      height += dsty;
      dsty = 0;
    }

    if (srcx + width > dataWidth) {
      width = dataWidth - srcx;
    }
    if (srcy + height > dataHeight) {
      height = dataHeight - srcy;
    }
    if (dstx + width > texWidth) {
      width = texWidth - dstx;
    }
    if (dsty + height > texHeight) {
      height = texHeight - dsty;
    }

    checkCompressedTextureExtensions(data);

    if (data.isDataCompressed()) {
      gl.glCompressedTexSubImage2D(
          newTarget,
          mipmapLevel,
          dstx,
          dsty,
          width,
          height,
          data.getInternalFormat(),
          buffer.remaining(),
          buffer);
    } else {
      int[] align = new int[1];
      int[] rowLength = new int[1];
      int[] skipRows = new int[1];
      int[] skipPixels = new int[1];
      gl.glGetIntegerv(GL.GL_UNPACK_ALIGNMENT, align, 0); // save alignment
      gl.glGetIntegerv(GL.GL_UNPACK_ROW_LENGTH, rowLength, 0); // save row length
      gl.glGetIntegerv(GL.GL_UNPACK_SKIP_ROWS, skipRows, 0); // save skipped rows
      gl.glGetIntegerv(GL.GL_UNPACK_SKIP_PIXELS, skipPixels, 0); // save skipped pixels
      gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, data.getAlignment());
      if (DEBUG && VERBOSE) {
        System.out.println("Row length  = " + rowlen);
        System.out.println("skip pixels = " + srcx);
        System.out.println("skip rows   = " + srcy);
        System.out.println("dstx        = " + dstx);
        System.out.println("dsty        = " + dsty);
        System.out.println("width       = " + width);
        System.out.println("height      = " + height);
      }
      gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, rowlen);
      gl.glPixelStorei(GL.GL_UNPACK_SKIP_ROWS, srcy);
      gl.glPixelStorei(GL.GL_UNPACK_SKIP_PIXELS, srcx);

      gl.glTexSubImage2D(
          newTarget,
          mipmapLevel,
          dstx,
          dsty,
          width,
          height,
          data.getPixelFormat(),
          data.getPixelType(),
          buffer);
      gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, align[0]); // restore alignment
      gl.glPixelStorei(GL.GL_UNPACK_ROW_LENGTH, rowLength[0]); // restore row length
      gl.glPixelStorei(GL.GL_UNPACK_SKIP_ROWS, skipRows[0]); // restore skipped rows
      gl.glPixelStorei(GL.GL_UNPACK_SKIP_PIXELS, skipPixels[0]); // restore skipped pixels
    }
  }
  /**
   * Updates the content area of the specified target of this texture using the data in the given
   * image. In general this is intended for construction of cube maps.
   *
   * @throws GLException if no OpenGL context was current or if any OpenGL-related errors occurred
   */
  public void updateImage(TextureData data, int target) throws GLException {
    GL gl = GLU.getCurrentGL();

    imgWidth = data.getWidth();
    imgHeight = data.getHeight();
    aspectRatio = (float) imgWidth / (float) imgHeight;
    mustFlipVertically = data.getMustFlipVertically();

    int texTarget = 0;
    int texParamTarget = this.target;

    // See whether we have automatic mipmap generation support
    boolean haveAutoMipmapGeneration =
        (gl.isExtensionAvailable("GL_VERSION_1_4")
            || gl.isExtensionAvailable("GL_SGIS_generate_mipmap"));

    // Indicate to the TextureData what functionality is available
    data.setHaveEXTABGR(gl.isExtensionAvailable("GL_EXT_abgr"));
    data.setHaveGL12(gl.isExtensionAvailable("GL_VERSION_1_2"));

    // Note that automatic mipmap generation doesn't work for
    // GL_ARB_texture_rectangle
    if ((!isPowerOfTwo(imgWidth) || !isPowerOfTwo(imgHeight)) && !haveNPOT(gl)) {
      haveAutoMipmapGeneration = false;
    }

    boolean expandingCompressedTexture = false;
    if (data.getMipmap() && !haveAutoMipmapGeneration) {
      // GLU always scales the texture's dimensions to be powers of
      // two. It also doesn't really matter exactly what the texture
      // width and height are because the texture coords are always
      // between 0.0 and 1.0.
      imgWidth = nextPowerOfTwo(imgWidth);
      imgHeight = nextPowerOfTwo(imgHeight);
      texWidth = imgWidth;
      texHeight = imgHeight;
      texTarget = GL.GL_TEXTURE_2D;
    } else if ((isPowerOfTwo(imgWidth) && isPowerOfTwo(imgHeight)) || haveNPOT(gl)) {
      if (DEBUG) {
        if (isPowerOfTwo(imgWidth) && isPowerOfTwo(imgHeight)) {
          System.err.println("Power-of-two texture");
        } else {
          System.err.println("Using GL_ARB_texture_non_power_of_two");
        }
      }

      texWidth = imgWidth;
      texHeight = imgHeight;
      texTarget = GL.GL_TEXTURE_2D;
    } else if (haveTexRect(gl) && !data.isDataCompressed()) {
      // GL_ARB_texture_rectangle does not work for compressed textures
      if (DEBUG) {
        System.err.println("Using GL_ARB_texture_rectangle");
      }

      texWidth = imgWidth;
      texHeight = imgHeight;
      texTarget = GL.GL_TEXTURE_RECTANGLE_ARB;
    } else {
      // If we receive non-power-of-two compressed texture data and
      // don't have true hardware support for compressed textures, we
      // can fake this support by producing an empty "compressed"
      // texture image, using glCompressedTexImage2D with that to
      // allocate the texture, and glCompressedTexSubImage2D with the
      // incoming data.
      if (data.isDataCompressed()) {
        if (data.getMipmapData() != null) {

          // We don't currently support expanding of compressed,
          // mipmapped non-power-of-two textures to the nearest power
          // of two; the obvious port of the non-mipmapped code didn't
          // work
          throw new GLException(
              "Mipmapped non-power-of-two compressed textures only supported on OpenGL 2.0 hardware (GL_ARB_texture_non_power_of_two)");
        }

        expandingCompressedTexture = true;
      }

      if (DEBUG) {
        System.err.println("Expanding texture to power-of-two dimensions");
      }

      if (data.getBorder() != 0) {
        throw new RuntimeException(
            "Scaling up a non-power-of-two texture which has a border won't work");
      }
      texWidth = nextPowerOfTwo(imgWidth);
      texHeight = nextPowerOfTwo(imgHeight);
      texTarget = GL.GL_TEXTURE_2D;
    }

    texParamTarget = texTarget;
    setImageSize(imgWidth, imgHeight, texTarget);

    if (target != 0) {
      // Allow user to override auto detection and skip bind step (for
      // cubemap construction)
      texTarget = target;
      if (this.target == 0) {
        throw new GLException("Override of target failed; no target specified yet");
      }
      texParamTarget = this.target;
      gl.glBindTexture(texParamTarget, texID);
    } else {
      gl.glBindTexture(texTarget, texID);
    }

    if (data.getMipmap() && !haveAutoMipmapGeneration) {
      int[] align = new int[1];
      gl.glGetIntegerv(GL.GL_UNPACK_ALIGNMENT, align, 0); // save alignment
      gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, data.getAlignment());

      if (data.isDataCompressed()) {
        throw new GLException("May not request mipmap generation for compressed textures");
      }

      try {
        GLU glu = new GLU();
        glu.gluBuild2DMipmaps(
            texTarget,
            data.getInternalFormat(),
            data.getWidth(),
            data.getHeight(),
            data.getPixelFormat(),
            data.getPixelType(),
            data.getBuffer());
      } finally {
        gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, align[0]); // restore alignment
      }
    } else {
      checkCompressedTextureExtensions(data);
      Buffer[] mipmapData = data.getMipmapData();
      if (mipmapData != null) {
        int width = texWidth;
        int height = texHeight;
        for (int i = 0; i < mipmapData.length; i++) {
          if (data.isDataCompressed()) {
            // Need to use glCompressedTexImage2D directly to allocate and fill this image
            // Avoid spurious memory allocation when possible
            gl.glCompressedTexImage2D(
                texTarget,
                i,
                data.getInternalFormat(),
                width,
                height,
                data.getBorder(),
                mipmapData[i].remaining(),
                mipmapData[i]);
          } else {
            // Allocate texture image at this level
            gl.glTexImage2D(
                texTarget,
                i,
                data.getInternalFormat(),
                width,
                height,
                data.getBorder(),
                data.getPixelFormat(),
                data.getPixelType(),
                null);
            updateSubImageImpl(data, texTarget, i, 0, 0, 0, 0, data.getWidth(), data.getHeight());
          }

          width = Math.max(width / 2, 1);
          height = Math.max(height / 2, 1);
        }
      } else {
        if (data.isDataCompressed()) {
          if (!expandingCompressedTexture) {
            // Need to use glCompressedTexImage2D directly to allocate and fill this image
            // Avoid spurious memory allocation when possible
            gl.glCompressedTexImage2D(
                texTarget,
                0,
                data.getInternalFormat(),
                texWidth,
                texHeight,
                data.getBorder(),
                data.getBuffer().capacity(),
                data.getBuffer());
          } else {
            ByteBuffer buf =
                DDSImage.allocateBlankBuffer(texWidth, texHeight, data.getInternalFormat());
            gl.glCompressedTexImage2D(
                texTarget,
                0,
                data.getInternalFormat(),
                texWidth,
                texHeight,
                data.getBorder(),
                buf.capacity(),
                buf);
            updateSubImageImpl(data, texTarget, 0, 0, 0, 0, 0, data.getWidth(), data.getHeight());
          }
        } else {
          if (data.getMipmap() && haveAutoMipmapGeneration) {
            // For now, only use hardware mipmapping for uncompressed 2D
            // textures where the user hasn't explicitly specified
            // mipmap data; don't know about interactions between
            // GL_GENERATE_MIPMAP and glCompressedTexImage2D
            gl.glTexParameteri(texParamTarget, GL.GL_GENERATE_MIPMAP, GL.GL_TRUE);
            usingAutoMipmapGeneration = true;
          }

          gl.glTexImage2D(
              texTarget,
              0,
              data.getInternalFormat(),
              texWidth,
              texHeight,
              data.getBorder(),
              data.getPixelFormat(),
              data.getPixelType(),
              null);
          updateSubImageImpl(data, texTarget, 0, 0, 0, 0, 0, data.getWidth(), data.getHeight());
        }
      }
    }

    int minFilter = (data.getMipmap() ? GL.GL_LINEAR_MIPMAP_LINEAR : GL.GL_LINEAR);
    int magFilter = GL.GL_LINEAR;
    int wrapMode = (gl.isExtensionAvailable("GL_VERSION_1_2") ? GL.GL_CLAMP_TO_EDGE : GL.GL_CLAMP);

    // REMIND: figure out what to do for GL_TEXTURE_RECTANGLE_ARB
    if (texTarget != GL.GL_TEXTURE_RECTANGLE_ARB) {
      gl.glTexParameteri(texParamTarget, GL.GL_TEXTURE_MIN_FILTER, minFilter);
      gl.glTexParameteri(texParamTarget, GL.GL_TEXTURE_MAG_FILTER, magFilter);
      gl.glTexParameteri(texParamTarget, GL.GL_TEXTURE_WRAP_S, wrapMode);
      gl.glTexParameteri(texParamTarget, GL.GL_TEXTURE_WRAP_T, wrapMode);
      if (this.target == GL.GL_TEXTURE_CUBE_MAP) {
        gl.glTexParameteri(texParamTarget, GL.GL_TEXTURE_WRAP_R, wrapMode);
      }
    }

    // Don't overwrite target if we're loading e.g. faces of a cube
    // map
    if ((this.target == 0)
        || (this.target == GL.GL_TEXTURE_2D)
        || (this.target == GL.GL_TEXTURE_RECTANGLE_ARB)) {
      this.target = texTarget;
    }

    // This estimate will be wrong for cube maps
    estimatedMemorySize = data.getEstimatedMemorySize();
  }
예제 #22
0
    // All rays we deal with here are in world coordinates.
    // Should take the refractive index of the material it is currently in.
    DoubleColor trace(Ray ray) {
      DoubleColor color = new DoubleColor(0.0, 0.0, 0.0, 1.0);
      HitRecord hit = new HitRecord();

      if (depth > Math.max(DEBUG_recursion, scene.maxRecursiveDepth)) return color;

      double tMin = 0.0001;
      double tMax = 10000000;

      // Spheres only for now
      for (int i = 0; i < numObjects; i++)
        // Did I hit the bounding sphere for an object?
        if (spheres[i].hit(ray, tMin, tMax, 0, hit))
          if (scene.spheresOnly) {
            for (PMesh.SurfCell s = shapes[i].surfHead; s != null; s = s.next)
              for (PMesh.PolyCell poly = s.polyHead; poly != null; poly = poly.next)
                // Triangles only for now
                if (poly.numVerts == 3) {
                  Double3D v[] = new Double3D[3];
                  int j = 0;
                  for (PMesh.VertListCell vert = poly.vert; vert != null; vert = vert.next)
                    v[j++] = shapes[i].vertArray.get(vert.vert).viewPos;
                  // Increment j in the line post access

                  // Check for a hit on this polygon
                  if (Triangle.hit(v[0], v[1], v[2], ray, tMin, tMax, 0, hit)) {
                    tMax = hit.t;

                    hit.normal = poly.viewNorm;
                    hit.matIndex = s.material;
                    hit.index = i;
                  }
                } else
                  System.out.println(
                      "Need to intersect polygon with " + poly.numVerts + " vertices.");
          } else {
            tMax = hit.t;
            hit.matIndex = i; // May cause an error if object 10 and it only has 3 materials.
            hit.index = i;
          }

      if (hit.index >= 0) // If it intersects then multi-sample
      {
        if (!sampled && depth == 0) {
          // Only sample once per ray from the main loop
          sampled = true;

          Double3D dir = ray.dir;
          DoubleColor antiAlias = trace(ray);

          for (int i = 0; i < samples; i++) {
            // Double3D sample = new Double3D(dir.x + imageSamples[i].x, dir.y + imageSamples[i].y,
            // dir.z).getUnit();
            // ray.dir = sample;
            ray.dir.x = dir.x + imageSamples[i].x;
            ray.dir.y = dir.y + imageSamples[i].y;

            antiAlias.plus(trace(ray));
          }
          antiAlias.scale(1.0 / (samples + 1.0));

          color.plus(antiAlias);
        } else if (hit.matIndex < shapes[hit.index].materials.length)
          color = shade(ray, hit, shapes[hit.index].materials[hit.matIndex], false);
        else
          color =
              shade(
                  ray,
                  hit,
                  shapes[hit.index].materials[shapes[hit.index].materials.length - 1],
                  false);
      } else // We hit nothing check for intersection with the far clip plane for checker board
      // pattern.
      if (scene.checkerBackground) color = shade(ray, hit, checkerBackgroundHit(ray, hit), true);

      return color;
    }
예제 #23
0
  protected void runTestGL(
      final GLCapabilities caps,
      final FrameLayout frameLayout,
      final boolean twoCanvas,
      final boolean resizeByComp)
      throws InterruptedException, InvocationTargetException {
    final JFrame frame = new JFrame("Bug816: " + this.getTestMethodName());
    Assert.assertNotNull(frame);
    final Container framePane = frame.getContentPane();

    final GLCanvas glCanvas1 = new GLCanvas(caps);
    Assert.assertNotNull(glCanvas1);
    final GLCanvas glCanvas2;
    if (twoCanvas) {
      glCanvas2 = new GLCanvas(caps);
      Assert.assertNotNull(glCanvas2);
    } else {
      glCanvas2 = null;
    }

    final Dimension glcDim = new Dimension(width / 2, height);
    final Dimension frameDim = new Dimension(twoCanvas ? width + 64 : width / 2 + 64, height + 64);

    setComponentSize(null, glCanvas1, glcDim, glCanvas2, glcDim);

    switch (frameLayout) {
      case None:
        {
          framePane.add(glCanvas1);
        }
        break;
      case Flow:
        {
          final Container c = new Container();
          c.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
          c.add(glCanvas1);
          if (twoCanvas) {
            c.add(glCanvas2);
          }
          framePane.add(c);
        }
        break;
      case DoubleBorderCenterSurrounded:
        {
          final Container c = new Container();
          c.setLayout(new BorderLayout());
          c.add(new Button("north"), BorderLayout.NORTH);
          c.add(new Button("south"), BorderLayout.SOUTH);
          c.add(new Button("east"), BorderLayout.EAST);
          c.add(new Button("west"), BorderLayout.WEST);
          if (twoCanvas) {
            final Container c2 = new Container();
            c2.setLayout(new GridLayout(1, 2));
            c2.add(glCanvas1);
            c2.add(glCanvas2);
            c.add(c2, BorderLayout.CENTER);
          } else {
            c.add(glCanvas1, BorderLayout.CENTER);
          }
          framePane.setLayout(new BorderLayout());
          framePane.add(new Button("NORTH"), BorderLayout.NORTH);
          framePane.add(new Button("SOUTH"), BorderLayout.SOUTH);
          framePane.add(new Button("EAST"), BorderLayout.EAST);
          framePane.add(new Button("WEST"), BorderLayout.WEST);
          framePane.add(c, BorderLayout.CENTER);
        }
        break;
      case Box:
        {
          final Container c = new Container();
          c.setLayout(new BoxLayout(c, BoxLayout.X_AXIS));
          c.add(glCanvas1);
          if (twoCanvas) {
            c.add(glCanvas2);
          }
          framePane.add(c);
        }
        break;
      case Split:
        {
          final Dimension sbDim = new Dimension(16, 16);
          final JScrollPane vsp =
              new JScrollPane(
                  ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
                  ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
          {
            final JScrollBar vsb = vsp.getVerticalScrollBar();
            vsb.setPreferredSize(sbDim);
            final BoundedRangeModel model = vsb.getModel();
            model.setMinimum(0);
            model.setMaximum(100);
            model.setValue(50);
            model.setExtent(1);
            vsb.setEnabled(true);
          }
          final JScrollPane hsp =
              new JScrollPane(
                  ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
                  ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
          {
            final JScrollBar hsb = hsp.getHorizontalScrollBar();
            hsb.setPreferredSize(sbDim);
            final BoundedRangeModel model = hsb.getModel();
            model.setMinimum(0);
            model.setMaximum(100);
            model.setValue(50);
            model.setExtent(1);
            hsb.setEnabled(true);
          }
          final JSplitPane horizontalSplitPane =
              new JSplitPane(
                  JSplitPane.HORIZONTAL_SPLIT, true, twoCanvas ? glCanvas2 : vsp, glCanvas1);
          horizontalSplitPane.setResizeWeight(0.5);
          final JSplitPane verticalSplitPane =
              new JSplitPane(JSplitPane.VERTICAL_SPLIT, true, horizontalSplitPane, hsp);
          verticalSplitPane.setResizeWeight(0.5);
          framePane.add(verticalSplitPane);
        }
        break;
    }
    final GearsES2 demo1 = new GearsES2(swapInterval);
    glCanvas1.addGLEventListener(demo1);
    if (twoCanvas) {
      final RedSquareES2 demo2 = new RedSquareES2(swapInterval);
      glCanvas2.addGLEventListener(demo2);
    }

    final Animator animator = new Animator();
    animator.add(glCanvas1);
    if (twoCanvas) {
      animator.add(glCanvas2);
    }
    final QuitAdapter quitAdapter = new QuitAdapter();
    new AWTWindowAdapter(new TraceWindowAdapter(quitAdapter), glCanvas1).addTo(frame);

    javax.swing.SwingUtilities.invokeAndWait(
        new Runnable() {
          public void run() {
            if (resizeByComp) {
              frame.pack();
            } else {
              setFrameSize(frame, true, frameDim);
            }
            frame.setVisible(true);
          }
        });
    Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true));
    Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glCanvas1, true));
    if (twoCanvas) {
      Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glCanvas2, true));
    }

    animator.start();
    Assert.assertTrue(animator.isStarted());
    Assert.assertTrue(animator.isAnimating());

    System.err.println(
        "canvas1 pos/siz: "
            + glCanvas1.getX()
            + "/"
            + glCanvas1.getY()
            + " "
            + glCanvas1.getSurfaceWidth()
            + "x"
            + glCanvas1.getSurfaceHeight());
    if (twoCanvas) {
      System.err.println(
          "canvas2 pos/siz: "
              + glCanvas2.getX()
              + "/"
              + glCanvas2.getY()
              + " "
              + glCanvas2.getSurfaceWidth()
              + "x"
              + glCanvas2.getSurfaceHeight());
    }

    Thread.sleep(Math.max(1000, duration / 2));
    if (null != rwsize) {
      final Dimension compRSizeHalf = new Dimension(rwsize.width / 2, rwsize.height);
      final Dimension frameRSizeHalf =
          new Dimension(twoCanvas ? rwsize.width + 64 : rwsize.width / 2 + 64, rwsize.height + 64);
      if (resizeByComp) {
        setComponentSize(frame, glCanvas1, compRSizeHalf, glCanvas2, compRSizeHalf);
      } else {
        setFrameSize(frame, true, frameRSizeHalf);
      }
      System.err.println(
          "resize canvas1 pos/siz: "
              + glCanvas1.getX()
              + "/"
              + glCanvas1.getY()
              + " "
              + glCanvas1.getSurfaceWidth()
              + "x"
              + glCanvas1.getSurfaceHeight());
      if (twoCanvas) {
        System.err.println(
            "resize canvas2 pos/siz: "
                + glCanvas2.getX()
                + "/"
                + glCanvas2.getY()
                + " "
                + glCanvas2.getSurfaceWidth()
                + "x"
                + glCanvas2.getSurfaceHeight());
      }
    }

    final long t0 = System.currentTimeMillis();
    long t1 = t0;
    while (!quitAdapter.shouldQuit() && t1 - t0 < duration) {
      Thread.sleep(100);
      t1 = System.currentTimeMillis();
    }

    Assert.assertNotNull(frame);
    Assert.assertNotNull(glCanvas1);
    if (twoCanvas) {
      Assert.assertNotNull(glCanvas2);
    } else {
      Assert.assertNull(glCanvas2);
    }

    Assert.assertNotNull(animator);
    animator.stop();
    Assert.assertFalse(animator.isAnimating());
    Assert.assertFalse(animator.isStarted());

    javax.swing.SwingUtilities.invokeAndWait(
        new Runnable() {
          public void run() {
            frame.setVisible(false);
          }
        });
    Assert.assertEquals(false, frame.isVisible());
    javax.swing.SwingUtilities.invokeAndWait(
        new Runnable() {
          public void run() {
            frame.remove(glCanvas1);
            if (twoCanvas) {
              frame.remove(glCanvas2);
            }
            frame.dispose();
          }
        });
  }