Package mapwriter.map

Source Code of mapwriter.map.MapRenderer

package mapwriter.map;

import java.awt.Point;
import java.util.ArrayList;

import mapwriter.Mw;
import mapwriter.Render;
import mapwriter.api.IMwChunkOverlay;
import mapwriter.api.IMwDataProvider;
import mapwriter.api.MwAPI;
import mapwriter.map.mapmode.MapMode;
import net.minecraft.util.ResourceLocation;

import org.lwjgl.opengl.GL11;

public class MapRenderer {
  private Mw mw;
  private MapMode mapMode;
  private MapView mapView;
  // accessed by the MwGui to check whether the mouse cursor is near the
  // player arrow on the rendered map
  public Point.Double playerArrowScreenPos = new Point.Double(0, 0);
  
  private ResourceLocation backgroundTexture = new ResourceLocation("mapwriter", "textures/map/background.png");
  private ResourceLocation roundMapTexture = new ResourceLocation("mapwriter", "textures/map/border_round.png");
  private ResourceLocation squareMapTexture = new ResourceLocation("mapwriter", "textures/map/border_square.png");
  private ResourceLocation playerArrowTexture = new ResourceLocation("mapwriter", "textures/map/arrow_player.png");
  private ResourceLocation northArrowTexture = new ResourceLocation("mapwriter", "textures/map/arrow_north.png");
 
  public MapRenderer(Mw mw, MapMode mapMode, MapView mapView) {
    this.mw = mw;
    this.mapMode = mapMode;
    this.mapView = mapView;
  }
 
  private void drawMap() {
   
    int regionZoomLevel = Math.max(0, this.mapView.getZoomLevel());
    double tSize = (double) this.mw.textureSize;
    double zoomScale = (double) (1 << regionZoomLevel);
   
    // if the texture UV coordinates do not line up with the texture pixels then the texture
    // will look blurry when it is drawn to the screen.
    // to fix this we round the texture coordinates to the nearest pixel boundary.
    // this is unnecessary when zoomed in as the texture will be upscaled and look blurry
    // anyway, so it is disabled in this case.
    // also the rounding causes the map to noticeably (and unpleasantly) 'snap' to texture
    // pixel boundaries when zoomed in.
   
    double u, v, w, h;
    if ((!this.mapMode.circular) && (this.mw.mapPixelSnapEnabled) && (this.mapView.getZoomLevel() >= 0)) {
      u = (Math.round(this.mapView.getMinX() / zoomScale) / tSize) % 1.0;
      v = (Math.round(this.mapView.getMinZ() / zoomScale) / tSize) % 1.0;
      w = Math.round(this.mapView.getWidth() / zoomScale) / tSize;
      h = Math.round(this.mapView.getHeight() / zoomScale) / tSize;
    } else {
      double tSizeInBlocks = tSize * zoomScale;
      u = (this.mapView.getMinX() / tSizeInBlocks) % 1.0;
      v = (this.mapView.getMinZ() / tSizeInBlocks) % 1.0;
      w = (this.mapView.getWidth() / tSizeInBlocks);
      h = (this.mapView.getHeight() / tSizeInBlocks);
    }
   
    GL11.glPushMatrix();
   
    if (this.mapMode.rotate) {
      GL11.glRotated(this.mw.mapRotationDegrees, 0.0f, 0.0f, 1.0f);
    }
    if (this.mapMode.circular) {
      Render.setCircularStencil(0, 0, this.mapMode.h / 2.0);
    }
   
    if ((this.mapView.getUndergroundMode()) && (regionZoomLevel == 0)) {
      // draw the underground map
      this.mw.undergroundMapTexture.requestView(this.mapView);
      // underground map needs to have a black background
      Render.setColourWithAlphaPercent(0x000000, this.mapMode.alphaPercent);
      Render.drawRect(this.mapMode.x, this.mapMode.y, this.mapMode.w, this.mapMode.h);
      Render.setColourWithAlphaPercent(0xffffff, this.mapMode.alphaPercent);
      this.mw.undergroundMapTexture.bind();
      Render.drawTexturedRect(
          this.mapMode.x, this.mapMode.y, this.mapMode.w, this.mapMode.h,
          u, v, u + w, v + h
      );
    } else {
      // draw the surface map
      MapViewRequest req = new MapViewRequest(this.mapView);
      this.mw.mapTexture.requestView(req, this.mw.executor, this.mw.regionManager);
     
      // draw the background texture
      if (this.mw.backgroundTextureMode > 0) {
        double bu1 = 0.0; double bu2 = 1.0;
        double bv1 = 0.0; double bv2 = 1.0;
        if (this.mw.backgroundTextureMode == 2) {
          // background moves with map if mode is 2
          double bSize = tSize / 256.0;
          bu1 = u * bSize; bu2 = (u + w) * bSize;
          bv1 = v * bSize; bv2 = (v + h) * bSize;
        }
        this.mw.mc.renderEngine.bindTexture(this.backgroundTexture);
        Render.setColourWithAlphaPercent(0xffffff, this.mapMode.alphaPercent);
        Render.drawTexturedRect(
            this.mapMode.x, this.mapMode.y, this.mapMode.w, this.mapMode.h,
            bu1, bv1, bu2, bv2
        );
      } else {
        // mode 0, no background texture
        Render.setColourWithAlphaPercent(0x000000, this.mapMode.alphaPercent);
        Render.drawRect(this.mapMode.x, this.mapMode.y, this.mapMode.w, this.mapMode.h);
      }
     
      // only draw surface map if the request is loaded (view requests are
      // loaded by the background thread)
      if (this.mw.mapTexture.isLoaded(req)) {
        this.mw.mapTexture.bind();
        Render.setColourWithAlphaPercent(0xffffff, this.mapMode.alphaPercent);
        Render.drawTexturedRect(
            this.mapMode.x, this.mapMode.y, this.mapMode.w, this.mapMode.h,
            u, v, u + w, v + h
        );
      }
    }
   
    // draw ProfMobius chunk overlay
    IMwDataProvider provider = this.drawOverlay();
   
    // overlay onDraw event
    if (provider != null) {
      GL11.glPushMatrix();     
      provider.onDraw(this.mapView, this.mapMode);
      GL11.glPopMatrix();     
    }
   
    if (this.mapMode.circular) {
      Render.disableStencil();
    }
   
    GL11.glPopMatrix();
  }
 
  private void drawBorder() {
    if (this.mapMode.circular) {
      this.mw.mc.renderEngine.bindTexture(this.roundMapTexture);
    } else {
      this.mw.mc.renderEngine.bindTexture(this.squareMapTexture);
    }
    Render.setColour(0xffffffff);
    Render.drawTexturedRect(
      this.mapMode.x / 0.75, this.mapMode.y / 0.75,
      this.mapMode.w / 0.75, this.mapMode.h / 0.75,
      0.0, 0.0, 1.0, 1.0
    );
  }
 
  private void drawPlayerArrow() {
    GL11.glPushMatrix();
    double scale = this.mapView.getDimensionScaling(this.mw.playerDimension);
    Point.Double p = this.mapMode.getClampedScreenXY(this.mapView, this.mw.playerX * scale, this.mw.playerZ * scale);
    this.playerArrowScreenPos.setLocation(p.x + this.mapMode.xTranslation, p.y + this.mapMode.yTranslation);
   
    // the arrow only needs to be rotated if the map is NOT rotated
    GL11.glTranslated(p.x, p.y, 0.0);
    if (!this.mapMode.rotate) {
      GL11.glRotated(-this.mw.mapRotationDegrees, 0.0f, 0.0f, 1.0f);
    }
   
    double arrowSize = this.mapMode.playerArrowSize;
    Render.setColour(0xffffffff);
    this.mw.mc.renderEngine.bindTexture(this.playerArrowTexture);
    Render.drawTexturedRect(
      -arrowSize, -arrowSize, arrowSize * 2, arrowSize * 2,
      0.0, 0.0, 1.0, 1.0
    );
    GL11.glPopMatrix();
  }
 
  private void drawIcons() {
    GL11.glPushMatrix();
   
    if (this.mapMode.rotate) {
      GL11.glRotated(this.mw.mapRotationDegrees, 0.0f, 0.0f, 1.0f);
    }
   
    // draw markers
    this.mw.markerManager.drawMarkers(this.mapMode, this.mapView);
   
    // draw player trail
    if (this.mw.playerTrail.enabled) {
      this.mw.playerTrail.draw(this.mapMode, this.mapView);
    }
   
    // draw north arrow
    if (this.mapMode.rotate) {
      double y = this.mapMode.h / 2.0;
      double arrowSize = this.mapMode.playerArrowSize;
      Render.setColour(0xffffffff);
      this.mw.mc.renderEngine.bindTexture(this.northArrowTexture);
      Render.drawTexturedRect(
        -arrowSize, -y - (arrowSize * 2), arrowSize * 2, arrowSize * 2,
        0.0, 0.0, 1.0, 1.0
      );
    }
   
    GL11.glPopMatrix();
   
    // outside of the matrix pop as theplayer arrow
    // needs to be drawn without rotation
    this.drawPlayerArrow();
  }
 
  private void drawCoords() {
    // draw coordinates
    if (this.mapMode.coordsEnabled) {
      GL11.glPushMatrix();
      GL11.glTranslatef(this.mapMode.textX, this.mapMode.textY, 0);
      if (this.mw.coordsMode != 2) {
        GL11.glScalef(0.5f, 0.5f, 1.0f);
      }
      int offset = 0;
      if (this.mw.coordsMode > 0) {
        Render.drawCentredString(0, 0, this.mapMode.textColour,
            "%d, %d, %d",
            this.mw.playerXInt,
            this.mw.playerYInt,
            this.mw.playerZInt
        );
        offset += 12;
      }
      if (this.mw.undergroundMode) {
        Render.drawCentredString(
          0, offset, this.mapMode.textColour,"underground mode"
        );
      }
      GL11.glPopMatrix();
    }
  }
 
  private IMwDataProvider drawOverlay() {
    // draw overlays from registered providers
        //for (IMwDataProvider provider : MwAPI.getDataProviders())
    IMwDataProvider provider = MwAPI.getCurrentDataProvider();
    if (provider != null) {
      ArrayList<IMwChunkOverlay> overlays = provider.getChunksOverlay(
          this.mapView.getDimension(),
          this.mapView.getX(), this.mapView.getZ(),
          this.mapView.getMinX(), this.mapView.getMinZ(),
          this.mapView.getMaxX(), this.mapView.getMaxZ()
      );
      if (overlays != null) {
            for (IMwChunkOverlay overlay : overlays) {
              paintChunk(this.mapMode, this.mapView, overlay);
            }
      }
    }
    return provider;
  }
 
  public void draw() {
   
    this.mapMode.setScreenRes();
    this.mapView.setMapWH(this.mapMode);
    this.mapView.setTextureSize(this.mw.textureSize);
   
    GL11.glPushMatrix();
    GL11.glLoadIdentity();
   
    // translate to center of minimap
    // z is -2000 so that it is drawn above the 3D world, but below GUI
    // elements which are typically at -3000
    GL11.glTranslated(this.mapMode.xTranslation, this.mapMode.yTranslation, -2000.0);
   
    // draw background, the map texture, and enabled overlays
    this.drawMap();
   
    if (this.mapMode.borderMode > 0) {
      this.drawBorder();
    }
    this.drawIcons();
   
    this.drawCoords();
   
    // some shader mods seem to need depth testing re-enabled
    GL11.glEnable(GL11.GL_DEPTH_TEST);
    GL11.glPopMatrix();
  }
 
  private static void paintChunk(MapMode mapMode, MapView mapView, IMwChunkOverlay overlay){
    int chunkX    = overlay.getCoordinates().x;
    int chunkZ    = overlay.getCoordinates().y;
    float filling = overlay.getFilling();
   
    Point.Double topCorner = mapMode.blockXZtoScreenXY(mapView, chunkX << 4, chunkZ << 4);
    Point.Double botCorner = mapMode.blockXZtoScreenXY(mapView, (chunkX + 1) << 4, (chunkZ + 1 << 4));

    topCorner.x = Math.max(mapMode.x,             topCorner.x);
    topCorner.x = Math.min(mapMode.x + mapMode.w, topCorner.x);
    topCorner.y = Math.max(mapMode.y,             topCorner.y);
    topCorner.y = Math.min(mapMode.y + mapMode.h, topCorner.y);
   
    botCorner.x = Math.max(mapMode.x,             botCorner.x);
    botCorner.x = Math.min(mapMode.x + mapMode.w, botCorner.x);
    botCorner.y = Math.max(mapMode.y,             botCorner.y);
    botCorner.y = Math.min(mapMode.y + mapMode.h, botCorner.y);   

    double sizeX = (botCorner.x - topCorner.x) * filling;
    double sizeY = (botCorner.y - topCorner.y) * filling;   
    double offsetX = ((botCorner.x - topCorner.x) - sizeX) / 2;
    double offsetY = ((botCorner.y - topCorner.y) - sizeY) / 2
   
    if (overlay.hasBorder()) {
      Render.setColour(overlay.getBorderColor());
      Render.drawRectBorder(topCorner.x + 1, topCorner.y + 1, botCorner.x - topCorner.x - 1, botCorner.y - topCorner.y - 1, overlay.getBorderWidth());
    }
   
    Render.setColour(overlay.getColor());
    Render.drawRect(topCorner.x + offsetX + 1, topCorner.y + offsetY + 1, sizeX - 1, sizeY - 1);
  }
}
TOP

Related Classes of mapwriter.map.MapRenderer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.