Android Open Source - Gloomy-Dungeons-3D Level Renderer






From Project

Back to project page Gloomy-Dungeons-3D.

License

The source code is released under:

MIT License

If you think the Android project Gloomy-Dungeons-3D listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package zame.game.engine;
//from  w  w w.  j  a v a 2s  .c o  m
import javax.microedition.khronos.opengles.GL10;
import zame.game.Common;
import zame.game.Config;
import zame.game.Renderer;

public class LevelRenderer
{
  public static class VisibleObject
  {
    public float midX;
    public float midY;
    public float fromX;
    public float fromY;
    public float toX;
    public float toY;
    public Object obj;
    public float dist = 0;
  }

  private static final int MAX_VISIBLE_OBJECTS = 64;
  private static final float FLOOR_FADE_ALPHA = 1.0f;

  private static final int AUTO_WALL_TYPE_WALL = 0;
  private static final int AUTO_WALL_TYPE_TRANSP = 1;
  private static final int AUTO_WALL_TYPE_DOOR = 2;

  private static final int AUTO_WALL_MASK_HORIZONTAL = 1;
  private static final int AUTO_WALL_MASK_VERTICAL = 2;
  private static final int AUTO_WALL_MASK_DOOR = 4;

  public static final int MAX_AUTO_WALLS = Level.MAX_WIDTH * Level.MAX_HEIGHT * 2;
  public static final float HALF_WALL = 1.0f / 2.5f;
  public static final float WALL_HGT = HALF_WALL * 2.0f;

  public static PortalTracer tracer;

  public static VisibleObject[] visibleObjects = new VisibleObject[MAX_VISIBLE_OBJECTS];
  public static int visibleObjectsCount;
  public static VisibleObject currVis;

  private static float flatObjDx;
  private static float flatObjDy;

  public static boolean showMonstersOnMap = false;

  public static void init()
  {
    visibleObjectsCount = 0;
    currVis = null;
    tracer = new PortalTracer();

    for (int i = 0; i < MAX_VISIBLE_OBJECTS; i++) {
      visibleObjects[i] = new VisibleObject();
    }
  }

  public static void updateAutoWalls()
  {
    for (int i = 0; i < State.autoWallsCount; i++)
    {
      AutoWall aw = State.autoWalls[i];

      if (aw.doorIndex >= 0) {
        aw.door = State.doors[aw.doorIndex];
      }
    }
  }

  public static void sortVisibleObjects()
  {
    currVis = null;

    for (int i = 0; i < visibleObjectsCount; i++)
    {
      VisibleObject vo = visibleObjects[i];

      int ci = 0;
      int co = 0;

      float t = (vo.fromX - State.heroX) * Common.heroSn + (vo.fromY - State.heroY) * Common.heroCs;

      if (t >= 0) ci++;
      if (t <= 0) co++;

      t = (vo.toX - State.heroX) * Common.heroSn + (vo.toY - State.heroY) * Common.heroCs;

      if (t >= 0) ci++;
      if (t <= 0) co++;

      if (ci > 0 && co > 0)
      {
        float dx = vo.midX - State.heroX;
        float dy = State.heroY - vo.midY;

        float dist = (float)Math.sqrt(dx * dx + dy * dy);

        if (currVis == null || dist < currVis.dist)
        {
          currVis = vo;
          currVis.dist = dist;
        }
      }
    }
  }

  private static void updateDoors(long elapsedTime)
  {
    for (int i = 0; i < State.doorsCount; i++)
    {
      Door door = State.doors[i];

      if (door.dir != 0)
      {
        if (door.dir > 0) {
          door.openPos = (float)(elapsedTime - door.lastTime) / 300.0f;
        } else {
          door.openPos = Door.OPEN_POS_MAX - (float)(elapsedTime - door.lastTime) / 200.0f;
        }

        door.update(elapsedTime);
      }
    }
  }

  public static float getLightness(float x, float y)
  {
    x -= State.heroX;
    y -= State.heroY;

    float d = (x * Common.heroCs - y * Common.heroSn);
    d = (d < 0.0f ? 0.0f : (d * 0.05f));

    return (1.0f - (d > 0.8f ? 0.8f : d));
  }

  public static void setObjLighting(float x, float y)
  {
    float l = getLightness(x, y);

    Renderer.r1 = l; Renderer.g1 = l; Renderer.b1 = l;
    Renderer.r2 = l; Renderer.g2 = l; Renderer.b2 = l;
    Renderer.r3 = l; Renderer.g3 = l; Renderer.b3 = l;
    Renderer.r4 = l; Renderer.g4 = l; Renderer.b4 = l;
  }

  public static void setWallLighting(float fromX, float fromY, float toX, float toY, boolean vert)
  {
    int ang = ((int)State.heroA + (vert ? 0 : 270)) % 360;

    if (ang > 90)
    {
      if (ang < 180) {
        ang = 180 - ang;
      } else if (ang < 270) {
        ang = ang - 180;
      } else {
        ang = 360 - ang;
      }
    }

    float l = 1.0f - 0.5f * (float)ang / 90.0f;

    float l1 = getLightness(fromX, fromY) * l;
    Renderer.r1 = l1; Renderer.g1 = l1; Renderer.b1 = l1;
    Renderer.r2 = l1; Renderer.g2 = l1; Renderer.b2 = l1;

    float l2 = getLightness(toX, toY) * l;
    Renderer.r3 = l2; Renderer.g3 = l2; Renderer.b3 = l2;
    Renderer.r4 = l2; Renderer.g4 = l2; Renderer.b4 = l2;
  }

  // This method:
  // did *not* check for available space (MAX_AUTO_WALLS),
  // did *not* check if wall already exists,
  // did *not* append wall mask,
  // did *not* add doors
  public static void appendAutoWall(int fromX, int fromY, int toX, int toY, int type)
  {
    int index = -1;
    boolean vert = (fromX == toX);

    for (int i = 0; i < State.autoWallsCount; i++)
    {
      AutoWall aw = State.autoWalls[i];

      if ((aw.door != null) || (aw.vert != vert) || (aw.type != type)) {
        continue;
      }

      if ((int)aw.fromX == fromX && (int)aw.fromY == fromY)
      {
        aw.fromX = (float)toX;
        aw.fromY = (float)toY;
        index = i;
        break;
      }
      else if ((int)aw.toX == fromX && (int)aw.toY == fromY)
      {
        aw.toX = (float)toX;
        aw.toY = (float)toY;
        index = i;
        break;
      }
      else if ((int)aw.fromX == toX && (int)aw.fromY == toY)
      {
        aw.fromX = (float)fromX;
        aw.fromY = (float)fromY;
        index = i;
        break;
      }
      else if ((int)aw.toX == toX && (int)aw.toY == toY)
      {
        aw.toX = (float)fromX;
        aw.toY = (float)fromY;
        index = i;
        break;
      }
    }

    if (index < 0)
    {
      AutoWall aw = State.autoWalls[State.autoWallsCount++];

      aw.fromX = (float)fromX;
      aw.fromY = (float)fromY;
      aw.toX = (float)toX;
      aw.toY = (float)toY;
      aw.vert = vert;
      aw.type = type;
      aw.doorIndex = -1;
      aw.door = null;

      return;
    }

    for (;;)
    {
      int nextIndex = -1;
      AutoWall awi = State.autoWalls[index];

      for (int i = 0; i < State.autoWallsCount; i++)
      {
        AutoWall aw = State.autoWalls[i];

        if ((i == index) || (aw.door != null) || (aw.vert != awi.vert) || (aw.type != awi.type)) {
          continue;
        }

        if ((int)aw.fromX == awi.fromX && (int)aw.fromY == awi.fromY)
        {
          aw.fromX = awi.toX;
          aw.fromY = awi.toY;
          nextIndex = i;
          break;
        }
        else if ((int)aw.toX == awi.fromX && (int)aw.toY == awi.fromY)
        {
          aw.toX = awi.toX;
          aw.toY = awi.toY;
          nextIndex = i;
          break;
        }
        else if ((int)aw.fromX == awi.toX && (int)aw.fromY == awi.toY)
        {
          aw.fromX = awi.fromX;
          aw.fromY = awi.fromY;
          nextIndex = i;
          break;
        }
        else if ((int)aw.toX == awi.toX && (int)aw.toY == awi.toY)
        {
          aw.toX = awi.fromX;
          aw.toY = awi.fromY;
          nextIndex = i;
          break;
        }
      }

      if (nextIndex < 0) {
        break;
      }

      State.autoWallsCount--;

      for (int i = index; i < State.autoWallsCount; i++) {
        State.autoWalls[i].copyFrom(State.autoWalls[i + 1]);
      }

      index = (nextIndex > index ? nextIndex - 1 : nextIndex);
    }
  }

  public static void renderLevel()
  {
    Renderer.z1 = -HALF_WALL;
    Renderer.z2 = HALF_WALL;
    Renderer.z3 = HALF_WALL;
    Renderer.z4 = -HALF_WALL;

    for (int i = 0; i < tracer.wallsCount; i++)
    {
      int autoWallMask;
      Door door;

      PortalTracer.Wall wall = tracer.walls[i];

      if (wall.fromX == wall.toX)
      {
        door = (wall.fromY < wall.toY ? Level.doorsMap[wall.fromY][wall.fromX - 1] : Level.doorsMap[wall.toY][wall.fromX]);
        autoWallMask = AUTO_WALL_MASK_VERTICAL;
      }
      else
      {
        door = (wall.fromX < wall.toX ? Level.doorsMap[wall.fromY][wall.fromX] : Level.doorsMap[wall.fromY - 1][wall.toX]);
        autoWallMask = AUTO_WALL_MASK_HORIZONTAL;
      }

      int mx = (wall.fromX < wall.toX ? wall.fromX : wall.toX);
      int my = (wall.fromY < wall.toY ? wall.fromY : wall.toY);

      if (((State.drawedAutoWalls[my][mx] & autoWallMask) == 0) && (State.autoWallsCount < MAX_AUTO_WALLS))
      {
        State.drawedAutoWalls[my][mx] |= autoWallMask;
        appendAutoWall(wall.fromX, wall.fromY, wall.toX, wall.toY, AUTO_WALL_TYPE_WALL);
      }

      if (Level.marksMap[wall.cellY][wall.cellX] != null && visibleObjectsCount < MAX_VISIBLE_OBJECTS)
      {
        VisibleObject vo = visibleObjects[visibleObjectsCount++];

        vo.midX = (wall.fromX + wall.toX) / 2.0f;
        vo.midY = (wall.fromY + wall.toY) / 2.0f;
        vo.fromX = wall.fromX;
        vo.fromY = wall.fromY;
        vo.toX = wall.toX;
        vo.toY = wall.toY;
        vo.obj = Level.marksMap[wall.cellY][wall.cellX];
      }

      Renderer.x1 = (float)wall.fromX; Renderer.y1 = -(float)wall.fromY;
      Renderer.x2 = (float)wall.fromX; Renderer.y2 = -(float)wall.fromY;
      Renderer.x3 = (float)wall.toX; Renderer.y3 = -(float)wall.toY;
      Renderer.x4 = (float)wall.toX; Renderer.y4 = -(float)wall.toY;

      setWallLighting((float)wall.fromX, (float)wall.fromY, (float)wall.toX, (float)wall.toY, (wall.fromX == wall.toX));
      Renderer.drawQuad(door != null ? door.texture + 0x10 : wall.texture);
    }
  }

  private static void renderDoors()
  {
    for (int i = 0; i < tracer.touchedCellsCount; i++)
    {
      PortalTracer.TouchedCell tc = tracer.touchedCells[i];
      Door door = Level.doorsMap[tc.y][tc.x];

      if (door == null) {
        continue;
      }

      float fromX, fromY, toX, toY;

      if (door.vert)
      {
        fromX = (float)door.x + 0.5f;
        toX = fromX;
        fromY = (float)door.y;
        toY = fromY + 1.0f;
      }
      else
      {
        fromX = (float)door.x;
        toX = fromX + 1.0f;
        fromY = (float)door.y + 0.5f;
        toY = fromY;
      }

      if (((State.drawedAutoWalls[door.y][door.x] & AUTO_WALL_MASK_DOOR) == 0) && (State.autoWallsCount < MAX_AUTO_WALLS))
      {
        State.drawedAutoWalls[door.y][door.x] |= AUTO_WALL_MASK_DOOR;
        AutoWall aw = State.autoWalls[State.autoWallsCount++];

        aw.fromX = fromX;
        aw.fromY = fromY;
        aw.toX = toX;
        aw.toY = toY;
        aw.vert = door.vert;
        aw.type = AUTO_WALL_TYPE_DOOR;
        aw.doorIndex = door.index;
        aw.door = door;
      }

      // do not add opened doors to visible objects, otherwise it is impossible to shoot monsters behind opened door
      if ((door.openPos) < 0.7f && (visibleObjectsCount < MAX_VISIBLE_OBJECTS))
      {
        VisibleObject vo = visibleObjects[visibleObjectsCount++];

        vo.midX = (float)door.x + 0.5f;
        vo.midY = (float)door.y + 0.5f;
        vo.fromX = fromX;
        vo.fromY = fromY;
        vo.toX = toX;
        vo.toY = toY;
        vo.obj = door;
      }

      if (door.vert)
      {
        fromY += door.openPos;
        toY += door.openPos;
      }
      else
      {
        fromX += door.openPos;
        toX += door.openPos;
      }

      Renderer.x1 = fromX; Renderer.y1 = -fromY;
      Renderer.x2 = fromX; Renderer.y2 = -fromY;
      Renderer.x3 = toX; Renderer.y3 = -toY;
      Renderer.x4 = toX; Renderer.y4 = -toY;

      setWallLighting(fromX, fromY, toX, toY, door.vert);
      Renderer.drawQuad(door.texture);
    }
  }

  // render objects, decorations and transparents
  private static void renderObjects()
  {
    for (int i = 0; i < tracer.touchedCellsCount; i++)
    {
      PortalTracer.TouchedCell tc = tracer.touchedCells[i];
      int tex = State.objectsMap[tc.y][tc.x];

      if (tex > 0)
      {
        float mx = (float)tc.x + 0.5f;
        float my = (float)tc.y + 0.5f;

        float fromX = mx + flatObjDy;
        float toX = mx - flatObjDy;
        float fromY = my - flatObjDx;
        float toY = my + flatObjDx;

        Renderer.x1 = fromX; Renderer.y1 = -fromY;
        Renderer.x2 = fromX; Renderer.y2 = -fromY;
        Renderer.x3 = toX; Renderer.y3 = -toY;
        Renderer.x4 = toX; Renderer.y4 = -toY;

        setObjLighting(mx, my);
        Renderer.drawQuad(tex);
      }

      tex = State.decorationsMap[tc.y][tc.x];

      if (tex != 0)
      {
        // if decoration tex == -1, than there is object here (or was before hero picked up it), but there can't be transparents
        if (tex > 0)
        {
          float mx = (float)tc.x + 0.5f;
          float my = (float)tc.y + 0.5f;

          float fromX = mx + flatObjDy;
          float toX = mx - flatObjDy;
          float fromY = my - flatObjDx;
          float toY = my + flatObjDx;

          Renderer.x1 = fromX; Renderer.y1 = -fromY;
          Renderer.x2 = fromX; Renderer.y2 = -fromY;
          Renderer.x3 = toX; Renderer.y3 = -toY;
          Renderer.x4 = toX; Renderer.y4 = -toY;

          setObjLighting(mx, my);
          Renderer.drawQuad(tex);
        }
      }
      else
      {
        tex = State.transpMap[tc.y][tc.x];

        if (tex >= TextureLoader.BASE_TRANSPARENTS + 0x10)
        {
          float fromX, fromY, toX, toY;
          boolean vert = (tex >= TextureLoader.BASE_TRANSPARENTS + 0x18);

          if (vert)
          {
            tex -= 8;

            fromX = (float)tc.x + 0.5f;
            toX = fromX;
            fromY = (float)tc.y;
            toY = fromY + 1.0f;
          }
          else
          {
            fromX = (float)tc.x;
            toX = fromX + 1.0f;
            fromY = (float)tc.y + 0.5f;
            toY = fromY;
          }

          if (((State.drawedAutoWalls[tc.y][tc.x] & AUTO_WALL_MASK_DOOR) == 0) && (State.autoWallsCount < MAX_AUTO_WALLS))
          {
            State.drawedAutoWalls[tc.y][tc.x] |= AUTO_WALL_MASK_DOOR;
            AutoWall aw = State.autoWalls[State.autoWallsCount++];

            aw.fromX = fromX;
            aw.fromY = fromY;
            aw.toX = toX;
            aw.toY = toY;
            aw.vert = vert;
            aw.type = AUTO_WALL_TYPE_TRANSP;
            aw.doorIndex = -1;
            aw.door = null;
          }

          Renderer.x1 = fromX; Renderer.y1 = -fromY;
          Renderer.x2 = fromX; Renderer.y2 = -fromY;
          Renderer.x3 = toX; Renderer.y3 = -toY;
          Renderer.x4 = toX; Renderer.y4 = -toY;

          setWallLighting(fromX, fromY, toX, toY, vert);
          Renderer.drawQuad(tex);
        }
        else if (tex > 0)
        {
          for (int s = 0; s < 4; s++)
          {
            if ((State.passableMap[tc.y + PortalTracer.Y_CELL_ADD[s]][tc.x + PortalTracer.X_CELL_ADD[s]] & Level.PASSABLE_MASK_WALL_N_TRANSP) == 0)
            {
              int fromX = tc.x + PortalTracer.X_ADD[s];
              int fromY = tc.y + PortalTracer.Y_ADD[s];
              int toX = tc.x + PortalTracer.X_ADD[(s + 1) % 4];
              int toY = tc.y + PortalTracer.Y_ADD[(s + 1) % 4];

              Renderer.x1 = (float)fromX; Renderer.y1 = -(float)fromY;
              Renderer.x2 = (float)fromX; Renderer.y2 = -(float)fromY;
              Renderer.x3 = (float)toX; Renderer.y3 = -(float)toY;
              Renderer.x4 = (float)toX; Renderer.y4 = -(float)toY;

              int mx = (fromX < toX ? fromX : toX);
              int my = (fromY < toY ? fromY : toY);
              int autoWallMask = ((s == 1 || s == 3) ? AUTO_WALL_MASK_VERTICAL : AUTO_WALL_MASK_HORIZONTAL);

              if (((State.drawedAutoWalls[my][mx] & autoWallMask) == 0) && (State.autoWallsCount < MAX_AUTO_WALLS))
              {
                State.drawedAutoWalls[my][mx] |= autoWallMask;
                appendAutoWall(fromX, fromY, toX, toY, AUTO_WALL_TYPE_TRANSP);
              }

              setWallLighting((float)fromX, (float)fromY, (float)toX, (float)toY, (s == 1 || s == 3));
              Renderer.drawQuad(tex);
            }
          }
        }
      }
    }
  }

  private static void renderMonsters(long elapsedTime, boolean deadCorpses)
  {
    for (int i = 0; i < State.monstersCount; i++)
    {
      Monster mon = State.monsters[i];

      int x = (int)mon.x;
      int y = (int)mon.y;

      if (  (!(tracer.touchedCellsMap[y][x] || tracer.touchedCellsMap[mon.cellX][mon.cellY])) ||
          (deadCorpses && mon.health > 0) ||
          (!deadCorpses && mon.health <= 0))
      {
        continue;
      }

      float fromX = mon.x + flatObjDy;
      float toX = mon.x - flatObjDy;
      float fromY = mon.y - flatObjDx;
      float toY = mon.y + flatObjDx;

      int tex = mon.texture;
      setObjLighting(mon.x, mon.y);

      Renderer.x1 = fromX; Renderer.y1 = -fromY;
      Renderer.x2 = fromX; Renderer.y2 = -fromY;
      Renderer.x3 = toX; Renderer.y3 = -toY;
      Renderer.x4 = toX; Renderer.y4 = -toY;

      if (mon.health > 0)
      {
        if ((mon.hitTimeout <= 0) && (mon.attackTimeout > 0)) {
          tex += 15;
        } else if (mon.isAimedOnHero) {
          tex += 2;
        } else {
          tex += ((((int)State.heroA + 360 + 45 - mon.dir * 90) % 360) / 90);
        }

        if (mon.hitTimeout > 0) {
          tex += 8;
        } else if (!mon.isInAttackState && ((elapsedTime % 800) > 400)) {
          tex += 4;
        }

        if (visibleObjectsCount < MAX_VISIBLE_OBJECTS)
        {
          VisibleObject vo = visibleObjects[visibleObjectsCount++];

          float dx = mon.x - State.heroX;
          float dy = mon.y - State.heroY;
          float dist = (float)Math.sqrt(dx * dx + dy * dy);
          float mult = Math.min(1.0f, 0.4f + dist * 0.12f);

          vo.midX = mon.x;
          vo.midY = mon.y;
          vo.fromX = mon.x + flatObjDy * mult;
          vo.fromY = mon.y - flatObjDx * mult;
          vo.toX = mon.x - flatObjDy * mult;
          vo.toY = mon.y + flatObjDx * mult;
          vo.obj = mon;
        }
      }
      else
      {
        if (mon.dieTime == 0) {
          mon.dieTime = elapsedTime;
        }

        tex += 12 + (mon.dieTime < 0 ? 2 : Math.min(2, (elapsedTime - mon.dieTime) / 150));
      }

      Renderer.drawQuadMon(tex);
    }
  }

  private static void renderFloor(GL10 gl)
  {
    gl.glDisable(GL10.GL_DEPTH_TEST);

    Renderer.r1 = 1.0f; Renderer.g1 = 1.0f; Renderer.b1 = 1.0f; Renderer.a1 = 1.0f;
    Renderer.r2 = 1.0f; Renderer.g2 = 1.0f; Renderer.b2 = 1.0f; Renderer.a2 = 1.0f;
    Renderer.r3 = 1.0f; Renderer.g3 = 1.0f; Renderer.b3 = 1.0f; Renderer.a3 = 1.0f;
    Renderer.r4 = 1.0f; Renderer.g4 = 1.0f; Renderer.b4 = 1.0f; Renderer.a4 = 1.0f;

    Renderer.init();

    Renderer.z1 = -HALF_WALL;
    Renderer.z2 = -HALF_WALL;
    Renderer.z3 = -HALF_WALL;
    Renderer.z4 = -HALF_WALL;

    Renderer.u1 = 0.0f; Renderer.v1 = (float)State.levelHeight;
    Renderer.u2 = 0.0f; Renderer.v2 = 0.0f;
    Renderer.u3 = (float)State.levelWidth; Renderer.v3 = 0.0f;
    Renderer.u4 = (float)State.levelWidth; Renderer.v4 = (float)State.levelHeight;

    Renderer.x1 = Renderer.u1; Renderer.y1 = -Renderer.v1;
    Renderer.x2 = Renderer.u2; Renderer.y2 = -Renderer.v2;
    Renderer.x3 = Renderer.u3; Renderer.y3 = -Renderer.v3;
    Renderer.x4 = Renderer.u4; Renderer.y4 = -Renderer.v4;

    Renderer.drawQuad();

    Renderer.bindTextureRep(gl, TextureLoader.textures[TextureLoader.TEXTURE_FLOOR]);
    Renderer.flush(gl);

    Renderer.init();

    Renderer.z1 = HALF_WALL;
    Renderer.z2 = HALF_WALL;
    Renderer.z3 = HALF_WALL;
    Renderer.z4 = HALF_WALL;

    Renderer.u2 = (float)State.levelWidth; Renderer.v2 = (float)State.levelHeight;
    Renderer.u4 = 0.0f; Renderer.v4 = 0.0f;

    Renderer.x2 = Renderer.u2; Renderer.y2 = -Renderer.v2;
    Renderer.x4 = Renderer.u4; Renderer.y4 = -Renderer.v4;

    Renderer.drawQuad();

    Renderer.bindTextureRep(gl, TextureLoader.textures[TextureLoader.TEXTURE_CEIL]);
    Renderer.flush(gl);

    // Fading

    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glPushMatrix();
    Renderer.loadIdentityAndOrthof(gl, -1.0f, 1.0f, -1.0f, 1.0f, 0f, 1.0f);

    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glPushMatrix();
    gl.glLoadIdentity();

    Renderer.init();

    Renderer.r1 = 0.0f; Renderer.g1 = 0.0f; Renderer.b1 = 0.0f;
    Renderer.r2 = 0.0f; Renderer.g2 = 0.0f; Renderer.b2 = 0.0f;
    Renderer.r3 = 0.0f; Renderer.g3 = 0.0f; Renderer.b3 = 0.0f;
    Renderer.r4 = 0.0f; Renderer.g4 = 0.0f; Renderer.b4 = 0.0f;

    Renderer.z1 = 0.0f;
    Renderer.z2 = 0.0f;
    Renderer.z3 = 0.0f;
    Renderer.z4 = 0.0f;

    Renderer.x1 = -1.0f; Renderer.y1 = -1.0f; Renderer.a1 = 0.0f;
    Renderer.x2 = -1.0f; Renderer.y2 = 0.0f; Renderer.a2 = FLOOR_FADE_ALPHA;
    Renderer.x3 = 1.0f; Renderer.y3 = 0.0f; Renderer.a3 = FLOOR_FADE_ALPHA;
    Renderer.x4 = 1.0f; Renderer.y4 = -1.0f; Renderer.a4 = 0.0f;

    Renderer.drawQuad();

    Renderer.x1 = -1.0f; Renderer.y1 = 0.0f; Renderer.a1 = FLOOR_FADE_ALPHA;
    Renderer.x2 = -1.0f; Renderer.y2 = 1.0f; Renderer.a2 = 0.0f;
    Renderer.x3 = 1.0f; Renderer.y3 = 1.0f; Renderer.a3 = 0.0f;
    Renderer.x4 = 1.0f; Renderer.y4 = 0.0f; Renderer.a4 = FLOOR_FADE_ALPHA;

    Renderer.drawQuad();

    gl.glEnable(GL10.GL_BLEND);
    gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
    Renderer.flush(gl, false);
    gl.glDisable(GL10.GL_BLEND);

    gl.glPopMatrix();
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glPopMatrix();
    gl.glMatrixMode(GL10.GL_MODELVIEW);
  }

  public static void render(GL10 gl, long elapsedTime, float ypos)
  {
    updateDoors(elapsedTime);

    tracer.trace(State.heroX, State.heroY, Common.heroAr, 44.0f * Common.G2RAD_F);
    visibleObjectsCount = 0;

    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();

    gl.glShadeModel(GL10.GL_SMOOTH);
    gl.glDisable(GL10.GL_BLEND);

    gl.glTranslatef(0f, ypos, -0.1f);
    gl.glRotatef(-90f, 1.0f, 0f, 0f);
    gl.glRotatef(90.0f - State.heroA, 0f, 0f, 1.0f);
    gl.glTranslatef(-State.heroX, State.heroY, 0f);

    renderFloor(gl);

    // Walls & Doors

    Renderer.z1 = -HALF_WALL;
    Renderer.z2 = HALF_WALL;
    Renderer.z3 = HALF_WALL;
    Renderer.z4 = -HALF_WALL;

    Renderer.a1 = 1.0f;
    Renderer.a2 = 1.0f;
    Renderer.a3 = 1.0f;
    Renderer.a4 = 1.0f;

    gl.glEnable(GL10.GL_DEPTH_TEST);
    Renderer.bindTexture(gl, TextureLoader.textures[TextureLoader.TEXTURE_MAIN]);

    Renderer.init();
    renderLevel();
    Renderer.flush(gl);

    // Doors

    // disable cull face - it is necessary for doors and transparents, and has no affect on monsters and objects
    gl.glDisable(GL10.GL_CULL_FACE);

    Renderer.init();
    renderDoors();
    Renderer.flush(gl);

    // Monsters, Objects & Transparents

    flatObjDx = (float)Math.cos(- Common.heroAr) * 0.5f;
    flatObjDy = (float)Math.sin(- Common.heroAr) * 0.5f;

    gl.glEnable(GL10.GL_ALPHA_TEST);
    gl.glAlphaFunc(GL10.GL_GREATER, Renderer.ALPHA_VALUE);

    // objects rendered after monsters (so if monster stay in cell with object, monster will be in front)
    // or reverse order, but set appropriate depth test function

    Renderer.bindTexture(gl, TextureLoader.textures[TextureLoader.TEXTURE_MON]);
    Renderer.init();
    renderMonsters(elapsedTime, false);
    Renderer.flush(gl);

    Renderer.bindTexture(gl, TextureLoader.textures[TextureLoader.TEXTURE_MAIN]);
    Renderer.init();
    renderObjects();
    Renderer.flush(gl);

    // dead corpses rendered to be in back

    Renderer.bindTexture(gl, TextureLoader.textures[TextureLoader.TEXTURE_MON]);
    Renderer.init();
    renderMonsters(elapsedTime, true);
    Renderer.flush(gl);

    gl.glDisable(GL10.GL_ALPHA_TEST);
    gl.glEnable(GL10.GL_CULL_FACE);
  }

  public static void renderAutoMap(GL10 gl)
  {
    gl.glDisable(GL10.GL_DEPTH_TEST);

    float autoMapZoom = 20.0f;

    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glPushMatrix();
    Renderer.loadIdentityAndOrthof(gl, -autoMapZoom * Common.ratio, autoMapZoom * Common.ratio, -autoMapZoom, autoMapZoom, 0f, 1.0f);

    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();
    gl.glTranslatef(Config.mapPosition * autoMapZoom, 0f, 0f);

    gl.glRotatef(90.0f - State.heroA, 0f, 0f, 1.0f);
    gl.glTranslatef(-State.heroX, State.heroY, 0f);

    gl.glEnable(GL10.GL_BLEND);
    gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);

    Renderer.init();

    Renderer.a1 = 0.5f;
    Renderer.a2 = Renderer.a1;

    Renderer.b1 = 0.0f;
    Renderer.b2 = 0.0f;

    for (int i = 0; i < State.autoWallsCount; i++)
    {
      AutoWall aw = State.autoWalls[i];

      if (aw.door != null)
      {
        Renderer.r1 = 0.0f;
        Renderer.r2 = 0.0f;
        Renderer.g1 = 1.0f;
        Renderer.g2 = 1.0f;

        float fromX = aw.fromX;
        float fromY = aw.fromY;
        float toX = aw.toX;
        float toY = aw.toY;

        if (aw.vert) {
          fromY += aw.door.openPos;
        } else {
          fromX += aw.door.openPos;
        }

        Renderer.drawLine(fromX, -fromY, toX, -toY);
      }
      else
      {
        if (aw.type == AUTO_WALL_TYPE_WALL)
        {
          Renderer.r1 = 1.0f;
          Renderer.r2 = 1.0f;
          Renderer.g1 = 1.0f;
          Renderer.g2 = 1.0f;
        }
        else
        {
          Renderer.r1 = 0.5f;
          Renderer.r2 = 0.5f;
          Renderer.g1 = 0.5f;
          Renderer.g2 = 0.5f;
        }

        Renderer.drawLine(aw.fromX, -aw.fromY, aw.toX, -aw.toY);
      }
    }

    if (showMonstersOnMap)
    {
      Renderer.g1 = 0.0f;
      Renderer.g2 = 0.0f;

      for (int i = 0; i < State.monstersCount; i++)
      {
        Monster mon = State.monsters[i];

        if (mon.health <= 0)
        {
          Renderer.r1 = 0.5f; Renderer.b1 = 0.5f;
          Renderer.r2 = 0.5f; Renderer.b2 = 0.5f;
        }
        else if (mon.chaseMode)
        {
          Renderer.r1 = 1.0f; Renderer.b1 = 0.0f;
          Renderer.r2 = 1.0f; Renderer.b2 = 0.0f;
        }
        else
        {
          Renderer.r1 = 0.0f; Renderer.b1 = 1.0f;
          Renderer.r2 = 0.0f; Renderer.b2 = 1.0f;
        }

        float mdx = (float)Math.cos((float)mon.shootAngle * Common.G2RAD_F) * 0.75f;
        float mdy = (float)Math.sin((float)mon.shootAngle * Common.G2RAD_F) * 0.75f;

        Renderer.drawLine(mon.x, -mon.y, mon.x+mdx, -mon.y+mdy);

        mdx *= 0.25;
        mdy *= 0.25;

        Renderer.drawLine(mon.x+mdy, -mon.y-mdx, mon.x-mdy, -mon.y+mdx);
      }
    }

    Renderer.flush(gl, false);

    gl.glLoadIdentity();
    gl.glTranslatef(Config.mapPosition * autoMapZoom, 0f, 0f);
    Renderer.init();

    Renderer.r1 = 1.0f; Renderer.g1 = 1.0f; Renderer.b1 = 1.0f;
    Renderer.r2 = 1.0f; Renderer.g2 = 1.0f; Renderer.b2 = 1.0f;

    Renderer.drawLine(-0.25f, -0.25f, 0.0f, 0.25f);
    Renderer.drawLine(0.0f, 0.25f, 0.25f, -0.25f);

    Renderer.flush(gl, false);

    gl.glDisable(GL10.GL_BLEND);
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glPopMatrix();
  }

  public static void surfaceSizeChanged(GL10 gl)
  {
    gl.glMatrixMode(GL10.GL_PROJECTION);

    float size = 0.1f * (float)Math.tan(Math.toRadians(50.0) / 2);
    Renderer.loadIdentityAndFrustumf(gl, -size, size, -size / Common.ratio, size / Common.ratio, 0.1f, 100.0f);

    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
  }
}




Java Source Code List

zame.game.AppConfig.java
zame.game.AppConfig.java
zame.game.Common.java
zame.game.ConfigZeemote.java
zame.game.ConfigZeemote.java
zame.game.Config.java
zame.game.GameActivityZeemoteHelper.java
zame.game.GameActivityZeemoteHelper.java
zame.game.GameActivity.java
zame.game.GamePreferencesActivity.java
zame.game.GamePreferencesActivity.java
zame.game.MenuActivityHelper.java
zame.game.MenuActivityHelper.java
zame.game.MenuActivity.java
zame.game.Renderer.java
zame.game.SoundManager.java
zame.game.ZameApplicationAnalyticsHelper.java
zame.game.ZameApplicationAnalyticsHelper.java
zame.game.ZameApplication.java
zame.game.ZameGame.java
zame.game.ZameJniRenderer.java
zame.game.engine.Action.java
zame.game.engine.AutoWall.java
zame.game.engine.Controls.java
zame.game.engine.Door.java
zame.game.engine.GameHelper.java
zame.game.engine.GameHelper.java
zame.game.engine.Game.java
zame.game.engine.Labels.java
zame.game.engine.LevelConfig.java
zame.game.engine.LevelRenderer.java
zame.game.engine.Level.java
zame.game.engine.Mark.java
zame.game.engine.Monster.java
zame.game.engine.Overlay.java
zame.game.engine.PortalTracer.java
zame.game.engine.State.java
zame.game.engine.Stats.java
zame.game.engine.TextureLoader.java
zame.game.engine.Weapons.java
zame.game.views.EndLevelView.java
zame.game.views.GameOverView.java
zame.game.views.GameView.java
zame.game.views.IZameView.java
zame.game.views.MenuViewHelper.java
zame.game.views.MenuViewHelper.java
zame.game.views.MenuView.java
zame.game.views.PreLevelView.java
zame.game.views.ZameGameView.java
zame.libs.FrameLayout.java
zame.libs.GLSurfaceView21.java
zame.libs.Grid.java
zame.libs.KeyMapPreference.java
zame.libs.LabelMaker.java
zame.libs.ListPreference.java
zame.libs.NumericSprite.java
zame.libs.SeekBarPreference.java
zame.promo.PromoView.java