Improve handling of rendering card image from scratch

This commit is contained in:
drdev
2014-07-27 22:15:14 +00:00
parent 390b5eb315
commit c03bbca0fc
6 changed files with 100 additions and 62 deletions

View File

@@ -6,9 +6,12 @@ import com.badlogic.gdx.graphics.glutils.FrameBuffer;
//Special graphics object for rendering to a texture
public class TextureRenderer extends Graphics {
private final float width, height;
private final FrameBuffer frameBuffer;
public TextureRenderer(float width, float height) {
public TextureRenderer(float width0, float height0) {
width = width0;
height = height0;
frameBuffer = new FrameBuffer(Format.RGB565, (int)width, (int)height, false);
frameBuffer.begin();
begin(width, height);
@@ -16,12 +19,19 @@ public class TextureRenderer extends Graphics {
public Texture finish() {
end();
frameBuffer.end();
Texture texture = frameBuffer.getColorBufferTexture();
//draw buffered texture to another frame buffer to flip it to the proper orientation
FrameBuffer fb = new FrameBuffer(Format.RGB565, (int)width, (int)height, false);
fb.begin();
begin(width, height);
drawImage(frameBuffer.getColorBufferTexture(), 0, 0, width, height);
//frameBuffer.dispose(); //avoid holding on to the first frame buffer
end();
fb.end();
Texture texture = fb.getColorBufferTexture();
dispose(); //dispose after generating texture
frameBuffer.dispose();
return texture;
}
}

View File

@@ -25,7 +25,6 @@ import com.google.common.cache.LoadingCache;
import com.google.common.cache.CacheLoader.InvalidCacheLoadException;
import forge.ImageKeys;
import forge.card.CardImageRenderer;
import forge.game.card.Card;
import forge.game.player.IHasIcon;
import forge.item.InventoryItem;
@@ -64,11 +63,9 @@ public class ImageCache {
Texture defImage = null;
try {
defImage = new Texture(Gdx.files.absolute(ForgeConstants.NO_CARD_FILE));
}
catch (Exception ex) {
} catch (Exception ex) {
System.err.println("could not load default card image");
}
finally {
} finally {
defaultImage = (null == defImage) ? new Texture(10, 10, Format.RGBA8888) : defImage;
}
}
@@ -79,34 +76,20 @@ public class ImageCache {
}
public static Texture getImage(Card card) {
final String key;
if (!FControl.mayShowCard(card) || card.isFaceDown()) {
return getImage(ImageKeys.TOKEN_PREFIX + ImageKeys.MORPH_IMAGE, true);
key = ImageKeys.TOKEN_PREFIX + ImageKeys.MORPH_IMAGE;
}
return getOrCreateImage(card);
else {
key = card.getImageKey();
}
public static Texture getOrCreateImage(Card card) {
String imageKey = card.getImageKey();
Texture image = getImage(imageKey, false);
if (image == null) {
image = CardImageRenderer.createCardImage(card, cache, imageKey);
}
return image;
return getImage(key, true);
}
public static Texture getImage(PaperCard pc) {
String imageKey = ImageKeys.getImageKey(pc, false);
Texture image = getImage(imageKey, false);
if (image == null) {
image = CardImageRenderer.createCardImage(pc, cache, imageKey);
return getImage(ImageKeys.getImageKey(pc, false), true);
}
return image;
}
public static Texture getImage(InventoryItem ii) {
if (ii instanceof PaperCard) {
return getImage((PaperCard)ii);
}
return getImage(ImageKeys.getImageKey(ii, false), true);
}
@@ -152,7 +135,7 @@ public class ImageCache {
// Load from file and add to cache if not found in cache initially.
Texture image;
try {
image = cache.get(imageKey);
image = ImageCache.cache.get(imageKey);
}
catch (final ExecutionException ex) {
if (!(ex.getCause() instanceof NullPointerException)) {

View File

@@ -1,11 +1,17 @@
package forge.assets;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.PixmapIO;
import com.badlogic.gdx.graphics.Texture;
import com.google.common.cache.CacheLoader;
import forge.Forge;
import forge.ImageKeys;
import forge.card.CardImageRenderer;
import forge.game.card.Card;
import forge.item.PaperCard;
import forge.model.FModel;
import forge.properties.ForgeConstants;
import org.apache.commons.lang3.StringUtils;
@@ -25,9 +31,11 @@ final class ImageLoader extends CacheLoader<String, Texture> {
final String path;
final String filename;
boolean isCard = false;
if (key.startsWith(ImageKeys.TOKEN_PREFIX)) {
filename = key.substring(ImageKeys.TOKEN_PREFIX.length());
path = ForgeConstants.CACHE_TOKEN_PICS_DIR;
isCard = true;
}
else if (key.startsWith(ImageKeys.ICON_PREFIX)) {
filename = key.substring(ImageKeys.ICON_PREFIX.length());
@@ -52,36 +60,71 @@ final class ImageLoader extends CacheLoader<String, Texture> {
else {
filename = key;
path = ForgeConstants.CACHE_CARD_PICS_DIR;
isCard = true;
}
Texture ret = findFile(key, path, filename);
if (ret != null) { return ret; }
// some S00 cards are really part of 6ED
if (null == ret ) {
String s2kAlias = ImageUtil.getSetFolder("S00");
if ( filename.startsWith(s2kAlias) ) {
if (filename.startsWith(s2kAlias)) {
ret = findFile(key, path, filename.replace(s2kAlias, ImageUtil.getSetFolder("6ED")));
}
if (ret != null) { return ret; }
}
// try without set prefix
String setlessFilename = null;
if (null == ret && filename.contains("/")) {
setlessFilename = filename.substring(filename.indexOf('/') + 1);
String setCode;
String setlessFilename;
int idx = filename.indexOf('/');
if (idx != -1) {
setCode = filename.substring(0, idx);
setlessFilename = filename.substring(idx + 1);
ret = findFile(key, path, setlessFilename);
if (ret != null) { return ret; }
// try lowering the art index to the minimum for regular cards
if (null == ret && setlessFilename.contains(".full")) {
if (setlessFilename.contains(".full")) {
ret = findFile(key, path, setlessFilename.replaceAll("[0-9]*[.]full", "1.full"));
if (ret != null) { return ret; }
}
}
else {
setCode = null;
setlessFilename = filename;
}
if (null == ret) {
System.out.println("File not found, no image created: " + key);
if (isCard) { //if image is for card, attempt to create image for it
int artIndex = 0;
String cardName = setlessFilename;
idx = cardName.indexOf('.');
if (idx != -1) {
int dotIdx = idx;
//trim art index
while (idx > 0 && Character.isDigit(cardName.charAt(idx - 1))) {
idx--;
}
if (dotIdx > idx) {
artIndex = Integer.parseInt(cardName.substring(dotIdx, idx));
}
cardName = cardName.substring(0, idx);
}
PaperCard pc = FModel.getMagicDb().getCommonCards().getCard(cardName, setCode, artIndex);
if (pc == null) {
pc = FModel.getMagicDb().getVariantCards().getCard(cardName, setCode, artIndex);
}
if (pc != null) {
ret = CardImageRenderer.createCardImage(Card.getCardForUi(pc));
if (ret != null) {
//PixmapIO.writePNG(Gdx.files.absolute(path + filename + ".png"), ret.);
return ret;
}
}
}
System.out.println("File not found, no image created: " + key);
return null;
}
private static Texture findFile(String key, String path, String filename) {
for (String ext : _FILE_EXTENSIONS) {

View File

@@ -7,7 +7,6 @@ import org.apache.commons.lang3.StringUtils;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;
import com.google.common.cache.LoadingCache;
import forge.TextureRenderer;
import forge.assets.FSkinColor;
@@ -16,7 +15,6 @@ import forge.assets.TextRenderer;
import forge.card.CardDetailUtil.DetailColors;
import forge.card.mana.ManaCost;
import forge.game.card.Card;
import forge.item.IPaperCard;
public class CardImageRenderer {
private static final float IMAGE_WIDTH = 360;
@@ -28,10 +26,7 @@ public class CardImageRenderer {
private static final FSkinFont TEXT_FONT = FSkinFont.forHeight(MANA_SYMBOL_SIZE * 0.95f);
private static final FSkinFont PT_FONT = NAME_FONT;
public static Texture createCardImage(IPaperCard pc, LoadingCache<String, Texture> cache, String imageKey) {
return createCardImage(Card.getCardForUi(pc), cache, imageKey);
}
public static Texture createCardImage(Card card, LoadingCache<String, Texture> cache, String imageKey) {
public static Texture createCardImage(Card card) {
float w = IMAGE_WIDTH;
float h = IMAGE_HEIGHT;
@@ -90,9 +85,7 @@ public class CardImageRenderer {
Color ptColor2 = color2 == null ? null : FSkinColor.tintColor(Color.WHITE, color2, CardRenderer.PT_BOX_TINT);
drawPtBox(renderer, card, idForeColor, ptColor1, ptColor2, x, y, w, ptBoxHeight);
Texture image = renderer.finish();
cache.put(imageKey, image);
return image;
return renderer.finish();
}
private static void drawHeader(TextureRenderer renderer, Card card, boolean canShow, Color color1, Color color2, float x, float y, float w, float h) {

View File

@@ -57,13 +57,14 @@ public class CardRenderer {
float w = width - 2 * FDialog.INSETS;
float h = height - 2 * FDialog.INSETS;
final Texture image;
final String key;
if (FControl.mayShowCard(card) || FDialog.isDialogOpen()) { //support showing if card revealed in dialog
image = ImageCache.getOrCreateImage(card);
key = card.getImageKey();
}
else { //only show card back if can't show card
image = ImageCache.getImage(ImageKeys.TOKEN_PREFIX + ImageKeys.MORPH_IMAGE, true);
key = ImageKeys.TOKEN_PREFIX + ImageKeys.MORPH_IMAGE;
}
Texture image = ImageCache.getImage(key, true);
if (image == null || image == ImageCache.defaultImage) { return false; } //don't support drawing zoom for null or default textures
float imageWidth = image.getWidth();

View File

@@ -1,6 +1,7 @@
package forge.toolbox;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.Vector2;
import forge.Forge;
@@ -8,8 +9,8 @@ import forge.Graphics;
import forge.assets.FSkinFont;
import forge.assets.FImage;
import forge.assets.FSkinImage;
import forge.assets.ImageCache;
import forge.assets.ImageUtil;
import forge.card.CardRenderer;
import forge.card.CardZoom;
import forge.game.card.Card;
import forge.screens.match.views.VPrompt;
@@ -104,8 +105,15 @@ public class FOptionPane extends FDialog {
}
@Override
public void draw(Graphics g) {
float cardWidth = getHeight() / FCardPanel.ASPECT_RATIO;
CardRenderer.drawCardWithOverlays(g, card, (getWidth() - cardWidth) / 2, 0, cardWidth, getHeight());
float h = getHeight();
float w = h / FCardPanel.ASPECT_RATIO;
float x = (getWidth() - w) / 2;
float y = 0;
Texture image = ImageCache.getImage(card);
if (image != null) {
g.drawImage(image, x, y, w, h);
}
}
};
cardDisplay.setHeight(Utils.SCREEN_HEIGHT / 2);