/*******************************************************************************
* Copyright (c) 2015
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*******************************************************************************/
package jsettlers.graphics.image;
import go.graphics.GLDrawContext;
import go.graphics.IllegalBufferException;
import go.graphics.TextureHandle;
import jsettlers.common.Color;
import jsettlers.graphics.map.draw.DrawBuffer;
import jsettlers.graphics.reader.ImageMetadata;
/**
* This is an image inside a multi image map.
*
* @author michael
*/
public class MultiImageImage extends Image {
private final MultiImageMap map;
private final float[] settlerGeometry;
private final float[] torsoGeometry;
/**
* This is the data that is required to store the position of a {@link MultiImageImage}.
*
* @author Michael Zangl.
*
*/
private final class Data {
private int width;
private int height;
private int offsetX;
private int offsetY;
private float umin;
private float umax;
private float vmin;
private float vmax;
}
private final Data settler;
private final Data torso;
public MultiImageImage(MultiImageMap map, ImageMetadata settlerMeta,
int settlerx, int settlery, ImageMetadata torsoMeta, int torsox,
int torsoy) {
this.map = map;
settler = new Data();
settlerGeometry =
createGeometry(map, settlerMeta, settlerx, settlery, settler);
if (torsoMeta != null) {
torso = new Data();
torsoGeometry =
createGeometry(map, torsoMeta, torsox, torsoy, torso);
} else {
torso = null;
torsoGeometry = null;
}
}
private static final float IMAGE_DRAW_OFFSET = 0.5f;
private static float[] createGeometry(MultiImageMap map,
ImageMetadata settlerMeta, int settlerx, int settlery, Data data) {
data.width = settlerMeta.width;
data.height = settlerMeta.height;
data.offsetX = settlerMeta.offsetX;
data.offsetY = settlerMeta.offsetY;
data.umin = (float) settlerx / map.getWidth();
data.umax = (float) (settlerx + settlerMeta.width) / map.getWidth();
data.vmin = (float) (settlery + settlerMeta.height) / map.getHeight();
data.vmax = (float) settlery / map.getHeight();
return new float[] {
// top left
settlerMeta.offsetX + IMAGE_DRAW_OFFSET,
-settlerMeta.offsetY - settlerMeta.height + IMAGE_DRAW_OFFSET,
0,
data.umin,
data.vmin,
// bottom left
settlerMeta.offsetX + IMAGE_DRAW_OFFSET,
-settlerMeta.offsetY + IMAGE_DRAW_OFFSET,
0,
data.umin,
data.vmax,
// bottom right
settlerMeta.offsetX + settlerMeta.width + IMAGE_DRAW_OFFSET,
-settlerMeta.offsetY + IMAGE_DRAW_OFFSET,
0,
data.umax,
data.vmax,
// top right
settlerMeta.offsetX + settlerMeta.width + IMAGE_DRAW_OFFSET,
-settlerMeta.offsetY - settlerMeta.height + IMAGE_DRAW_OFFSET,
0,
data.umax,
data.vmin,
};
}
@Override
public void drawAt(GLDrawContext gl, float x, float y) {
drawAt(gl, x, y, null);
}
@Override
public void drawAt(GLDrawContext gl, float x, float y, Color color) {
gl.glPushMatrix();
gl.glTranslatef(x, y, 0);
draw(gl, color);
gl.glPopMatrix();
}
@Override
public void draw(GLDrawContext gl, Color color) {
draw(gl, color, 1);
}
@Override
public void draw(GLDrawContext gl, Color color, float multiply) {
try {
gl.color(multiply, multiply, multiply, 1);
TextureHandle texture = map.getTexture(gl);
gl.drawQuadWithTexture(texture, settlerGeometry);
if (torsoGeometry != null) {
if (color != null) {
gl.color(color.getRed() * multiply,
color.getGreen() * multiply,
color.getBlue() * multiply, color.getAlpha());
}
gl.drawQuadWithTexture(texture, torsoGeometry);
}
} catch (IllegalBufferException e) {
handleIllegalBufferException(e);
}
}
private static final float[] TEMP_BUFFER = new float[5 * 4];
@Override
public void drawImageAtRect(GLDrawContext gl, float left, float bottom,
float right, float top) {
try {
gl.color(1, 1, 1, 1);
System.arraycopy(settlerGeometry, 0, TEMP_BUFFER, 0, 4 * 5);
TEMP_BUFFER[0] = left + IMAGE_DRAW_OFFSET;
TEMP_BUFFER[1] = top + IMAGE_DRAW_OFFSET;
TEMP_BUFFER[5] = left + IMAGE_DRAW_OFFSET;
TEMP_BUFFER[6] = bottom + IMAGE_DRAW_OFFSET;
TEMP_BUFFER[10] = right + IMAGE_DRAW_OFFSET;
TEMP_BUFFER[11] = bottom + IMAGE_DRAW_OFFSET;
TEMP_BUFFER[15] = right + IMAGE_DRAW_OFFSET;
TEMP_BUFFER[16] = top + IMAGE_DRAW_OFFSET;
gl.drawQuadWithTexture(map.getTexture(gl), TEMP_BUFFER);
} catch (IllegalBufferException e) {
handleIllegalBufferException(e);
}
}
@Override
public int getWidth() {
return settler.width;
}
@Override
public int getHeight() {
return settler.height;
}
@Override
public void drawAt(GLDrawContext gl, DrawBuffer buffer, float viewX,
float viewY, int iColor) {
drawAt(gl, buffer, viewX, viewY, iColor, iColor);
}
private void drawAt(GLDrawContext gl, DrawBuffer buffer, float viewX,
float viewY, int sColor, int tColor) {
try {
TextureHandle texture = map.getTexture(gl);
buffer.addImage(texture, viewX + settler.offsetX
+ IMAGE_DRAW_OFFSET, viewY - settler.offsetY - settler.height
+ IMAGE_DRAW_OFFSET, viewX + settler.offsetX + settler.width
+ IMAGE_DRAW_OFFSET, viewY - settler.offsetY
+ IMAGE_DRAW_OFFSET, settler.umin, settler.vmin, settler.umax,
settler.vmax, sColor);
if (torso != null) {
buffer.addImage(texture, viewX + torso.offsetX
+ IMAGE_DRAW_OFFSET, viewY - torso.offsetY - torso.height
+ IMAGE_DRAW_OFFSET, viewX + torso.offsetX + torso.width
+ IMAGE_DRAW_OFFSET, viewY - torso.offsetY
+ IMAGE_DRAW_OFFSET, torso.umin, torso.vmin, torso.umax,
torso.vmax, tColor);
}
} catch (IllegalBufferException e) {
handleIllegalBufferException(e);
}
}
@Override
public void drawAt(GLDrawContext gl, DrawBuffer buffer, float viewX,
float viewY, Color color, float multiply) {
drawAt(gl, buffer, viewX, viewY,
Color.getABGR(multiply, multiply, multiply, 1),
dimColor(color, multiply));
}
}