package com.nilunder.bdx.gl; import com.badlogic.gdx.graphics.glutils.HdpiUtils; import javax.vecmath.Vector2f; import javax.vecmath.Matrix3f; import javax.vecmath.Vector3f; import com.nilunder.bdx.Bdx; import com.nilunder.bdx.Scene; import com.nilunder.bdx.Camera; public class Viewport{ public enum Type{ LETTERBOX, EXTEND, SCALE, SCREEN } private Type type; private Vector2f positionNormalized, sizeNormalized; public int x, y, w, h; public Scene scene; public Viewport(Scene scene, Type type){ this.scene = scene; this.type = type; this.positionNormalized = new Vector2f(); this.sizeNormalized = new Vector2f(1, 1); update(); } public Type type(){ return type; } public void type(Type type){ this.type = type; update(); } public Matrix3f orientation(){ return scene.camera.orientation(); } public Vector2f resolution(){ return scene.camera.resolution(); } public void resolution(Vector2f resolution){ resolution(Math.round(resolution.x), Math.round(resolution.y)); } public void resolution(int width, int height){ scene.camera.resolution(width, height); update(); } public Vector2f sizeNormalized(){ return new Vector2f(sizeNormalized); } public void sizeNormalized(Vector2f sizeNormalized){ this.sizeNormalized = sizeNormalized; update(); } public void sizeNormalized(float width, float height){ sizeNormalized(new Vector2f(width, height)); } public Vector2f size(){ return sizeNormalized.mul(Bdx.display.size()); } public void size(Vector2f size){ sizeNormalized(size.div(Bdx.display.size())); } public void size(int width, int height){ size(new Vector2f(width, height)); } public Vector2f positionNormalized(){ return new Vector2f(positionNormalized); } public void positionNormalized(Vector2f positionNormalized){ this.positionNormalized = positionNormalized; update(); } public void positionNormalized(float x, float y){ positionNormalized(new Vector2f(x, y)); } public Vector2f position(){ return positionNormalized.mul(Bdx.display.size()); } public void position(Vector2f position){ positionNormalized(position.div(Bdx.display.size())); } public void position(float x, float y){ position(new Vector2f(x, y)); } public Vector2f viewportPositionNormalized(Vector3f position) { Vector2f p = scene.camera.screenPositionNormalized(position); p.sub(new Vector2f(x, y).div(Bdx.display.size())); p = p.mul(Bdx.display.size().div(new Vector2f(w, h))); return p; } public void apply(){ scene.camera.update(); HdpiUtils.glViewport(x, y, w, h); } public void update(int displayWidth, int displayHeight){ Vector2f resolution = resolution(); x = Math.round(positionNormalized.x * displayWidth); y = Math.round(positionNormalized.y * displayHeight); if (type == Type.SCREEN){ w = Math.round(sizeNormalized.x * resolution.x); h = Math.round(sizeNormalized.y * resolution.y); scene.camera.size(resolution); }else{ w = Math.round(sizeNormalized.x * displayWidth); h = Math.round(sizeNormalized.y * displayHeight); if (type == Type.SCALE){ scene.camera.size(resolution); }else{ float dRatio = (float) w / h; if (type == Type.LETTERBOX){ float rRatio = resolution.x / resolution.y; if (dRatio < rRatio){ int h2 = Math.round(w / rRatio); y += (h - h2) / 2; h = h2; }else if (dRatio > rRatio){ int w2 = Math.round(h * rRatio); x += (w - w2) / 2; w = w2; } if (scene.camera.type == Camera.Type.PERSPECTIVE){ scene.camera.size(w, h); } }else if (type == Type.EXTEND){ scene.camera.size(Math.round(resolution.y * dRatio), (int) resolution.y); } } } apply(); } public void update(){ update(Bdx.display.width(), Bdx.display.height()); } }