Guten Abend liebe Forengemeinde,
ich habe da mal eine Frage, bei der ihr mir hoffentlich weiterhelfen könnt.
Ich habe vor einiger Zeit eine kleine Game-Engine programmiert. Für die Renderung verwende ich ganz normal ein Graphics2D-Objekt, den ich über eine Rendermethode alle Zeichenobjekte erben lasse. Nun wollte ich gerne das Backend meiner Engine so umstellen, dass man einfach die Renderung auf OpenGL oder DirectX umschalten kann.
Also habe ich eine eigene Graphics-Interface und Klasse erstellt, die ich nun anstatt wie bisher Graphics2D an die Rendermethoden übergebe. Das funktioniert soweit auch. Nur bekomme ich leider seltsamme Seiteneffekte.
- auf meinem Rechner (Windows 7 AMD Phenom II X4, NVidia GeForce GTX 280, 8 GB RAM, DirectX 11, Java 6 u 18 (JDK)) werden Bilder sowie Rectangles gerendert, oval, arc, roundrect usw. werden nicht gerendert (!)
- auf meinem Virtuellen PC (Windows XP SP3) werden keine Bilder gerendert, dafür aber rect, oval, roundrect, arc usw.
- auf meinem Notebook (Windows XP SP3) wird alles gerendert
Aufgrund der verschiedenen Laufzeitverhalten verstehe ich nicht so ganz, was ich falsch gemacht habe.
Meine Graphics-Klasse mappt die (für mich) wichtigsten Graphics2D-Methoden (vorerst habe ich nur Swing implementiert). Zu diesem Zweck wird über eine setSource-Methode die "Kernel"-Instanz pro Rendervorgang (vor der Renderung) an die Graphics-Instanz übergeben und als Attribut gespeichert (Ich weis, sollte man nicht machen, geht aber nicht anders...). Während der Renderung wird dann über das gespeicherte Attribut gearbeitet.
Hier mal der Quellcode meiner Graphics-Klasse.
[Java]public class DefaultEGEGraphics implements EGEGraphics {
// public constant class attributes
/**
* A neutral affine transformation for reseting the transformation of the
* source-graphics.
*/
public static final AffineTransform EMPTY_TRANSFORM = new AffineTransform();
// private object attributes
private Graphics2D source;
private EGETransformation transformation;
private EGEVector i_vector;
private EGEFont font;
private EGEColor color;
private EGEComposite composite;
private Composite oldComposite;
// constructors
/**
* This constructor creates a new graphics-object that will be used for the
* internal rendering of ege. This constructor should only be used by the
* internal ege-rendering-classes.
*
* @param graphics
* the native java-swing graphics context that should be mapped.
*/
public DefaultEGEGraphics(Graphics2D graphics) {
setSource(graphics);
}
// implemented methods
public void clearRect(double x, double y, double width, double height) {
source.clearRect((int) x, (int) y, (int) width, (int) height);
}
public void clipRect(double x, double y, double width, double height) {
source.clipRect((int) x, (int) y, (int) width, (int) height);
}
public EGEGraphics create() {
return new DefaultEGEGraphics((Graphics2D) source.create());
}
public void drawArc(double x, double y, double width, double height, double startAngle, double arcAngle) {
source.drawArc((int) x, (int) y, (int) width, (int) height, (int) startAngle, (int) arcAngle);
}
public void drawImage(ImageResource img, double x, double y) {
source.drawImage(img.getResource(), (int) x, (int) y, null);
}
public void drawImage(ImageResource img, double x, double y, EGEColor bgcolor) {
source.drawImage(img.getResource(), (int) x, (int) y, (Color) bgcolor.getSource(), null);
}
public void drawImage(ImageResource img, double x, double y, double width, double height) {
source.drawImage(img.getResource(), (int) x, (int) y, (int) width, (int) height, null);
}
public void drawImage(ImageResource img, double x, double y, double width, double height, EGEColor bgcolor) {
source.drawImage(img.getResource(), (int) x, (int) y, (int) width, (int) height, (Color) bgcolor.getSource(), null);
}
public void drawLine(double x1, double y1, double x2, double y2) {
source.drawLine((int) x1, (int) y1, (int) x2, (int) y2);
}
public void drawOval(double x, double y, double width, double height) {
source.drawOval((int) x, (int) y, (int) width, (int) height);
}
public void drawRect(double x, double y, double width, double height) {
source.drawRect((int) x, (int) y, (int) width, (int) height);
}
public void drawRoundRect(double x, double y, double width, double height, double arcWidth, double arcHeight) {
source.drawRoundRect((int) x, (int) y, (int) width, (int) height, (int) arcWidth, (int) arcHeight);
}
public void drawShape(EGEShape shape) {
int v1_p1_x, v1_p1_y, v1_p2_x, v1_p2_y;
for (int i = 1; i < shape.size(); i++) {
v1_p1_x = (int) shape.get(i - 1).getX();
v1_p1_y = (int) shape.get(i - 1).getY();
v1_p2_x = (int) shape.get(i).getX();
v1_p2_y = (int) shape.get(i).getY();
source.drawLine(v1_p1_x, v1_p1_y, v1_p2_x, v1_p2_y);
}
}
public void drawShape(EGEShape shape, Transformable transform) {
if (i_vector == null)
i_vector = new EGEVector(0., 0.);
int v1_p1_x, v1_p1_y, v1_p2_x, v1_p2_y;
for (int i = 1; i < shape.size(); i++) {
shape.get(i_vector, transform, i - 1);
v1_p1_x = (int) i_vector.getX();
v1_p1_y = (int) i_vector.getY();
shape.get(i_vector, transform, i);
v1_p2_x = (int) i_vector.getX();
v1_p2_y = (int) i_vector.getY();
source.drawLine(v1_p1_x, v1_p1_y, v1_p2_x, v1_p2_y);
}
}
public void fillArc(double x, double y, double width, double height, double startAngle, double arcAngle) {
source.fillArc((int) x, (int) y, (int) width, (int) height, (int) startAngle, (int) arcAngle);
}
public void fillOval(double x, double y, double width, double height) {
source.fillOval((int) x, (int) y, (int) width, (int) height);
}
public void fillRect(double x, double y, double width, double height) {
source.fillRect((int) x, (int) y, (int) width, (int) height);
}
public void fillRoundRect(double x, double y, double width, double height, double arcWidth, double arcHeight) {
source.fillRoundRect((int) x, (int) y, (int) width, (int) height, (int) arcWidth, (int) arcHeight);
}
public EGEColor getColor() {
return color;
}
public EGEFont getFont() {
return font;
}
public Transformable getTransformation() {
return transformation;
}
public void setClip(double x, double y, double width, double height) {
source.setClip((int) x, (int) y, (int) width, (int) height);
}
public void setColor(EGEColor c) {
this.color = c;
source.setColor((Color) color.getSource());
}
public void setFont(EGEFont font) {
if (font == null)
return;
this.font = font;
}
public void setTransformation(Transformable transformation) {
this.transformation.setRotation(transformation.getRotation());
this.transformation.setX(transformation.getX());
this.transformation.setXScale(transformation.getXScale());
this.transformation.setXShear(transformation.getXShear());
this.transformation.setY(transformation.getY());
this.transformation.setYScale(transformation.getYScale());
this.transformation.setYShear(transformation.getYShear());
source.setTransform(EMPTY_TRANSFORM);
source.translate(this.transformation.getX(), this.transformation.getY());
source.rotate(this.transformation.getRotation());
source.scale(this.transformation.getXScale(), this.transformation.getYScale());
source.shear(this.transformation.getXShear(), this.transformation.getYShear());
}
public void translate(double x, double y) {
transformation.addX(x);
transformation.addY(y);
source.translate(x, y);
}
public Graphics2D getSource() {
return source;
}
public void setSource(Object source) {
if (source instanceof Graphics2D) {
this.source = (Graphics2D) source;
if (transformation == null)
transformation = new EGETransformation();
if (font == null)
font = EGETemplates.FONT01;
oldComposite = ((Graphics2D) source).getComposite();
}
}
public EGEComposite getComposite() {
return composite;
}
public void setComposite(EGEComposite composite) {
this.composite = composite;
if (composite != null) {
source.setComposite((Composite) composite.getSource());
} else if (oldComposite != null) {
source.setComposite(oldComposite);
}
}
public void drawString(String str, double x, double y) {
font.drawString(this, str, x, y);
}
public void reset() {
transformation.setRotation(0);
transformation.setX(0);
transformation.setXScale(1);
transformation.setXShear(0);
transformation.setY(0);
transformation.setYScale(1);
transformation.setYShear(0);
source.setTransform(EMPTY_TRANSFORM);
source.translate(transformation.getX(), transformation.getY());
source.rotate(transformation.getRotation());
source.scale(transformation.getXScale(), transformation.getYScale());
source.shear(transformation.getXShear(), transformation.getYShear());
source.setClip(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
}
public void resetComposite() {
source.setComposite(oldComposite);
}
public void rotate(double rotation) {
transformation.setRotation(transformation.getRotation() + rotation);
source.rotate(PI / 180. * rotation);
}
public void scale(double xs, double ys) {
transformation.setXScale(transformation.getXScale() / xs);
transformation.setYScale(transformation.getXScale() / ys);
source.scale(xs, ys);
}
public void shear(double xs, double ys) {
transformation.setXShear(transformation.getXShear() + xs);
transformation.setYShear(transformation.getXShear() + ys);
source.shear(xs, ys);
}
}[/Java]
Ich hoffe ich habe mich einigermaßen verständlich ausgedrückt...
Währe nett, wenn mir jemand weiterhelfen könnte. Für (sinnvolle) Vorschläge bin ich dankbar.
Danke und Gruß
Steev
ich habe da mal eine Frage, bei der ihr mir hoffentlich weiterhelfen könnt.
Ich habe vor einiger Zeit eine kleine Game-Engine programmiert. Für die Renderung verwende ich ganz normal ein Graphics2D-Objekt, den ich über eine Rendermethode alle Zeichenobjekte erben lasse. Nun wollte ich gerne das Backend meiner Engine so umstellen, dass man einfach die Renderung auf OpenGL oder DirectX umschalten kann.
Also habe ich eine eigene Graphics-Interface und Klasse erstellt, die ich nun anstatt wie bisher Graphics2D an die Rendermethoden übergebe. Das funktioniert soweit auch. Nur bekomme ich leider seltsamme Seiteneffekte.
- auf meinem Rechner (Windows 7 AMD Phenom II X4, NVidia GeForce GTX 280, 8 GB RAM, DirectX 11, Java 6 u 18 (JDK)) werden Bilder sowie Rectangles gerendert, oval, arc, roundrect usw. werden nicht gerendert (!)
- auf meinem Virtuellen PC (Windows XP SP3) werden keine Bilder gerendert, dafür aber rect, oval, roundrect, arc usw.
- auf meinem Notebook (Windows XP SP3) wird alles gerendert
Aufgrund der verschiedenen Laufzeitverhalten verstehe ich nicht so ganz, was ich falsch gemacht habe.
Meine Graphics-Klasse mappt die (für mich) wichtigsten Graphics2D-Methoden (vorerst habe ich nur Swing implementiert). Zu diesem Zweck wird über eine setSource-Methode die "Kernel"-Instanz pro Rendervorgang (vor der Renderung) an die Graphics-Instanz übergeben und als Attribut gespeichert (Ich weis, sollte man nicht machen, geht aber nicht anders...). Während der Renderung wird dann über das gespeicherte Attribut gearbeitet.
Hier mal der Quellcode meiner Graphics-Klasse.
[Java]public class DefaultEGEGraphics implements EGEGraphics {
// public constant class attributes
/**
* A neutral affine transformation for reseting the transformation of the
* source-graphics.
*/
public static final AffineTransform EMPTY_TRANSFORM = new AffineTransform();
// private object attributes
private Graphics2D source;
private EGETransformation transformation;
private EGEVector i_vector;
private EGEFont font;
private EGEColor color;
private EGEComposite composite;
private Composite oldComposite;
// constructors
/**
* This constructor creates a new graphics-object that will be used for the
* internal rendering of ege. This constructor should only be used by the
* internal ege-rendering-classes.
*
* @param graphics
* the native java-swing graphics context that should be mapped.
*/
public DefaultEGEGraphics(Graphics2D graphics) {
setSource(graphics);
}
// implemented methods
public void clearRect(double x, double y, double width, double height) {
source.clearRect((int) x, (int) y, (int) width, (int) height);
}
public void clipRect(double x, double y, double width, double height) {
source.clipRect((int) x, (int) y, (int) width, (int) height);
}
public EGEGraphics create() {
return new DefaultEGEGraphics((Graphics2D) source.create());
}
public void drawArc(double x, double y, double width, double height, double startAngle, double arcAngle) {
source.drawArc((int) x, (int) y, (int) width, (int) height, (int) startAngle, (int) arcAngle);
}
public void drawImage(ImageResource img, double x, double y) {
source.drawImage(img.getResource(), (int) x, (int) y, null);
}
public void drawImage(ImageResource img, double x, double y, EGEColor bgcolor) {
source.drawImage(img.getResource(), (int) x, (int) y, (Color) bgcolor.getSource(), null);
}
public void drawImage(ImageResource img, double x, double y, double width, double height) {
source.drawImage(img.getResource(), (int) x, (int) y, (int) width, (int) height, null);
}
public void drawImage(ImageResource img, double x, double y, double width, double height, EGEColor bgcolor) {
source.drawImage(img.getResource(), (int) x, (int) y, (int) width, (int) height, (Color) bgcolor.getSource(), null);
}
public void drawLine(double x1, double y1, double x2, double y2) {
source.drawLine((int) x1, (int) y1, (int) x2, (int) y2);
}
public void drawOval(double x, double y, double width, double height) {
source.drawOval((int) x, (int) y, (int) width, (int) height);
}
public void drawRect(double x, double y, double width, double height) {
source.drawRect((int) x, (int) y, (int) width, (int) height);
}
public void drawRoundRect(double x, double y, double width, double height, double arcWidth, double arcHeight) {
source.drawRoundRect((int) x, (int) y, (int) width, (int) height, (int) arcWidth, (int) arcHeight);
}
public void drawShape(EGEShape shape) {
int v1_p1_x, v1_p1_y, v1_p2_x, v1_p2_y;
for (int i = 1; i < shape.size(); i++) {
v1_p1_x = (int) shape.get(i - 1).getX();
v1_p1_y = (int) shape.get(i - 1).getY();
v1_p2_x = (int) shape.get(i).getX();
v1_p2_y = (int) shape.get(i).getY();
source.drawLine(v1_p1_x, v1_p1_y, v1_p2_x, v1_p2_y);
}
}
public void drawShape(EGEShape shape, Transformable transform) {
if (i_vector == null)
i_vector = new EGEVector(0., 0.);
int v1_p1_x, v1_p1_y, v1_p2_x, v1_p2_y;
for (int i = 1; i < shape.size(); i++) {
shape.get(i_vector, transform, i - 1);
v1_p1_x = (int) i_vector.getX();
v1_p1_y = (int) i_vector.getY();
shape.get(i_vector, transform, i);
v1_p2_x = (int) i_vector.getX();
v1_p2_y = (int) i_vector.getY();
source.drawLine(v1_p1_x, v1_p1_y, v1_p2_x, v1_p2_y);
}
}
public void fillArc(double x, double y, double width, double height, double startAngle, double arcAngle) {
source.fillArc((int) x, (int) y, (int) width, (int) height, (int) startAngle, (int) arcAngle);
}
public void fillOval(double x, double y, double width, double height) {
source.fillOval((int) x, (int) y, (int) width, (int) height);
}
public void fillRect(double x, double y, double width, double height) {
source.fillRect((int) x, (int) y, (int) width, (int) height);
}
public void fillRoundRect(double x, double y, double width, double height, double arcWidth, double arcHeight) {
source.fillRoundRect((int) x, (int) y, (int) width, (int) height, (int) arcWidth, (int) arcHeight);
}
public EGEColor getColor() {
return color;
}
public EGEFont getFont() {
return font;
}
public Transformable getTransformation() {
return transformation;
}
public void setClip(double x, double y, double width, double height) {
source.setClip((int) x, (int) y, (int) width, (int) height);
}
public void setColor(EGEColor c) {
this.color = c;
source.setColor((Color) color.getSource());
}
public void setFont(EGEFont font) {
if (font == null)
return;
this.font = font;
}
public void setTransformation(Transformable transformation) {
this.transformation.setRotation(transformation.getRotation());
this.transformation.setX(transformation.getX());
this.transformation.setXScale(transformation.getXScale());
this.transformation.setXShear(transformation.getXShear());
this.transformation.setY(transformation.getY());
this.transformation.setYScale(transformation.getYScale());
this.transformation.setYShear(transformation.getYShear());
source.setTransform(EMPTY_TRANSFORM);
source.translate(this.transformation.getX(), this.transformation.getY());
source.rotate(this.transformation.getRotation());
source.scale(this.transformation.getXScale(), this.transformation.getYScale());
source.shear(this.transformation.getXShear(), this.transformation.getYShear());
}
public void translate(double x, double y) {
transformation.addX(x);
transformation.addY(y);
source.translate(x, y);
}
public Graphics2D getSource() {
return source;
}
public void setSource(Object source) {
if (source instanceof Graphics2D) {
this.source = (Graphics2D) source;
if (transformation == null)
transformation = new EGETransformation();
if (font == null)
font = EGETemplates.FONT01;
oldComposite = ((Graphics2D) source).getComposite();
}
}
public EGEComposite getComposite() {
return composite;
}
public void setComposite(EGEComposite composite) {
this.composite = composite;
if (composite != null) {
source.setComposite((Composite) composite.getSource());
} else if (oldComposite != null) {
source.setComposite(oldComposite);
}
}
public void drawString(String str, double x, double y) {
font.drawString(this, str, x, y);
}
public void reset() {
transformation.setRotation(0);
transformation.setX(0);
transformation.setXScale(1);
transformation.setXShear(0);
transformation.setY(0);
transformation.setYScale(1);
transformation.setYShear(0);
source.setTransform(EMPTY_TRANSFORM);
source.translate(transformation.getX(), transformation.getY());
source.rotate(transformation.getRotation());
source.scale(transformation.getXScale(), transformation.getYScale());
source.shear(transformation.getXShear(), transformation.getYShear());
source.setClip(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
}
public void resetComposite() {
source.setComposite(oldComposite);
}
public void rotate(double rotation) {
transformation.setRotation(transformation.getRotation() + rotation);
source.rotate(PI / 180. * rotation);
}
public void scale(double xs, double ys) {
transformation.setXScale(transformation.getXScale() / xs);
transformation.setYScale(transformation.getXScale() / ys);
source.scale(xs, ys);
}
public void shear(double xs, double ys) {
transformation.setXShear(transformation.getXShear() + xs);
transformation.setYShear(transformation.getXShear() + ys);
source.shear(xs, ys);
}
}[/Java]
Ich hoffe ich habe mich einigermaßen verständlich ausgedrückt...
Währe nett, wenn mir jemand weiterhelfen könnte. Für (sinnvolle) Vorschläge bin ich dankbar.
Danke und Gruß
Steev