Skip to content

Commit 0207819

Browse files
committed
Feat: Added texture wrap support
1 parent 117afe3 commit 0207819

File tree

4 files changed

+123
-2
lines changed

4 files changed

+123
-2
lines changed

src/main/java/engine/processing/ProcessingTexture.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import engine.resources.FilterMode;
44
import engine.resources.Texture;
5+
import engine.resources.TextureWrapMode;
56
import processing.core.PImage;
67

78
public class ProcessingTexture implements Texture {
@@ -10,9 +11,12 @@ public class ProcessingTexture implements Texture {
1011

1112
private FilterMode filterMode;
1213

14+
private TextureWrapMode textureWrapMode;
15+
1316
public ProcessingTexture(PImage image) {
1417
this.image = image;
1518
this.filterMode = FilterMode.BILINEAR;
19+
this.textureWrapMode = TextureWrapMode.CLAMP;
1620
}
1721

1822
@Override
@@ -61,6 +65,16 @@ public void setFilterMode(FilterMode filterMode) {
6165
this.filterMode = filterMode;
6266
}
6367

68+
@Override
69+
public TextureWrapMode getTextureWrapMode() {
70+
return textureWrapMode;
71+
}
72+
73+
@Override
74+
public void setTextureWrapMode(TextureWrapMode textureWrapMode) {
75+
this.textureWrapMode = textureWrapMode;
76+
}
77+
6478
@Override
6579
public Texture getBackendTexture() {
6680
return this;

src/main/java/engine/resources/Texture.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,29 @@ public interface Texture {
5555
*/
5656
void setFilterMode(FilterMode filterMode);
5757

58+
/**
59+
* Gets the current texture wrapping mode.
60+
*
61+
* <p>The texture wrap mode determines how the texture is applied when texture coordinates exceed
62+
* the [0, 1] range. For example, in {@link TextureWrapMode#REPEAT}, the texture will repeat,
63+
* whereas in {@link TextureWrapMode#CLAMP}, the texture will extend the edge pixels.
64+
*
65+
* @return the {@link TextureWrapMode} currently applied to the texture.
66+
*/
67+
TextureWrapMode getTextureWrapMode();
68+
69+
/**
70+
* Sets the texture wrapping mode.
71+
*
72+
* <p>This method controls how the texture is mapped outside the standard [0, 1] texture
73+
* coordinate range. Use {@link TextureWrapMode#REPEAT} to tile the texture across a surface, or
74+
* {@link TextureWrapMode#CLAMP} to stretch the texture's edge pixels when coordinates exceed the
75+
* valid range.
76+
*
77+
* @param textureWrapMode the new {@link TextureWrapMode} to apply to the texture.
78+
*/
79+
void setTextureWrapMode(TextureWrapMode textureWrapMode);
80+
5881
/**
5982
* Gets the underlying backend texture implementation. This is useful for accessing
6083
* engine-specific or platform-specific features.

src/main/java/engine/resources/Texture2D.java

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,20 +55,33 @@ public int getHeight() {
5555
/**
5656
* Binds the texture to the specified texture unit for rendering.
5757
*
58+
* <p>Binding a texture makes it available for use in subsequent rendering operations. The texture
59+
* unit represents a specific slot in the graphics pipeline to which the texture is assigned.
60+
*
5861
* @param unit the texture unit to bind this texture to.
62+
* @see #unbind()
5963
*/
6064
@Override
6165
public void bind(int unit) {
6266
texture.bind(unit);
6367
}
6468

65-
/** Unbinds the texture from its currently bound texture unit. */
69+
/**
70+
* Unbinds the texture from its currently bound texture unit.
71+
*
72+
* <p>Once a texture is unbound, it is no longer available for rendering until it is bound again.
73+
*/
6674
@Override
6775
public void unbind() {
6876
texture.unbind();
6977
}
7078

71-
/** Deletes the texture and releases any associated resources. */
79+
/**
80+
* Deletes the texture and releases any associated resources.
81+
*
82+
* <p>This method should be called when the texture is no longer needed to free up GPU memory.
83+
* After a texture is deleted, it cannot be used for rendering unless it is recreated.
84+
*/
7285
@Override
7386
public void delete() {
7487
texture.delete();
@@ -77,7 +90,11 @@ public void delete() {
7790
/**
7891
* Updates the pixel data of the texture.
7992
*
93+
* <p>This method replaces the existing texture data with new pixel values. The pixel data must
94+
* match the dimensions of the texture.
95+
*
8096
* @param pixels an array of pixel data to set for this texture.
97+
* @throws IllegalArgumentException if the pixel array size does not match the texture dimensions.
8198
*/
8299
@Override
83100
public void setPixels(int[] pixels) {
@@ -87,6 +104,9 @@ public void setPixels(int[] pixels) {
87104
/**
88105
* Gets the filter mode currently applied to the texture.
89106
*
107+
* <p>The filter mode determines how the texture is sampled when it is magnified or minified
108+
* during rendering. Common filter modes include nearest-neighbor and linear filtering.
109+
*
90110
* @return the filter mode of the texture.
91111
* @see FilterMode
92112
*/
@@ -98,6 +118,10 @@ public FilterMode getFilterMode() {
98118
/**
99119
* Sets the filter mode for the texture.
100120
*
121+
* <p>The filter mode controls how the texture is sampled when rendered at different sizes. For
122+
* example, linear filtering smooths the texture when scaled, while nearest-neighbor filtering
123+
* preserves sharp edges.
124+
*
101125
* @param filterMode the desired filter mode to apply to the texture.
102126
* @see FilterMode
103127
*/
@@ -106,9 +130,42 @@ public void setFilterMode(FilterMode filterMode) {
106130
texture.setFilterMode(filterMode);
107131
}
108132

133+
/**
134+
* Gets the texture wrapping mode currently applied to this texture.
135+
*
136+
* <p>The texture wrap mode controls how the texture is applied when texture coordinates exceed
137+
* the [0, 1] range. For example, in {@link TextureWrapMode#REPEAT}, the texture will tile
138+
* infinitely, whereas in {@link TextureWrapMode#CLAMP}, the texture's edge pixels are stretched.
139+
*
140+
* @return the {@link TextureWrapMode} applied to the texture.
141+
*/
142+
@Override
143+
public TextureWrapMode getTextureWrapMode() {
144+
return texture.getTextureWrapMode();
145+
}
146+
147+
/**
148+
* Sets the texture wrapping mode for this texture.
149+
*
150+
* <p>This method controls how the texture is mapped outside the standard [0, 1] texture
151+
* coordinate range. Use {@link TextureWrapMode#REPEAT} to tile the texture across a surface, or
152+
* {@link TextureWrapMode#CLAMP} to stretch the texture's edge pixels when coordinates exceed the
153+
* valid range.
154+
*
155+
* @param textureWrapMode the new {@link TextureWrapMode} to apply to the texture.
156+
*/
157+
@Override
158+
public void setTextureWrapMode(TextureWrapMode textureWrapMode) {
159+
this.texture.setTextureWrapMode(textureWrapMode);
160+
}
161+
109162
/**
110163
* Retrieves the backend texture instance used by this facade.
111164
*
165+
* <p>This method provides access to the underlying texture object managed by the {@link
166+
* TextureManager}. It is useful for accessing low-level or engine-specific features not exposed
167+
* by the {@link Texture2D} class.
168+
*
112169
* @return the underlying {@link Texture} instance.
113170
*/
114171
@Override

src/main/java/workspace/GraphicsPImpl.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import engine.resources.FilterMode;
1010
import engine.resources.Image;
1111
import engine.resources.Texture;
12+
import engine.resources.TextureWrapMode;
1213
import engine.scene.camera.Camera;
1314
import engine.scene.light.Light;
1415
import engine.scene.light.LightRenderer;
@@ -158,10 +159,36 @@ private void applyTexture() {
158159
return; // Ensure texture is properly initialized before applying it.
159160
}
160161
((PGraphicsOpenGL) g).textureSampling(getSamplingMode(texture.getFilterMode()));
162+
g.textureWrap(getTextureWrapMode());
161163
g.textureMode(PApplet.NORMAL);
162164
g.texture(texture.getImage());
163165
}
164166

167+
/**
168+
* Converts the internal {@link TextureWrapMode} to a corresponding Processing constant.
169+
*
170+
* <p>This method maps the engine's {@link TextureWrapMode} values to the equivalent constants
171+
* defined by the {@link PApplet} class for use in Processing-based rendering. The supported
172+
* mappings are:
173+
*
174+
* <ul>
175+
* <li>{@link TextureWrapMode#CLAMP} -> {@link PApplet#CLAMP}
176+
* <li>{@link TextureWrapMode#REPEAT} -> {@link PApplet#REPEAT}
177+
* </ul>
178+
*
179+
* <p>If an unsupported or unexpected wrap mode is encountered, a warning is printed to {@code
180+
* System.err}, and {@link PApplet#CLAMP} is returned as a fallback.
181+
*
182+
* @return the corresponding Processing constant for the texture wrap mode.
183+
*/
184+
private int getTextureWrapMode() {
185+
TextureWrapMode textureWrapMode = texture.getTextureWrapMode();
186+
if (textureWrapMode == TextureWrapMode.CLAMP) return PApplet.CLAMP;
187+
if (textureWrapMode == TextureWrapMode.REPEAT) return PApplet.REPEAT;
188+
System.err.println("Warning: Unexpected texture wrap mode value: " + textureWrapMode);
189+
return PApplet.CLAMP;
190+
}
191+
165192
/**
166193
* Maps the given filter mode to the corresponding texture sampling mode.
167194
*

0 commit comments

Comments
 (0)