Commit 65b6eb39 authored by Matthias Betz's avatar Matthias Betz
Browse files

Add scene/pick shaders and ShaderProgram compiler

parent cbc859ff
package de.hft.stuttgart.citydoctor2.gui.gl;
import com.jogamp.opengl.GL3;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;
/** Compiles and links a GLSL program from classpath resources next to this class. */
public class ShaderProgram {
private final int program;
public ShaderProgram(GL3 gl, String vertexResource, String fragmentResource) {
int vs = compile(gl, GL3.GL_VERTEX_SHADER, read(vertexResource));
int fs = compile(gl, GL3.GL_FRAGMENT_SHADER, read(fragmentResource));
program = gl.glCreateProgram();
gl.glAttachShader(program, vs);
gl.glAttachShader(program, fs);
gl.glLinkProgram(program);
checkLink(gl, program);
gl.glDeleteShader(vs);
gl.glDeleteShader(fs);
}
public void use(GL3 gl) { gl.glUseProgram(program); }
public int uniform(GL3 gl, String name) { return gl.glGetUniformLocation(program, name); }
public void dispose(GL3 gl) { gl.glDeleteProgram(program); }
private static int compile(GL3 gl, int type, String src) {
int shader = gl.glCreateShader(type);
gl.glShaderSource(shader, 1, new String[]{src}, new int[]{src.length()}, 0);
gl.glCompileShader(shader);
int[] status = new int[1];
gl.glGetShaderiv(shader, GL3.GL_COMPILE_STATUS, status, 0);
if (status[0] == 0) {
throw new IllegalStateException("Shader compile failed: " + infoLog(gl, shader, true));
}
return shader;
}
private static void checkLink(GL3 gl, int program) {
int[] status = new int[1];
gl.glGetProgramiv(program, GL3.GL_LINK_STATUS, status, 0);
if (status[0] == 0) {
throw new IllegalStateException("Program link failed: " + infoLog(gl, program, false));
}
}
private static String infoLog(GL3 gl, int handle, boolean shader) {
int[] len = new int[1];
if (shader) {
gl.glGetShaderiv(handle, GL3.GL_INFO_LOG_LENGTH, len, 0);
} else {
gl.glGetProgramiv(handle, GL3.GL_INFO_LOG_LENGTH, len, 0);
}
byte[] log = new byte[Math.max(1, len[0])];
if (shader) {
gl.glGetShaderInfoLog(handle, log.length, new int[1], 0, log, 0);
} else {
gl.glGetProgramInfoLog(handle, log.length, new int[1], 0, log, 0);
}
return new String(log, StandardCharsets.UTF_8);
}
private static String read(String resource) {
try (InputStream in = ShaderProgram.class.getResourceAsStream(resource)) {
if (in == null) {
throw new IllegalStateException("Shader resource not found: " + resource);
}
try (BufferedReader r = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
return r.lines().collect(Collectors.joining("\n"));
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
#version 330 core
flat in int vId;
out vec4 fragColor;
void main() {
int id = vId;
float r = float( id & 0xFF) / 255.0;
float g = float((id >> 8) & 0xFF) / 255.0;
float b = float((id >> 16) & 0xFF) / 255.0;
fragColor = vec4(r, g, b, 1.0);
}
#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 2) in int aId;
uniform mat4 uMVP;
flat out int vId;
void main() {
gl_Position = uMVP * vec4(aPos, 1.0);
vId = aId;
}
#version 330 core
in vec3 vColor;
flat in int vSelected;
out vec4 fragColor;
void main() {
vec3 c = vColor;
if (vSelected == 1) {
c = mix(c, vec3(1.0, 0.0, 0.0), 0.6);
}
fragColor = vec4(c, 1.0);
}
#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aColor;
layout(location = 2) in int aId;
uniform mat4 uMVP;
uniform int uSelectedId;
out vec3 vColor;
flat out int vSelected;
void main() {
gl_Position = uMVP * vec4(aPos, 1.0);
vColor = aColor;
vSelected = (aId == uSelectedId) ? 1 : 0;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment