forked from skeeto/sample-java-project
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathShader.java
More file actions
125 lines (109 loc) · 3.67 KB
/
Shader.java
File metadata and controls
125 lines (109 loc) · 3.67 KB
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
package com.nullprogram.lwjgl;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.GL20;
/**
* An OpenGL shader. Call dispose() on the shader to delete the shader
* and free up GPU resources.
*/
@EqualsAndHashCode(of = "handle")
public abstract class Shader {
/** Byte array read buffer size. */
private static final int BUFFER_SIZE = 1024;
/** The handle for this shader. */
@Getter
private final int handle;
/** True if this shader has been deleted already. */
private boolean disposed = false;
/**
* Create and compile a new shader from a string.
* @param type the type of this shader
* @param source the source string
* @throws LWJGLException on compilation error
*/
public Shader(final int type, final String source) throws LWJGLException {
handle = compile(type, source);
}
/**
* Create and compile a new shader from a string.
* @param type the type of this shader
* @param file the source file
* @throws LWJGLException on compilation error
* @throws IOException if the source could not be read
*/
public Shader(final int type, final File file)
throws IOException, LWJGLException {
this(type, fetch(new FileInputStream(file)));
}
/**
* Create and compile a new shader from a string.
* @param type the type of this shader
* @param resource the source resource
* @throws LWJGLException on compilation error
* @throws IOException if the source could not be read
*/
public Shader(final int type, final URL resource)
throws IOException, LWJGLException {
this(type, fetch(resource.openStream()));
}
/**
* Disposes of this shader and the system resources it is
* using. This can be safely called multiple times, but it is not
* thread-safe.
*/
public void dispose() {
if (!disposed) {
GL20.glDeleteShader(handle);
disposed = true;
}
}
@Override
public void finalize() {
dispose();
}
/**
* Compile the shader code and return the handle.
* @param type the type of this shader
* @param source the shader source code
* @return the shader's handle
* @throws LWJGLException when compilation fails
*/
private static int compile(final int type, final String source)
throws LWJGLException {
int shader = GL20.glCreateShader(type);
GL20.glShaderSource(shader, source);
GL20.glCompileShader(shader);
if (GL20.glGetShader(shader, GL20.GL_COMPILE_STATUS) == 0) {
/* Compile failed. */
int len = GL20.glGetShader(shader, GL20.GL_INFO_LOG_LENGTH);
String info = GL20.glGetShaderInfoLog(shader, len);
GL20.glDeleteShader(shader);
throw new LWJGLException(info);
}
return shader;
}
/**
* Read the given input into a byte array.
* @param in the input stream to be read
* @return the byte array containing the resource
* @throws java.io.IOException on IO error
*/
private static String fetch(final InputStream in)
throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
int n;
while ((n = in.read(buffer)) > 0) {
out.write(buffer, 0, n);
}
out.close();
return new String(out.toByteArray());
}
}