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--; } }
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; } } }
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(); }
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(); }
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(); }
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; }
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(); } }
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); }
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 ); }
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(); }
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); } }
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(); }
/** Returns the distance at which objects should spawn. */ public float getSpawnDistance() { return Math.min(8 * player.getSpeed(), Tunnel.GRID_LENGTH * Tunnel.GSQ_LEN / 2); }
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] ); }
// 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; }
// 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); }
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(); }
// 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; }
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(); } }); }