예제 #1
0
 public void setViewport(int i, int j, int width, int height) {
   SLog.d(did, String.format("Viewport set: %d/%d", width, height));
   viewport[0] = i;
   viewport[1] = j;
   viewport[2] = width;
   viewport[3] = height;
 }
예제 #2
0
  @Override
  public void onSurfaceChanged(GL10 gl, int width, int height) {
    gl.glViewport(0, 0, width, height);

    camera.setViewport(0, 0, width, height);
    camera.changePerspective(gl, Projection.PERSPECTIVE);

    SLog.d(did, "Surface created.");
  }
예제 #3
0
  public void changePerspective(GL10 gl, Projection p) {
    SLog.d(did, "Changing perspective.");
    gl.glMatrixMode(GL10.GL_PROJECTION); // select projection
    gl.glLoadIdentity(); // reset
    float aspect = ((float) viewport[2] / viewport[3]);
    switch (p) {
      case PERSPECTIVE:
        SLog.d(did, "Setting perspective mode width aspect = " + aspect);
        gl.glFrustumf(-aspect, aspect, -1f, 1f, near, far);
        break;
      case ORTHOGRAPHIC:
        SLog.d(did, "Setting orthographic mode.");
        gl.glOrthof(-1, 1, -1, 1, -1f, 10.0f);
        break;
      default:
        break;
    }

    hasChanged = true;
  }
예제 #4
0
 static {
   SLog.setTag(did, "GL Renderer.");
 }
예제 #5
0
public class GLRenderer implements GameRenderer {

  private static final int did = SLog.register(GLRenderer.class);

  static {
    SLog.setTag(did, "GL Renderer.");
  }

  private GLSurface surface;
  private RenderScheduler renderScheduler;
  private GLCamera camera;

  public GLRenderer(RenderScheduler scheduler, GLCamera camera) {
    this.camera = camera;
    this.renderScheduler = scheduler;
  }

  public void reset(GL10 gl) {}

  @Override
  public void onSurfaceChanged(GL10 gl, int width, int height) {
    gl.glViewport(0, 0, width, height);

    camera.setViewport(0, 0, width, height);
    camera.changePerspective(gl, Projection.PERSPECTIVE);

    SLog.d(did, "Surface created.");
  }

  public void setCamera(GLCamera camera) {
    this.camera = camera;
  }

  /** Makes renderer work. */
  public void renderFrame() {
    surface.requestRender();
  }

  @Override
  public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    camera.reset(gl);
  }

  @Override
  public void onDrawFrame(GL10 gl) {
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

    camera.update(gl);
    camera.focusOnObjects(gl);

    for (Renderable r : renderScheduler.getRenderList(gl)) {
      gl.glPushMatrix();
      r.draw(gl);
      gl.glPopMatrix();
    }
  }

  @Override
  public void setSurface(GLSurface surface) {
    this.surface = surface;
  }

  @Override
  public GLSurface getSurface() {
    return surface;
  }

  @Override
  public Camera getCamera() {
    return camera;
  }
}
예제 #6
0
 static {
   SLog.setTag(did, "Camera.");
   SLog.setLevel(did, Level.VERBOSE);
 }
예제 #7
0
/**
 * Motion observer musi być świadomy gdzie znajduje się kamera! Inaczej współrzędne nic nie znaczą,
 * bo nie wiadomo gdzie jesteśmy w przestrzeni.
 *
 * <p>http://stackoverflow.com/questions/2093096/implementing-ray-picking
 * http://ovcharov.me/2011/01/14/android-opengl-es-ray-picking/
 *
 * <p>Może macierze powinienem przetrzymywać jako zwykle floaty i je przestawiać po prostu sobie?
 * http://www.learnopengles.com/android-lesson-one-getting-started/ a na koniec podawać do opengl
 *
 * <p>Faktycznie, samemu powinno się trzymać te macierze! !!!!!!!!!!!!!!!!!!!!!!!!!!! When working
 * with opengles 2 in Android you keep track of your matrices yourself, usually as a couple of
 * float[]. If you calculate them directly in the shader, I don't think that you can get them.
 * !!!!!!!!!!!!!!!!!!!!!!!!!!!
 *
 * <p>Opengl 2.0 nie ma już nawet funkcji translate czy scale, trzeba robić to samemu! A więc każdy
 * obiekt będzie pewnie musiał mieć dostęp jakoś do kamery i zlecać przestawienia modelview...
 *
 * <p>dobre http://stackoverflow.com/questions/6261867/question-about-3d-picking-in-
 * android-with-opengl-es-2
 *
 * <p>Wszelkie glulookat itd przestają mieć rację bytu, wszystkie operacje na macierzach robimy
 * systemowo a dostarczamy je po prostu do renderowania
 *
 * <p>Znikają funkcje jak gl.matrixMode itd.
 *
 * <p>Na razie oldschoolowo PICK RAY (przez wczytywanie macierzy z opengl na siłę przy użyciu
 * glGetFloat - które oczywiście znika razem z translate itp itd. w następnej wersji opengl). Na
 * razie mogę sobie korzystać ze wszystkich GLU.cośtam Pojawia się pytanie najważniejsze - czy przy
 * obliczaniu ray musimy znać aktaulną dla danego obiektu macierz model?
 *
 * <p>Jeśli tak by było to każdy renderer musi sobie trzymać kopię modelview matrix. Projection się
 * nie zmienia więc może siedzieć tutaj.
 *
 * @author kboom
 */
public class GLCamera implements Camera {

  private static final int did = SLog.register(GLCamera.class);

  static {
    SLog.setTag(did, "Camera.");
    SLog.setLevel(did, Level.VERBOSE);
  }

  private boolean hasChanged = true;
  // Position the eye behind the origin.
  private float xEye = 0f;
  private float yEye = 0f; // put somewhere here to get pretty much good view
  // over things
  private float zEye = 3f;

  // We are looking toward the distance
  private float xLook = 0f;
  private float yLook = 0f;
  private float zLook = 0f;

  // This is where our head (not eyes!) would be pointing were we holding the
  // camera.
  final float xUp = 0.0f;
  final float yUp = 1.0f;
  final float zUp = 0.0f;

  private float near = 1f;
  private float far = 100f;

  /*
   *
   * Most important matrices. (chyba do wywalenia...)
   */

  /** Screen dimensions. */
  private final int[] viewport = new int[4];

  /**
   * This matrix can be thought of as our camera. This matrix transforms world space to eye space;
   * it positions things relative to our eye.
   */
  private final float[] modelview = new float[16];

  /**
   * How the objects are rendered in the space. Probably will be used by every object to draw itself
   * onto the screen.
   */
  private final float[] projection = new float[16];

  // dummy one
  private final float[] dummy = new float[16];

  public GLCamera() {
    SLog.v(did, "+++ constructor +++");
  }

  public void setViewport(int i, int j, int width, int height) {
    SLog.d(did, String.format("Viewport set: %d/%d", width, height));
    viewport[0] = i;
    viewport[1] = j;
    viewport[2] = width;
    viewport[3] = height;
  }

  public void reset(GL10 gl) {
    SLog.v(did, "Reseting..");
    hasChanged = true;
  }

  public enum Projection {
    PERSPECTIVE,
    ORTHOGRAPHIC
  }

  public void changePerspective(GL10 gl, Projection p) {
    SLog.d(did, "Changing perspective.");
    gl.glMatrixMode(GL10.GL_PROJECTION); // select projection
    gl.glLoadIdentity(); // reset
    float aspect = ((float) viewport[2] / viewport[3]);
    switch (p) {
      case PERSPECTIVE:
        SLog.d(did, "Setting perspective mode width aspect = " + aspect);
        gl.glFrustumf(-aspect, aspect, -1f, 1f, near, far);
        break;
      case ORTHOGRAPHIC:
        SLog.d(did, "Setting orthographic mode.");
        gl.glOrthof(-1, 1, -1, 1, -1f, 10.0f);
        break;
      default:
        break;
    }

    hasChanged = true;
  }

  public void focusOnObjects(GL10 gl) {
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glEnable(GL10.GL_DEPTH_TEST);
    gl.glClearColor(0f, 0f, 0f, 1.0f);
  }

  public void update(GL10 gl) {
    gl.glMatrixMode(GL10.GL_PROJECTION);
    // dopisane
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    // gl.glLoadIdentity();

    // koniec
    if (hasChanged) {
      GLU.gluLookAt(gl, xEye, yEye, zEye, xLook, yLook, zLook, xUp, yUp, zUp);
      hasChanged = false;
    }
    // GL11 gl11 = (GL11) gl;
    // gl11.glGetFloatv(GL10.GL_MODELVIEW, modelview, 0); // wystarczyło
    // dopisać 0 i już
    // traktuje jako
    // float
    // gl11.glGetFloatv(GL10.GL_PROJECTION, projection, 0);

    // NIEPOTRZEBNE BO DZIAła i bez tego
    /*
     * gl.glLoadIdentity(); gl.glFrustumf(-aspect, aspect, -1f, 1f, near,
     * far); gl.glRotatef(xAngle * 10, 1f, 0, 0); gl.glRotatef(yAngle * 10,
     * 0, 1f, 0); gl.glRotatef(zAngle, 0f, 0f, 1f); gl.glTranslatef(xPos,
     * yPos, zPos);
     */

  }

  @Override
  public void accomodateTo(float near, float far) {
    this.near = near;
    this.far = far;

    hasChanged = true;
  }

  @Override
  public void move(float x, float y, float z) {
    xEye = x;
    yEye = y;
    zEye = z;

    hasChanged = true;
  }

  @Override
  public void rotate(float xAngle, float yAngle, float zAngle) {
    // just rotate the coordinates
    hasChanged = true;
  }

  @Override
  public void getRay(float x, float y, float z, float[] ray) {

    /*
     *
     * normalised_x = 2 * mouse_x / win_width - 1 normalised_y = 1 - 2 *
     * mouse_y / win_height // note the y pos is inverted, so +y is at the
     * top of the screen
     *
     * unviewMat = (projectionMat * modelViewMat).inverse()
     *
     * near_point = unviewMat * Vec(normalised_x, normalised_y, 0, 1)
     * camera_pos = ray_origin = modelViewMat.inverse().col(4) ray_dir =
     * near_point - camera_pos
     */

    // GLU.gluUnProject(winX, winY, winZ, model, modelOffset, project,
    // projectOffset, view, viewOffset, obj, objOffset)

    GLU.gluUnProject(x, viewport[3] - y, z, modelview, 0, projection, 0, viewport, 0, ray, 0);

    // fix
    if (ray[3] != 0) {
      ray[0] = ray[0] / ray[3];
      ray[1] = ray[1] / ray[3];
      ray[2] = ray[2] / ray[3];
    }

    ray[0] = ray[0] - xEye;
    ray[1] = ray[1] - yEye;
    ray[2] = ray[2] - zEye;

    // 0f jako 4 ta?
  }

  @Override
  public void lookAt(float x, float y, float z) {
    xLook = x;
    yLook = y;
    zLook = z;
  }

  /*
   * OBOWIAZUJACE PODEJSCIE normalizedPoint[0] = (x * 2 / screenW) -1;
   * normalizedPoint[1] = 1 - (y * 2 / screenH); normalizedPoint[2] = ?
   * normalizedPoint[3] = ? matrix = perspective_matrix x model_matrix
   * inv_matrix = inverse(matrix) outpoint = inv_matrix x normalizedPoint
   */

  // albo to?

  /*
   * public void unproject(float [] in, float [] out) {
   *
   * // multiply to get mvp float [] mvp = dummy; Matrix.multiplyMM(mvp, 0,
   * projection, 0, modelview, 0); // invert it Matrix.invertM(mvp, 0, mvp,
   * 0);
   *
   * // screen coordinates are already normalized // compute it
   * Matrix.multiplyMV(out, 0, mvp, 0, in, 0);
   *
   * if (out[3] == 0) return null;
   *
   * out[3] = 1 / out[3];
   *
   * float o1 = out[1]; float o2 = out[2]; float o3 = out[3]; float o4 =
   * out[4];
   *
   * out[0] = o1 * o3; out[1] = o1 * o3; out[2] = o2 * o3; out[3] = 0; // not
   * really needed...
   *
   * // potem
   *
   * Vec3 near = unProject(30, 50, 0, mvpMatrix, 800, 480); Vec3 far =
   * unProject(30, 50, 1, mvpMatrix, 800, 480); // 1 for winz means projected
   * on the far plane Vec3 pickingRay = Subtract(far, near); // Vector
   * subtraction
   *
   * }
   */

}
예제 #8
0
 public void reset(GL10 gl) {
   SLog.v(did, "Reseting..");
   hasChanged = true;
 }
예제 #9
0
 public GLCamera() {
   SLog.v(did, "+++ constructor +++");
 }