All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.lessvoid.textureatlas.CoreTextureAtlasGenerator Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (c) 2013, Jens Hohmuth
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
package de.lessvoid.textureatlas;

import java.nio.FloatBuffer;

import de.lessvoid.coregl.ColorFormat;
import de.lessvoid.coregl.CoreFBO;
import de.lessvoid.coregl.CoreRender;
import de.lessvoid.coregl.CoreShader;
import de.lessvoid.coregl.CoreTexture2D;
import de.lessvoid.coregl.CoreVAO;
import de.lessvoid.coregl.CoreVAO.FloatType;
import de.lessvoid.coregl.CoreVBO;
import de.lessvoid.coregl.CoreVBO.DataType;
import de.lessvoid.coregl.CoreVBO.UsageType;
import de.lessvoid.coregl.ResizeFilter;
import de.lessvoid.coregl.Type;
import de.lessvoid.coregl.spi.CoreGL;
import de.lessvoid.math.MatrixFactory;
import de.lessvoid.textureatlas.TextureAtlasGenerator.Result;

/**
 * This uses de.lessvoid.textureatlas.TextureAtlasGenerator while rendering
 * individual CoreTextures into a CoreRenderToTexture target.
 *
 * @author void
 */
public class CoreTextureAtlasGenerator {
  private final CoreRender coreRender;
  private final CoreFBO renderToTexture;
  private final CoreVAO vao;
  private final CoreVBO vbo;
  private final TextureAtlasGenerator generator;
  private final CoreShader shader;
  private final CoreTexture2D texture;

  /**
   * Prepare a RenderToTexture target of the given width x height that will be
   * used as the rendering target for the texture atlas algorithm.
   *
   * @param width
   *          width of the texture
   * @param height
   *          height of the texture
   */
  public CoreTextureAtlasGenerator(final CoreGL gl, final int width, final int height) {
    coreRender = CoreRender.createCoreRender(gl);

    renderToTexture = CoreFBO.createCoreFBO(gl);
    renderToTexture.bindFramebuffer();

    texture = CoreTexture2D
        .createEmptyTexture(gl, ColorFormat.RGBA, Type.UNSIGNED_BYTE, width, height, ResizeFilter.Linear);
    renderToTexture.attachTexture(texture.getTextureId(), 0);

    shader = CoreShader.createShaderWithVertexAttributes(gl, "aVertex", "aUV");
    shader.vertexShader("de/lessvoid/coregl/plain-texture.vs");
    shader.fragmentShader("de/lessvoid/coregl/plain-texture.fs");
    shader.link();
    shader.activate();
    shader.setUniformi("uTexture", 0);

    vao = CoreVAO.createCoreVAO(gl);
    vao.bind();

    vbo = CoreVBO.createCoreVBO(gl, DataType.FLOAT, UsageType.STREAM_DRAW, 4 * 4);
    vbo.bind();

    vao.enableVertexAttribute(0);
    vao.vertexAttribPointer(0, 2, FloatType.FLOAT, 4, 0);
    vao.enableVertexAttribute(1);
    vao.vertexAttribPointer(1, 2, FloatType.FLOAT, 4, 2);

    renderToTexture.bindFramebuffer();

    coreRender.clearColor(0.f, 0.f, 0.f, 0.f);
    coreRender.clearColorBuffer();

    renderToTexture.disableAndResetViewport(width, height);

    vao.unbind();

    generator = new TextureAtlasGenerator(width, height);
  }

  /**
   * Add a single CoreTexture2D to the atlas and return informations about the
   * position in the texture atlas.
   *
   * @param texture
   *          the texture
   * @param name
   *          the name used to identify this texture
   * @param padding
   *          padding value around the texture when being placed into the atlas
   * @return the Result
   */
  public Result addImage(final CoreTexture2D texture, final String name, final int padding) {
    try {
      final Result result = generator.addImage(texture.getWidth(), texture.getHeight(), name, padding);
      put(texture, result.getX(), result.getY());
      return result;
    } catch (final TextureAtlasGeneratorException e) {
      return null;
    }
  }

  /**
   * The target texture allocated for the texture atlas. If you want to later
   * render using the texture atlas you'll need to call this and call bind() on
   * it.
   * 
   * @return the CoreRenderToTexture allocated for the texture altas
   */
  public CoreTexture2D getTargetTexture() {
    return texture;
  }

  /**
   * Width of the texture atlas used.
   * 
   * @return width of the texture atlas
   */
  public int getWidth() {
    return texture.getWidth();
  }

  /**
   * Height of the texture atlas used.
   * 
   * @return height of the texture atlas
   */
  public int getHeight() {
    return texture.getHeight();
  }

  private void put(final CoreTexture2D source, final int x, final int y) {
    shader.activate();
    shader.setUniformMatrix("uMvp",
                            4,
                            MatrixFactory.createOrtho(0, texture.getWidth(), 0, texture.getHeight()).toBuffer());

    vao.bind();
    renderToTexture.bindFramebuffer();

    final FloatBuffer buffer = vbo.getBuffer();
    buffer.put(x);
    buffer.put(y);
    buffer.put(0.0f);
    buffer.put(0.0f);

    buffer.put(x);
    buffer.put(y + source.getHeight());
    buffer.put(0.0f);
    buffer.put(1.0f);

    buffer.put(x + source.getWidth());
    buffer.put(y);
    buffer.put(1.0f);
    buffer.put(0.0f);

    buffer.put(x + source.getWidth());
    buffer.put(y + source.getHeight());
    buffer.put(1.0f);
    buffer.put(1.0f);
    buffer.rewind();
    vbo.bind();
    vbo.send();

    coreRender.renderTriangleStrip(4);
    vao.unbind();
    renderToTexture.disableAndResetViewport(source.getWidth(), source.getHeight());
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy