From aaf094a40abebd89168ccf101973132b2daf1382 Mon Sep 17 00:00:00 2001 From: Simon Dietz Date: Tue, 24 Dec 2024 09:09:07 +0100 Subject: [PATCH 1/2] Feat: Image resource handling and drawing. --- src/main/java/engine/resources/Image.java | 16 + .../java/engine/resources/ImageLoader.java | 6 + .../java/engine/resources/ImageResource.java | 29 ++ src/main/java/engine/resources/Resource.java | 10 + .../engine/resources/ResourceManager.java | 47 ++ src/main/java/workspace/GraphicsPImpl.java | 52 +- src/main/java/workspace/ui/Graphics2D.java | 465 +++++++++--------- 7 files changed, 380 insertions(+), 245 deletions(-) create mode 100644 src/main/java/engine/resources/Image.java create mode 100644 src/main/java/engine/resources/ImageLoader.java create mode 100644 src/main/java/engine/resources/ImageResource.java create mode 100644 src/main/java/engine/resources/Resource.java create mode 100644 src/main/java/engine/resources/ResourceManager.java diff --git a/src/main/java/engine/resources/Image.java b/src/main/java/engine/resources/Image.java new file mode 100644 index 00000000..8723717b --- /dev/null +++ b/src/main/java/engine/resources/Image.java @@ -0,0 +1,16 @@ +package engine.resources; + +public class Image { + + private final Object backendImage; + + public Image(Object backendImage) { + this.backendImage = backendImage; + } + + public Object getBackendImage() { + return backendImage; + } + + // Add methods to abstract common operations like `getWidth()`, `getHeight()`, etc. +} diff --git a/src/main/java/engine/resources/ImageLoader.java b/src/main/java/engine/resources/ImageLoader.java new file mode 100644 index 00000000..7f662402 --- /dev/null +++ b/src/main/java/engine/resources/ImageLoader.java @@ -0,0 +1,6 @@ +package engine.resources; + +public interface ImageLoader { + + Object loadImage(String path); // Returns the backend-specific image object +} diff --git a/src/main/java/engine/resources/ImageResource.java b/src/main/java/engine/resources/ImageResource.java new file mode 100644 index 00000000..5acbd65d --- /dev/null +++ b/src/main/java/engine/resources/ImageResource.java @@ -0,0 +1,29 @@ +package engine.resources; + +public class ImageResource implements Resource { + + private Object image; + + private String path; + + @Override + public void load(String path) { + this.image = ResourceManager.getInstance().loadImage(path); + this.path = path; + } + + @Override + public void unload() { + ResourceManager.getInstance().unloadImage(path); + this.image = null; + } + + @Override + public boolean isLoaded() { + return image != null; + } + + public Object getImage() { + return image; + } +} diff --git a/src/main/java/engine/resources/Resource.java b/src/main/java/engine/resources/Resource.java new file mode 100644 index 00000000..af03bf78 --- /dev/null +++ b/src/main/java/engine/resources/Resource.java @@ -0,0 +1,10 @@ +package engine.resources; + +public interface Resource { + + void load(String path); + + void unload(); + + boolean isLoaded(); +} diff --git a/src/main/java/engine/resources/ResourceManager.java b/src/main/java/engine/resources/ResourceManager.java new file mode 100644 index 00000000..fdfedab4 --- /dev/null +++ b/src/main/java/engine/resources/ResourceManager.java @@ -0,0 +1,47 @@ +package engine.resources; + +import java.util.HashMap; +import java.util.Map; + +public class ResourceManager { + + private static ResourceManager instance; + + private ImageLoader imageLoader; + + private final Map resourceCache = new HashMap<>(); + + private ResourceManager() {} + + public static ResourceManager getInstance() { + if (instance == null) { + instance = new ResourceManager(); + } + return instance; + } + + public void setImageLoader(ImageLoader loader) { + this.imageLoader = loader; + } + + public Image loadImage(String path) { + if (resourceCache.containsKey(path)) { + return resourceCache.get(path); // Return cached resource + } + + if (imageLoader == null) { + throw new IllegalStateException("ImageLoader is not set!"); + } + + Object obj = imageLoader.loadImage(path); + Image image = new Image(obj); + + resourceCache.put(path, image); + + return image; + } + + public void unloadImage(String path) { + resourceCache.remove(path); // Optionally handle cleanup for backend-specific resources + } +} diff --git a/src/main/java/workspace/GraphicsPImpl.java b/src/main/java/workspace/GraphicsPImpl.java index 3d1f5a5c..3d7d28da 100644 --- a/src/main/java/workspace/GraphicsPImpl.java +++ b/src/main/java/workspace/GraphicsPImpl.java @@ -5,6 +5,7 @@ import engine.processing.LightGizmoRenderer; import engine.processing.LightRendererImpl; import engine.render.Material; +import engine.resources.Image; import engine.scene.camera.Camera; import engine.scene.light.Light; import engine.scene.light.LightRenderer; @@ -14,6 +15,8 @@ import mesh.Mesh3D; import processing.core.PApplet; import processing.core.PGraphics; +import processing.core.PImage; +import processing.opengl.PGraphicsOpenGL; import processing.opengl.PShader; import workspace.render.Mesh3DRenderer; import workspace.ui.Color; @@ -35,6 +38,10 @@ public class GraphicsPImpl implements Graphics { private LightGizmoRenderer lightGizmoRenderer; + public static int faceCount = 0; + + public static int vertexCount = 0; + @Override public void setAmbientColor(math.Color ambientColor) { this.ambientColor = ambientColor; @@ -66,6 +73,8 @@ public GraphicsPImpl(PApplet p) { @Override public void fillFaces(Mesh3D mesh) { + faceCount += mesh.faces.size(); + vertexCount += mesh.vertices.size(); if (wireframeMode) { g.noFill(); stroke(); @@ -342,9 +351,9 @@ public void rotateZ(float angle) { @Override public void rotate(float rx, float ry, float rz) { - g.rotateX(rx); - g.rotateY(ry); - g.rotateZ(rz); + g.rotateX(rx); + g.rotateY(ry); + g.rotateZ(rz); } public void camera() { @@ -460,15 +469,48 @@ public void applyCamera(Camera camera) { if (camera == null) { throw new IllegalArgumentException("Camera instance cannot be null."); } - + + // g.resetMatrix(); + // Matrix4f m = camera.getViewProjectionMatrix(); + // + // + // Vector3f target = camera.getTarget(); + // Vector3f eye = camera.getTransform().getPosition(); + // Matrix4f look = Matrix4f.lookAt(eye, target, new Vector3f(0, 1, 0)); + // + // m = m.multiply(look); + + // g.getMatrix().set(m.getValues()); + float fov = camera.getFieldOfView(); float aspect = camera.getAspectRatio(); float near = camera.getNearPlane(); float far = camera.getFarPlane(); - g.perspective(fov, aspect, near, far); + // g.perspective(fov, aspect, near, far); + + Matrix4f m = camera.getProjectionMatrix(); + ((PGraphicsOpenGL) g).projection.set(m.getValues()); Vector3f target = camera.getTarget(); Vector3f eye = camera.getTransform().getPosition(); g.camera(eye.x, eye.y, eye.z, target.x, target.y, target.z, 0, 1, 0); } + + @Override + public void drawImage(Image image, float x, float y) { + if (image.getBackendImage() instanceof PImage) { + g.image((PImage) image.getBackendImage(), x, y); + } else { + throw new IllegalArgumentException("Unsupported image backend."); + } + } + + @Override + public void drawImage(Image image, float x, float y, float width, float height) { + if (image.getBackendImage() instanceof PImage) { + g.image((PImage) image.getBackendImage(), x, y, width, height); + } else { + throw new IllegalArgumentException("Unsupported image backend."); + } + } } diff --git a/src/main/java/workspace/ui/Graphics2D.java b/src/main/java/workspace/ui/Graphics2D.java index f957c87a..1b155c54 100644 --- a/src/main/java/workspace/ui/Graphics2D.java +++ b/src/main/java/workspace/ui/Graphics2D.java @@ -1,247 +1,232 @@ package workspace.ui; +import engine.resources.Image; + /** * Defines the 2D rendering context and operations for a 2D rendering system. - *

- * This interface provides methods for basic 2D graphics rendering operations - * such as drawing geometric shapes (rectangles, ovals, and lines), text - * rendering, color setting, transformations (translate, scale, rotate), and - * text metrics calculations. It serves as the foundation for implementing 2D - * rendering capabilities in a graphics pipeline. - *

- * - *

- * Implementations of this interface are responsible for providing concrete - * rendering logic with support for transformations and state management (e.g., - * push and pop matrix operations). - *

+ * + *

This interface provides methods for basic 2D graphics rendering operations such as drawing + * geometric shapes (rectangles, ovals, and lines), text rendering, color setting, transformations + * (translate, scale, rotate), and text metrics calculations. It serves as the foundation for + * implementing 2D rendering capabilities in a graphics pipeline. + * + *

Implementations of this interface are responsible for providing concrete rendering logic with + * support for transformations and state management (e.g., push and pop matrix operations). */ public interface Graphics2D { - /** - * Retrieves the current width of the rendering context's viewport. - * - * @return The width in pixels. - */ - int getWidth(); - - /** - * Retrieves the current height of the rendering context's viewport. - * - * @return The height in pixels. - */ - int getHeight(); - - /** - * Sets the current drawing color using a {@link Color}. - * - * @param color The color to set for rendering operations. - */ - void setColor(Color color); - - /** - * Sets the current drawing color using a math-defined {@link math.Color}. - * - * @param color The math-defined color to use for rendering operations. - */ - void setColor(math.Color color); - - /** - * Sets the current drawing color using RGB integer values. - * - * @param red The red channel value (0-255). - * @param green The green channel value (0-255). - * @param blue The blue channel value (0-255). - */ - void setColor(int red, int green, int blue); - - /** - * Sets the thickness of strokes (lines) used in subsequent drawing commands. - * - * @param weight The stroke weight to apply (e.g., 1.0 for standard line - * thickness). - */ - void strokeWeight(float weight); - - /** - * Saves the current transformation matrix onto a stack for future - * restoration. - * - * This allows temporary transformations without permanently altering the - * rendering state. - */ - void pushMatrix(); - - /** - * Restores the last saved transformation matrix from the stack. - * - * This undoes any temporary transformations applied since the last - * pushMatrix(). - */ - void popMatrix(); - - /** - * Translates the rendering context by a specified distance in 2D space. - * - * @param x The amount to translate along the x-axis. - * @param y The amount to translate along the y-axis. - */ - void translate(float x, float y); - - /** - * Scales the rendering context by specified scaling factors along the x and y - * axes. - * - * @param sx The scaling factor along the x-axis. - * @param sy The scaling factor along the y-axis. - */ - void scale(float sx, float sy); - - /** - * Rotates the rendering context by the given angle in radians. - * - * @param angle The angle to rotate by, in radians. - */ - void rotate(float angle); - - /** - * Draws an unfilled rectangle at the specified coordinates with the given - * dimensions. - * - * @param x The x-coordinate of the top-left corner of the rectangle. - * @param y The y-coordinate of the top-left corner of the rectangle. - * @param width The width of the rectangle. - * @param height The height of the rectangle. - */ - void drawRect(float x, float y, float width, float height); - - /** - * Draws a filled rectangle at the specified coordinates with the given - * dimensions. - * - * @param x The x-coordinate of the top-left corner of the rectangle. - * @param y The y-coordinate of the top-left corner of the rectangle. - * @param width The width of the rectangle. - * @param height The height of the rectangle. - */ - void fillRect(float x, float y, float width, float height); - - /** - * Draws the outline of a rounded rectangle with specified position, - * dimensions, and corner radius. - * - *

- * The rectangle is defined by its top-left corner (x, y), its width, and its - * height. The "radii" parameter specifies the corner radius, which determines - * how rounded the corners appear. If the corner radius is 0, this method - * behaves like {@link #drawRect(float, float, float, float)}. - * - * @param x The x-coordinate of the top-left corner of the rectangle. - * @param y The y-coordinate of the top-left corner of the rectangle. - * @param width The width of the rectangle. - * @param height The height of the rectangle. - * @param radii The corner radius for rounding the corners of the rectangle. - * A larger value results in more rounded corners. - */ - void drawRoundRect(float x, float y, float width, float height, float radii); - - /** - * Draws a filled rounded rectangle with specified position, dimensions, and - * corner radius. - * - *

- * The rectangle is defined by its top-left corner (x, y), its width, and its - * height. The "radii" parameter specifies the corner radius, which determines - * how rounded the corners appear. If the corner radius is 0, this method - * behaves like {@link #fillRect(float, float, float, float)}. - * - * @param x The x-coordinate of the top-left corner of the rectangle. - * @param y The y-coordinate of the top-left corner of the rectangle. - * @param width The width of the rectangle. - * @param height The height of the rectangle. - * @param radii The corner radius for rounding the corners of the rectangle. - * A larger value results in more rounded corners. - */ - void fillRoundRect(float x, float y, float width, float height, float radii); - - /** - * Draws an unfilled oval at the specified coordinates with the given - * dimensions. - * - * @param x The x-coordinate of the top-left corner of the bounding box - * of the oval. - * @param y The y-coordinate of the top-left corner of the bounding box - * of the oval. - * @param width The width of the bounding box. - * @param height The height of the bounding box. - */ - void drawOval(float x, float y, float width, float height); - - /** - * Draws a filled oval at the specified coordinates with the given dimensions. - * - * @param x The x-coordinate of the top-left corner of the bounding box - * of the oval. - * @param y The y-coordinate of the top-left corner of the bounding box - * of the oval. - * @param width The width of the bounding box. - * @param height The height of the bounding box. - */ - void fillOval(float x, float y, float width, float height); - - /** - * Draws a line from (x1, y1) to (x2, y2). - * - * @param x1 Starting x-coordinate. - * @param y1 Starting y-coordinate. - * @param x2 Ending x-coordinate. - * @param y2 Ending y-coordinate. - */ - void drawLine(float x1, float y1, float x2, float y2); - - /** - * Sets the size of text to render for subsequent text rendering operations. - * - * @param size The desired text size. - */ - void textSize(float size); - - /** - * Retrieves the current text size used by text rendering operations. - * - * @return The current text size. - */ - float getTextSize(); - - /** - * Computes the width of the given text string at the current text size. - * - * @param text The text to compute the width for. - * @return The width of the rendered text. - */ - float textWidth(String text); - - /** - * Retrieves the ascent of text (the portion of text above the baseline). - * - * @return The ascent value of the text. - */ - float textAscent(); - - /** - * Retrieves the descent of text (the portion of text below the baseline). - * - * @return The descent value of the text. - */ - float textDescent(); - - /** - * Renders text at the given screen coordinates. - * - * @param text The text to render. - * @param x The x-coordinate to start rendering the text. - * @param y The y-coordinate to start rendering the text. - */ - void text(String text, float x, float y); - -} \ No newline at end of file + /** + * Retrieves the current width of the rendering context's viewport. + * + * @return The width in pixels. + */ + int getWidth(); + + /** + * Retrieves the current height of the rendering context's viewport. + * + * @return The height in pixels. + */ + int getHeight(); + + /** + * Sets the current drawing color using a {@link Color}. + * + * @param color The color to set for rendering operations. + */ + void setColor(Color color); + + /** + * Sets the current drawing color using a math-defined {@link math.Color}. + * + * @param color The math-defined color to use for rendering operations. + */ + void setColor(math.Color color); + + /** + * Sets the current drawing color using RGB integer values. + * + * @param red The red channel value (0-255). + * @param green The green channel value (0-255). + * @param blue The blue channel value (0-255). + */ + void setColor(int red, int green, int blue); + + /** + * Sets the thickness of strokes (lines) used in subsequent drawing commands. + * + * @param weight The stroke weight to apply (e.g., 1.0 for standard line thickness). + */ + void strokeWeight(float weight); + + /** + * Saves the current transformation matrix onto a stack for future restoration. + * + *

This allows temporary transformations without permanently altering the rendering state. + */ + void pushMatrix(); + + /** + * Restores the last saved transformation matrix from the stack. + * + *

This undoes any temporary transformations applied since the last pushMatrix(). + */ + void popMatrix(); + + /** + * Translates the rendering context by a specified distance in 2D space. + * + * @param x The amount to translate along the x-axis. + * @param y The amount to translate along the y-axis. + */ + void translate(float x, float y); + + /** + * Scales the rendering context by specified scaling factors along the x and y axes. + * + * @param sx The scaling factor along the x-axis. + * @param sy The scaling factor along the y-axis. + */ + void scale(float sx, float sy); + + /** + * Rotates the rendering context by the given angle in radians. + * + * @param angle The angle to rotate by, in radians. + */ + void rotate(float angle); + + /** + * Draws an unfilled rectangle at the specified coordinates with the given dimensions. + * + * @param x The x-coordinate of the top-left corner of the rectangle. + * @param y The y-coordinate of the top-left corner of the rectangle. + * @param width The width of the rectangle. + * @param height The height of the rectangle. + */ + void drawRect(float x, float y, float width, float height); + + /** + * Draws a filled rectangle at the specified coordinates with the given dimensions. + * + * @param x The x-coordinate of the top-left corner of the rectangle. + * @param y The y-coordinate of the top-left corner of the rectangle. + * @param width The width of the rectangle. + * @param height The height of the rectangle. + */ + void fillRect(float x, float y, float width, float height); + + /** + * Draws the outline of a rounded rectangle with specified position, dimensions, and corner + * radius. + * + *

The rectangle is defined by its top-left corner (x, y), its width, and its height. The + * "radii" parameter specifies the corner radius, which determines how rounded the corners appear. + * If the corner radius is 0, this method behaves like {@link #drawRect(float, float, float, + * float)}. + * + * @param x The x-coordinate of the top-left corner of the rectangle. + * @param y The y-coordinate of the top-left corner of the rectangle. + * @param width The width of the rectangle. + * @param height The height of the rectangle. + * @param radii The corner radius for rounding the corners of the rectangle. A larger value + * results in more rounded corners. + */ + void drawRoundRect(float x, float y, float width, float height, float radii); + + /** + * Draws a filled rounded rectangle with specified position, dimensions, and corner radius. + * + *

The rectangle is defined by its top-left corner (x, y), its width, and its height. The + * "radii" parameter specifies the corner radius, which determines how rounded the corners appear. + * If the corner radius is 0, this method behaves like {@link #fillRect(float, float, float, + * float)}. + * + * @param x The x-coordinate of the top-left corner of the rectangle. + * @param y The y-coordinate of the top-left corner of the rectangle. + * @param width The width of the rectangle. + * @param height The height of the rectangle. + * @param radii The corner radius for rounding the corners of the rectangle. A larger value + * results in more rounded corners. + */ + void fillRoundRect(float x, float y, float width, float height, float radii); + + /** + * Draws an unfilled oval at the specified coordinates with the given dimensions. + * + * @param x The x-coordinate of the top-left corner of the bounding box of the oval. + * @param y The y-coordinate of the top-left corner of the bounding box of the oval. + * @param width The width of the bounding box. + * @param height The height of the bounding box. + */ + void drawOval(float x, float y, float width, float height); + + /** + * Draws a filled oval at the specified coordinates with the given dimensions. + * + * @param x The x-coordinate of the top-left corner of the bounding box of the oval. + * @param y The y-coordinate of the top-left corner of the bounding box of the oval. + * @param width The width of the bounding box. + * @param height The height of the bounding box. + */ + void fillOval(float x, float y, float width, float height); + + /** + * Draws a line from (x1, y1) to (x2, y2). + * + * @param x1 Starting x-coordinate. + * @param y1 Starting y-coordinate. + * @param x2 Ending x-coordinate. + * @param y2 Ending y-coordinate. + */ + void drawLine(float x1, float y1, float x2, float y2); + + /** + * Sets the size of text to render for subsequent text rendering operations. + * + * @param size The desired text size. + */ + void textSize(float size); + + /** + * Retrieves the current text size used by text rendering operations. + * + * @return The current text size. + */ + float getTextSize(); + + /** + * Computes the width of the given text string at the current text size. + * + * @param text The text to compute the width for. + * @return The width of the rendered text. + */ + float textWidth(String text); + + /** + * Retrieves the ascent of text (the portion of text above the baseline). + * + * @return The ascent value of the text. + */ + float textAscent(); + + /** + * Retrieves the descent of text (the portion of text below the baseline). + * + * @return The descent value of the text. + */ + float textDescent(); + + /** + * Renders text at the given screen coordinates. + * + * @param text The text to render. + * @param x The x-coordinate to start rendering the text. + * @param y The y-coordinate to start rendering the text. + */ + void text(String text, float x, float y); + + void drawImage(Image image, float x, float y); + + void drawImage(Image image, float x, float y, float width, float height); +} From dfb536aa91e399c1215f168928bb745a3e005355 Mon Sep 17 00:00:00 2001 From: Simon Dietz Date: Tue, 24 Dec 2024 09:10:12 +0100 Subject: [PATCH 2/2] Feat: Show/Hide info text via setter. --- src/main/java/engine/application/BasicApplication.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/engine/application/BasicApplication.java b/src/main/java/engine/application/BasicApplication.java index 4a5c14f0..fc85406f 100644 --- a/src/main/java/engine/application/BasicApplication.java +++ b/src/main/java/engine/application/BasicApplication.java @@ -110,7 +110,7 @@ public void update() { } @Override - public void render(Graphics g) { + public void render(Graphics g) { if (activeScene != null) { activeScene.render(g); } @@ -170,4 +170,8 @@ public Scene getActiveScene() { public void setActiveScene(Scene activeScene) { this.activeScene = activeScene; } + + public void setDisplayInfoText(boolean displayInfoText) { + this.displayInfoText = displayInfoText; + } }