forked from daveyliam/mapwriter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTexture.java
158 lines (138 loc) · 5.44 KB
/
Texture.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package mapwriter;
import java.nio.IntBuffer;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
public class Texture {
private int id;
public final int w;
public final int h;
private final IntBuffer pixelBuf;
// allocate new texture and fill from IntBuffer
public Texture(int w, int h, int fillColour, int minFilter, int maxFilter, int textureWrap) {
this.id = GL11.glGenTextures();
this.w = w;
this.h = h;
this.pixelBuf = MwUtil.allocateDirectIntBuffer(w * h);
this.fillRect(0, 0, w, h, fillColour);
this.pixelBuf.position(0);
this.bind();
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, w, h, 0, GL12.GL_BGRA, GL11.GL_UNSIGNED_BYTE, this.pixelBuf);
this.setTexParameters(minFilter, maxFilter, textureWrap);
}
public Texture(int w, int h, int fillColour) {
this(w, h, fillColour, GL11.GL_LINEAR, GL11.GL_NEAREST, GL12.GL_CLAMP_TO_EDGE);
}
// create from existing texture
public Texture(int id) {
this.id = id;
this.bind();
this.w = Render.getTextureWidth();
this.h = Render.getTextureHeight();
this.pixelBuf = MwUtil.allocateDirectIntBuffer(this.w * this.h);
this.getPixelsFromExistingTexture();
MwUtil.log("created new MwTexture from GL texture id %d (%dx%d) (%d pixels)", this.id, this.w, this.h, this.pixelBuf.limit());
}
// free up the resources used by the GL texture
public synchronized void close() {
if (this.id != 0) {
try {
GL11.glDeleteTextures(this.id);
} catch (NullPointerException e) {
MwUtil.log("MwTexture.close: null pointer exception (texture %d)", this.id);
}
this.id = 0;
}
}
public synchronized void fillRect(int x, int y, int w, int h, int colour) {
int offset = (y * this.w) + x;
for (int j = 0; j < h; j++) {
this.pixelBuf.position(offset + (j * this.w));
for (int i = 0; i < w; i++) {
this.pixelBuf.put(colour);
}
}
}
// Copy a rectangular sub-region of dimensions 'w' x 'h' from the pixel buffer to the array 'pixels'.
public synchronized void getRGB(int x, int y, int w, int h, int[] pixels, int offset, int scanSize) {
int bufOffset = (y * this.w) + x;
for (int i = 0; i < h; i++) {
this.pixelBuf.position(bufOffset + (i * this.w));
this.pixelBuf.get(pixels, offset + (i * scanSize), w);
}
}
// Copy a rectangular sub-region of dimensions 'w' x 'h' from the array 'pixels' to the pixel buffer.
public synchronized void setRGB(int x, int y, int w, int h, int[] pixels, int offset, int scanSize) {
int bufOffset = (y * this.w) + x;
for (int i = 0; i < h; i++) {
this.pixelBuf.position(bufOffset + (i * this.w));
this.pixelBuf.put(pixels, offset + (i * scanSize), w);
}
}
public synchronized void setRGBOpaque(int x, int y, int w, int h, int[] pixels, int offset, int scanSize) {
int bufOffset = (y * this.w) + x;
for (int i = 0; i < h; i++) {
this.pixelBuf.position(bufOffset + (i * this.w));
int rowOffset = offset + (i * scanSize);
for (int j = 0; j < w; j++) {
this.pixelBuf.put(pixels[rowOffset + j] | 0xff000000);
}
}
}
public synchronized void setRGB(int x, int y, int colour) {
this.pixelBuf.put((y * this.w) + x, colour);
}
public synchronized int getRGB(int x, int y) {
return this.pixelBuf.get((y * this.w) + x);
}
public void bind() {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.id);
}
// set texture scaling and wrapping parameters
public void setTexParameters(int minFilter, int maxFilter, int textureWrap) {
this.bind();
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, textureWrap);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, textureWrap);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, minFilter);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, maxFilter);
}
public void setLinearScaling(boolean enabled) {
this.bind();
if (enabled) {
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
} else {
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
}
}
// update texture from pixels in pixelBuf
public synchronized void updateTextureArea(int x, int y, int w, int h) {
try {
this.bind();
GL11.glPixelStorei(GL11.GL_UNPACK_ROW_LENGTH, this.w);
this.pixelBuf.position((y * this.w) + x);
GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, x, y, w, h, GL12.GL_BGRA, GL11.GL_UNSIGNED_BYTE, this.pixelBuf);
GL11.glPixelStorei(GL11.GL_UNPACK_ROW_LENGTH, 0);
} catch (NullPointerException e) {
MwUtil.log("MwTexture.updatePixels: null pointer exception (texture %d)", this.id);
}
}
public synchronized void updateTexture() {
this.bind();
this.pixelBuf.position(0);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, this.w, this.h, 0, GL12.GL_BGRA, GL11.GL_UNSIGNED_BYTE, this.pixelBuf);
}
// copy pixels from GL texture to pixelBuf
private synchronized void getPixelsFromExistingTexture() {
try {
this.bind();
this.pixelBuf.clear();
GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL12.GL_BGRA, GL11.GL_UNSIGNED_BYTE, this.pixelBuf);
// getTexImage does not seem to advance the buffer position, so flip does not work here
// this.pixelBuf.flip()
this.pixelBuf.limit(this.w * this.h);
} catch (NullPointerException e) {
MwUtil.log("MwTexture.getPixels: null pointer exception (texture %d)", this.id);
}
}
}