예제 #1
0
  /** @see Font#drawString(float, float, String, Color, int, int) */
  public void drawString(float x, float y, String text, Color col, int startIndex, int endIndex) {
    fontImage.bind();
    col.bind();

    GL.glTranslatef(x, y, 0);
    if (displayListCaching && startIndex == 0 && endIndex == text.length() - 1) {
      DisplayList displayList =
          (DisplayList) displayLists.get(text + "" + startIndex + "" + endIndex);
      if (displayList != null) {
        GL.glCallList(displayList.id);
      } else {
        // Compile a new display list.
        displayList = new DisplayList();
        displayList.text = text;
        int displayListCount = displayLists.size();
        if (displayListCount < DISPLAY_LIST_CACHE_SIZE) {
          displayList.id = baseDisplayListID + displayListCount;
        } else {
          displayList.id = eldestDisplayListID;
          displayLists.remove(eldestDisplayList.text);
        }

        displayLists.put(text + "" + startIndex + "" + endIndex, displayList);

        GL.glNewList(displayList.id, SGL.GL_COMPILE_AND_EXECUTE);
        render(text, startIndex, endIndex);
        GL.glEndList();
      }
    } else {
      render(text, startIndex, endIndex);
    }
    GL.glTranslatef(-x, -y, 0);
  }
예제 #2
0
  /**
   * Render based on immediate rendering
   *
   * @param text The text to be rendered
   * @param start The index of the first character in the string to render
   * @param end The index of the last character in the string to render
   */
  private void render(String text, int start, int end) {
    GL.glBegin(SGL.GL_QUADS);

    int x = 0, y = 0;
    CharDef lastCharDef = null;
    char[] data = text.toCharArray();
    for (int i = 0; i < data.length; i++) {
      int id = data[i];
      if (id == '\n') {
        x = 0;
        y += getLineHeight();
        continue;
      }
      if (id >= chars.length) {
        continue;
      }
      CharDef charDef = chars[id];
      if (charDef == null) {
        continue;
      }

      if (lastCharDef != null) x += lastCharDef.getKerning(id);
      lastCharDef = charDef;

      if ((i >= start) && (i <= end)) {
        charDef.draw(x, y);
      }

      x += charDef.xadvance;
    }
    GL.glEnd();
  }
예제 #3
0
  public void setBlendMode(int mode) {
    oldBlendMode = blendMode;
    blendMode = mode;

    GL14.glBlendEquation(GL14.GL_FUNC_ADD);
    if (mode < 100) {
      g.setDrawMode(mode);
      return;
    }

    try {
      Reflection.invokePrivateMethod(mPredraw, g);
    } catch (Exception e) {
      App.getApp().handle(e);
    }
    gl.glEnable(SGL.GL_BLEND);
    gl.glColorMask(true, true, true, true);

    if (mode == BM_ADD || mode == BM_SUBTRACT) {
      gl.glBlendFunc(SGL.GL_SRC_ALPHA, SGL.GL_ONE);
      if (mode == BM_SUBTRACT) {
        GL14.glBlendEquation(GL14.GL_FUNC_SUBTRACT);
        GL14.glBlendEquation(GL14.GL_FUNC_REVERSE_SUBTRACT);
      }
    }

    try {
      Reflection.invokePrivateMethod(mPostdraw, g);
    } catch (Exception e) {
      App.getApp().handle(e);
    }
  }
  /**
   * Draw the outline of the given shape. Only the vertices are set. The colour has to be set
   * independently of this method.
   *
   * @param shape The shape to draw.
   * @param fill The fill to apply
   */
  public static final void draw(Shape shape, ShapeFill fill) {
    float points[] = shape.getPoints();

    Texture t = TextureImpl.getLastBind();
    TextureImpl.bindNone();

    float center[] = shape.getCenter();
    GL.glBegin(SGL.GL_LINE_STRIP);
    for (int i = 0; i < points.length; i += 2) {
      fill.colorAt(shape, points[i], points[i + 1]).bind();
      Vector2f offset = fill.getOffsetAt(shape, points[i], points[i + 1]);
      GL.glVertex2f(points[i] + offset.x, points[i + 1] + offset.y);
    }

    if (shape.closed()) {
      fill.colorAt(shape, points[0], points[1]).bind();
      Vector2f offset = fill.getOffsetAt(shape, points[0], points[1]);
      GL.glVertex2f(points[0] + offset.x, points[1] + offset.y);
    }
    GL.glEnd();

    if (t == null) {
      TextureImpl.bindNone();
    } else {
      t.bind();
    }
  }
예제 #5
0
 /**
  * Uploads the pixel data to the given texture at the specified position. This only needs to be
  * called once, after the pixel data has changed.
  *
  * @param texture the texture to modify
  * @param x the x position to place the pixel data on the texture
  * @param y the y position to place the pixel data on the texture
  */
 public void apply(Texture texture, int x, int y) {
   if (x + width > texture.getTextureWidth() || y + height > texture.getTextureHeight())
     throw new IndexOutOfBoundsException("pixel data won't fit in given texture");
   position(length());
   pixels.flip();
   int glFmt = format.getOGLType();
   final SGL GL = Renderer.get();
   texture.bind();
   GL.glTexSubImage2D(
       SGL.GL_TEXTURE_2D, 0, x, y, width, height, glFmt, SGL.GL_UNSIGNED_BYTE, pixels);
 }
  /**
   * Draw the the given shape filled in. Only the vertices are set. The colour has to be set
   * independently of this method.
   *
   * @param shape The shape to fill.
   * @param callback The callback that will be invoked for each shape point
   */
  private static final void fill(Shape shape, PointCallback callback) {
    Triangulator tris = shape.getTriangles();

    GL.glBegin(SGL.GL_TRIANGLES);
    for (int i = 0; i < tris.getTriangleCount(); i++) {
      for (int p = 0; p < 3; p++) {
        float[] pt = tris.getTrianglePoint(i, p);
        float[] np = callback.preRenderPoint(shape, pt[0], pt[1]);

        if (np == null) {
          GL.glVertex2f(pt[0], pt[1]);
        } else {
          GL.glVertex2f(np[0], np[1]);
        }
      }
    }
    GL.glEnd();
  }
예제 #7
0
  public void resetAnimState() {
    if (stateNew == null) return;

    if (stateNew.scaleH != 1 || stateNew.scaleV != 1) g.scale(stateNew.scaleH, stateNew.scaleV);
    if (stateNew.angle != 0) gl.glRotatef(stateNew.angle, 0f, 0f, 1f);
    if (stateNew.pos.x != 0 || stateNew.pos.y != 0) g.translate(stateNew.pos.x, stateNew.pos.y);
    Color.white.bind();
    g.setColor(stateColor);

    stateNew = null;
  }
예제 #8
0
  public void setAnimState(AnimState state) {
    if (state != null) resetAnimState();

    getPrivates();
    stateColor = g.getColor();
    stateNew = new AnimState(state);

    g.setColor(state.color);
    state.color.bind();
    if (state.pos.x != 0 || state.pos.y != 0) g.translate(-state.pos.x, -state.pos.y);
    if (state.angle != 0) gl.glRotatef(-state.angle, 0f, 0f, 1f);
    if (state.scaleH != 1 || state.scaleV != 1) g.scale(1f / state.scaleH, 1f / state.scaleV);
  }
예제 #9
0
  /**
   * @see org.newdawn.slick.Game#render(org.newdawn.slick.GameContainer, org.newdawn.slick.Graphics)
   */
  public final void render(GameContainer container, Graphics g) throws SlickException {
    int yoffset = 0;
    int xoffset = 0;

    if (targetHeight < container.getHeight()) {
      yoffset = (container.getHeight() - targetHeight) / 2;
    }
    if (targetWidth < container.getWidth()) {
      xoffset = (container.getWidth() - targetWidth) / 2;
    }

    SlickCallable.enterSafeBlock();
    g.setClip(xoffset, yoffset, targetWidth, targetHeight);
    GL.glTranslatef(xoffset, yoffset, 0);
    g.scale(targetWidth / normalWidth, targetHeight / normalHeight);
    GL.glPushMatrix();
    held.render(container, g);
    GL.glPopMatrix();
    g.clearClip();
    SlickCallable.leaveSafeBlock();

    renderOverlay(container, g);
  }
예제 #10
0
  public void drawRectangleGradient(
      Vector2f p1,
      Vector2f p2,
      Color topLeft,
      Color topRight,
      Color bottomLeft,
      Color bottomRight) {
    getPrivates();

    try {
      Reflection.invokePrivateMethod(mPredraw, g);
    } catch (Exception e) {
      App.getApp().handle(e);
    }
    TextureImpl.bindNone();
    Color.white.bind();
    GL11.glBegin(GL11.GL_POLYGON);
    Color c;
    c = topLeft;
    gl.glColor4f(c.r, c.g, c.b, c.a);
    gl.glVertex2f(p1.x, p1.y);
    c = topRight;
    gl.glColor4f(c.r, c.g, c.b, c.a);
    gl.glVertex2f(p2.x, p1.y);
    c = bottomRight;
    gl.glColor4f(c.r, c.g, c.b, c.a);
    gl.glVertex2f(p2.x, p2.y);
    c = bottomLeft;
    gl.glColor4f(c.r, c.g, c.b, c.a);
    gl.glVertex2f(p1.x, p2.y);
    gl.glEnd();
    try {
      Reflection.invokePrivateMethod(mPostdraw, g);
    } catch (Exception e) {
      App.getApp().handle(e);
    }
  }
  /** Initialise the GL context */
  protected void initGL() {
    Log.info("Starting display " + width + "x" + height);
    GL.initDisplay(width, height);

    if (input == null) {
      input = new Input(height);
    }
    input.init(height);
    // no need to remove listeners?
    // input.removeAllListeners();
    if (game instanceof InputListener) {
      input.removeListener((InputListener) game);
      input.addListener((InputListener) game);
    }

    if (graphics != null) {
      graphics.setDimensions(getWidth(), getHeight());
    }
    lastGame = game;
  }
예제 #12
0
  public void drawTriangle(Vector2f p1, Vector2f p2, Vector2f p3, Color c1, Color c2, Color c3) {
    getPrivates();

    try {
      Reflection.invokePrivateMethod(mPredraw, g);
    } catch (Exception e) {
      App.getApp().handle(e);
    }
    TextureImpl.bindNone();
    Color.white.bind();
    gl.glBegin(SGL.GL_TRIANGLES);
    gl.glColor4f(c1.r, c1.g, c1.b, c1.a);
    gl.glVertex2f(p1.x, p1.y);
    gl.glColor4f(c2.r, c2.g, c2.b, c2.a);
    gl.glVertex2f(p2.x, p2.y);
    gl.glColor4f(c3.r, c3.g, c3.b, c3.a);
    gl.glVertex2f(p3.x, p3.y);
    gl.glEnd();
    try {
      Reflection.invokePrivateMethod(mPostdraw, g);
    } catch (Exception e) {
      App.getApp().handle(e);
    }
  }
예제 #13
0
  /**
   * Render the particles in the system
   *
   * @param x The x coordinate to render the particle system at (in the current coordinate space)
   * @param y The y coordinate to render the particle system at (in the current coordiante space)
   */
  public void render(float x, float y) {
    if ((sprite == null) && (defaultImageName != null)) {
      loadSystemParticleImage();
    }

    if (!visible) {
      return;
    }

    GL.glTranslatef(x, y, 0);

    if (blendingMode == BLEND_ADDITIVE) {
      GL.glBlendFunc(SGL.GL_SRC_ALPHA, SGL.GL_ONE);
    }
    if (usePoints()) {
      GL.glEnable(SGL.GL_POINT_SMOOTH);
      TextureImpl.bindNone();
    }

    // iterate over all emitters
    for (int emitterIdx = 0; emitterIdx < emitters.size(); emitterIdx++) {
      // get emitter
      ParticleEmitter emitter = (ParticleEmitter) emitters.get(emitterIdx);

      // check for additive override and enable when set
      if (emitter.useAdditive()) {
        GL.glBlendFunc(SGL.GL_SRC_ALPHA, SGL.GL_ONE);
      }

      // now get the particle pool for this emitter and render all particles that are in use
      ParticlePool pool = (ParticlePool) particlesByEmitter.get(emitter);
      Image image = emitter.getImage();
      if (image == null) {
        image = this.sprite;
      }

      if (!emitter.isOriented() && !emitter.usePoints(this)) {
        image.startUse();
      }

      for (int i = 0; i < pool.particles.length; i++) {
        if (pool.particles[i].inUse()) pool.particles[i].render();
      }

      if (!emitter.isOriented() && !emitter.usePoints(this)) {
        image.endUse();
      }

      // reset additive blend mode
      if (emitter.useAdditive()) {
        GL.glBlendFunc(SGL.GL_SRC_ALPHA, SGL.GL_ONE_MINUS_SRC_ALPHA);
      }
    }

    if (usePoints()) {
      GL.glDisable(SGL.GL_POINT_SMOOTH);
    }
    if (blendingMode == BLEND_ADDITIVE) {
      GL.glBlendFunc(SGL.GL_SRC_ALPHA, SGL.GL_ONE_MINUS_SRC_ALPHA);
    }

    Color.white.bind();
    GL.glTranslatef(-x, -y, 0);
  }
예제 #14
0
  /**
   * Parse the font definition file
   *
   * @param fntFile The stream from which the font file can be read
   * @throws SlickException
   */
  private void parseFnt(InputStream fntFile) throws SlickException {
    if (displayListCaching) {
      baseDisplayListID = GL.glGenLists(DISPLAY_LIST_CACHE_SIZE);
      if (baseDisplayListID == 0) displayListCaching = false;
    }

    try {
      // now parse the font file
      BufferedReader in = new BufferedReader(new InputStreamReader(fntFile));
      String info = in.readLine();
      String common = in.readLine();
      String page = in.readLine();

      Map kerning = new HashMap(64);
      List charDefs = new ArrayList(MAX_CHAR);
      int maxChar = 0;
      boolean done = false;
      while (!done) {
        String line = in.readLine();
        if (line == null) {
          done = true;
        } else {
          if (line.startsWith("chars c")) {
            // ignore
          } else if (line.startsWith("char")) {
            CharDef def = parseChar(line);
            if (def != null) {
              maxChar = Math.max(maxChar, def.id);
              charDefs.add(def);
            }
          }
          if (line.startsWith("kernings c")) {
            // ignore
          } else if (line.startsWith("kerning")) {
            StringTokenizer tokens = new StringTokenizer(line, " =");
            tokens.nextToken(); // kerning
            tokens.nextToken(); // first
            short first = Short.parseShort(tokens.nextToken()); // first value
            tokens.nextToken(); // second
            int second = Integer.parseInt(tokens.nextToken()); // second value
            tokens.nextToken(); // offset
            int offset = Integer.parseInt(tokens.nextToken()); // offset value
            List values = (List) kerning.get(new Short(first));
            if (values == null) {
              values = new ArrayList();
              kerning.put(new Short(first), values);
            }
            // Pack the character and kerning offset into a short.
            values.add(new Short((short) ((offset << 8) | second)));
          }
        }
      }

      chars = new CharDef[maxChar + 1];
      for (Iterator iter = charDefs.iterator(); iter.hasNext(); ) {
        CharDef def = (CharDef) iter.next();
        chars[def.id] = def;
      }

      // Turn each list of kerning values into a short[] and set on the chardef.
      for (Iterator iter = kerning.entrySet().iterator(); iter.hasNext(); ) {
        Entry entry = (Entry) iter.next();
        short first = ((Short) entry.getKey()).shortValue();
        List valueList = (List) entry.getValue();
        short[] valueArray = new short[valueList.size()];
        int i = 0;
        for (Iterator valueIter = valueList.iterator(); valueIter.hasNext(); i++)
          valueArray[i] = ((Short) valueIter.next()).shortValue();
        chars[first].kerning = valueArray;
      }
    } catch (IOException e) {
      Log.error(e);
      throw new SlickException("Failed to parse font file: " + fntFile);
    }
  }
 /**
  * Enter the orthographic mode
  *
  * @param xsize The size of the panel being used
  * @param ysize The size of the panel being used
  */
 protected void enterOrtho(int xsize, int ysize) {
   GL.enterOrtho(xsize, ysize);
 }
  /**
   * Update and render the game
   *
   * @param delta The change in time since last update and render
   * @throws SlickException Indicates an internal fault to the game.
   */
  protected void updateAndRender(int delta) throws SlickException {
    if (smoothDeltas) {
      if (getFPS() != 0) {
        delta = 1000 / getFPS();
      }
    }

    input.poll(width, height);

    Music.poll(delta);
    if (!paused) {
      storedDelta += delta;

      if (storedDelta >= minimumLogicInterval) {
        try {
          if (maximumLogicInterval != 0) {
            long cycles = storedDelta / maximumLogicInterval;
            for (int i = 0; i < cycles; i++) {
              game.update(this, (int) maximumLogicInterval);
            }

            int remainder = (int) (storedDelta % maximumLogicInterval);
            if (remainder > minimumLogicInterval) {
              game.update(this, (int) (remainder % maximumLogicInterval));
              storedDelta = 0;
            } else {
              storedDelta = remainder;
            }
          } else {
            game.update(this, (int) storedDelta);
            storedDelta = 0;
          }

        } catch (Throwable e) {
          //					Log.error(e);
          throw new SlickException("Game.update() failure.", e);
        }
      }
    } else {
      game.update(this, 0);
    }

    if (hasFocus() || getAlwaysRender()) {
      if (clearEachFrame) {
        GL.glClear(SGL.GL_COLOR_BUFFER_BIT | SGL.GL_DEPTH_BUFFER_BIT);
      }

      GL.glLoadIdentity();

      graphics.resetTransform();
      graphics.resetFont();
      graphics.resetLineWidth();
      graphics.setAntiAlias(false);
      try {
        game.render(this, graphics);
      } catch (Throwable e) {
        //				Log.error(e);
        throw new SlickException("Game.render() failure.", e);
      }
      graphics.resetTransform();

      if (showFPS) {
        defaultFont.drawString(10, 10, "FPS: " + recordedFPS);
      }

      GL.flush();
    }

    if (targetFPS != -1) {
      Display.sync(targetFPS);
    }
  }