vrtc / jgltut (public) (License: GPLv3) (since 2020-10-12) (hash sha1)
Implement [gltut](https://paroj.github.io/gltut/) examples with [LWJGL3](https://www.lwjgl.org/).
List of commits:
Subject Hash Author Date (UTC)
feat!: Improve mock renderer fd45e6ac8a05602140bc30a9153f1e10c4815db1 Vladyslav Bondarenko 2020-10-07 16:29:47
Feat: add mock renderer a9270982088c680cd9b2462fd14ddbc048b314bd Vladyslav Bondarenko 2020-09-26 12:37:55
Initial commit 860d5debdc468cc159f2cbba261e5d8abb0abe38 Vladyslav Bondarenko 2020-09-21 12:45:18
Commit fd45e6ac8a05602140bc30a9153f1e10c4815db1 - feat!: Improve mock renderer
Add shader program compilation. Application fails to run due to invalid
OpenGL operation in RendererAA.
Author: Vladyslav Bondarenko
Author date (UTC): 2020-10-07 16:29
Committer name: Vladyslav Bondarenko
Committer date (UTC): 2020-10-07 16:29
Parent(s): a9270982088c680cd9b2462fd14ddbc048b314bd
Signer:
Signing key:
Signing status: N
Tree: ee640d77d539fae06b00cf38fb9a85dbff5cc727
File Lines added Lines deleted
bin/build.sh 14 0
bin/run.sh 2 1
conf/glslangValidator.conf 101 0
share/glslang/org.jgltut.tutaa/ShaderRendererAA.frag 8 0
share/glslang/org.jgltut.tutaa/ShaderRendererAA.vert 8 0
src/org.jgltut.tutaa/src/org/jgltut/tutaa/Application.java 2 0
src/org.jgltut.tutaa/src/org/jgltut/tutaa/ApplicationBuilder.java 2 3
src/org.jgltut.tutaa/src/org/jgltut/tutaa/Renderer.java 41 0
src/org.jgltut.tutaa/src/org/jgltut/tutaa/RendererAA.java 56 10
src/org.jgltut.tutaa/src/org/jgltut/tutaa/ShaderProgram.java 78 0
src/org.jgltut.tutaa/src/org/jgltut/tutaa/ShaderProgramBuilder.java 127 0
src/org.jgltut.tutaa/src/org/jgltut/tutaa/ShaderReader.java 78 0
src/org.jgltut.tutaa/src/org/jgltut/tutaa/ShaderType.java 22 0
src/org.jgltut.tutaa/src/org/jgltut/tutaa/Stage.java 12 0
File bin/build.sh changed (mode: 100755) (index 32cad5a..2668c04)
1 1 #!/bin/bash #!/bin/bash
2 echo '# build'
3 set -e
2 4 DIR=`dirname $0` DIR=`dirname $0`
3 5 BASEDIR="${DIR}/../" BASEDIR="${DIR}/../"
4 6
7 echo '# verify'
8 glslangValidator "${BASEDIR}conf/glslangValidator.conf" \
9 "${BASEDIR}share/glslang/org.jgltut.tutaa/ShaderRendererAA.vert" \
10 "${BASEDIR}share/glslang/org.jgltut.tutaa/ShaderRendererAA.frag"
11
12 echo '# compile'
5 13 mkdir -p "${BASEDIR}share/classes/" mkdir -p "${BASEDIR}share/classes/"
6 14
7 15 javac --module-source-path="${BASEDIR}/src/*/src/" \ javac --module-source-path="${BASEDIR}/src/*/src/" \
 
... ... javac --module-source-path="${BASEDIR}/src/*/src/" \
12 20 -d "${BASEDIR}share/classes/" \ -d "${BASEDIR}share/classes/" \
13 21 -m org.jgltut.tutaa -m org.jgltut.tutaa
14 22
23 echo '# package'
15 24 jar -cfe "${BASEDIR}share/java/org.jgltut.tutaa.jar" \ jar -cfe "${BASEDIR}share/java/org.jgltut.tutaa.jar" \
16 25 org.jgltut.tutaa.Main \ org.jgltut.tutaa.Main \
26 -C "${BASEDIR}share/glslang/org.jgltut.tutaa/" . \
17 27 -C "${BASEDIR}share/classes/org.jgltut.tutaa/" . -C "${BASEDIR}share/classes/org.jgltut.tutaa/" .
28
29 echo '# validate'
30 ls "${BASEDIR}share/java/org.jgltut.tutaa.jar"
31 jar tvf "${BASEDIR}share/java/org.jgltut.tutaa.jar"
File bin/run.sh changed (mode: 100755) (index d2dd5ff..400a8b3)
1 1 #!/bin/bash #!/bin/bash
2 2 DIR=`dirname $0` DIR=`dirname $0`
3 3 BASEDIR="${DIR}/../" BASEDIR="${DIR}/../"
4 mkdir -p "${BASEDIR}/var/log/"
4 5 java -ea -Dorg.lwjgl.librarypath="${BASEDIR}lib/java/" \ java -ea -Dorg.lwjgl.librarypath="${BASEDIR}lib/java/" \
5 6 -p "${BASEDIR}lib/java/:${BASEDIR}share/java/" \ -p "${BASEDIR}lib/java/:${BASEDIR}share/java/" \
6 -m org.jgltut.tutaa
7 -m org.jgltut.tutaa > "${BASEDIR}var/log/out.log" 2> "${BASEDIR}var/log/err.log"
File conf/glslangValidator.conf added (mode: 100644) (index 0000000..cff7716)
1 MaxLights 32
2 MaxClipPlanes 6
3 MaxTextureUnits 32
4 MaxTextureCoords 32
5 MaxVertexAttribs 64
6 MaxVertexUniformComponents 4096
7 MaxVaryingFloats 64
8 MaxVertexTextureImageUnits 32
9 MaxCombinedTextureImageUnits 80
10 MaxTextureImageUnits 32
11 MaxFragmentUniformComponents 4096
12 MaxDrawBuffers 32
13 MaxVertexUniformVectors 128
14 MaxVaryingVectors 8
15 MaxFragmentUniformVectors 16
16 MaxVertexOutputVectors 16
17 MaxFragmentInputVectors 15
18 MinProgramTexelOffset -8
19 MaxProgramTexelOffset 7
20 MaxClipDistances 8
21 MaxComputeWorkGroupCountX 65535
22 MaxComputeWorkGroupCountY 65535
23 MaxComputeWorkGroupCountZ 65535
24 MaxComputeWorkGroupSizeX 1024
25 MaxComputeWorkGroupSizeY 1024
26 MaxComputeWorkGroupSizeZ 64
27 MaxComputeUniformComponents 1024
28 MaxComputeTextureImageUnits 16
29 MaxComputeImageUniforms 8
30 MaxComputeAtomicCounters 8
31 MaxComputeAtomicCounterBuffers 1
32 MaxVaryingComponents 60
33 MaxVertexOutputComponents 64
34 MaxGeometryInputComponents 64
35 MaxGeometryOutputComponents 128
36 MaxFragmentInputComponents 128
37 MaxImageUnits 8
38 MaxCombinedImageUnitsAndFragmentOutputs 8
39 MaxCombinedShaderOutputResources 8
40 MaxImageSamples 0
41 MaxVertexImageUniforms 0
42 MaxTessControlImageUniforms 0
43 MaxTessEvaluationImageUniforms 0
44 MaxGeometryImageUniforms 0
45 MaxFragmentImageUniforms 8
46 MaxCombinedImageUniforms 8
47 MaxGeometryTextureImageUnits 16
48 MaxGeometryOutputVertices 256
49 MaxGeometryTotalOutputComponents 1024
50 MaxGeometryUniformComponents 1024
51 MaxGeometryVaryingComponents 64
52 MaxTessControlInputComponents 128
53 MaxTessControlOutputComponents 128
54 MaxTessControlTextureImageUnits 16
55 MaxTessControlUniformComponents 1024
56 MaxTessControlTotalOutputComponents 4096
57 MaxTessEvaluationInputComponents 128
58 MaxTessEvaluationOutputComponents 128
59 MaxTessEvaluationTextureImageUnits 16
60 MaxTessEvaluationUniformComponents 1024
61 MaxTessPatchComponents 120
62 MaxPatchVertices 32
63 MaxTessGenLevel 64
64 MaxViewports 16
65 MaxVertexAtomicCounters 0
66 MaxTessControlAtomicCounters 0
67 MaxTessEvaluationAtomicCounters 0
68 MaxGeometryAtomicCounters 0
69 MaxFragmentAtomicCounters 8
70 MaxCombinedAtomicCounters 8
71 MaxAtomicCounterBindings 1
72 MaxVertexAtomicCounterBuffers 0
73 MaxTessControlAtomicCounterBuffers 0
74 MaxTessEvaluationAtomicCounterBuffers 0
75 MaxGeometryAtomicCounterBuffers 0
76 MaxFragmentAtomicCounterBuffers 1
77 MaxCombinedAtomicCounterBuffers 1
78 MaxAtomicCounterBufferSize 16384
79 MaxTransformFeedbackBuffers 4
80 MaxTransformFeedbackInterleavedComponents 64
81 MaxCullDistances 8
82 MaxCombinedClipAndCullDistances 8
83 MaxSamples 4
84 MaxMeshOutputVerticesNV 256
85 MaxMeshOutputPrimitivesNV 512
86 MaxMeshWorkGroupSizeX_NV 32
87 MaxMeshWorkGroupSizeY_NV 1
88 MaxMeshWorkGroupSizeZ_NV 1
89 MaxTaskWorkGroupSizeX_NV 32
90 MaxTaskWorkGroupSizeY_NV 1
91 MaxTaskWorkGroupSizeZ_NV 1
92 MaxMeshViewCountNV 4
93 nonInductiveForLoops 1
94 whileLoops 1
95 doWhileLoops 1
96 generalUniformIndexing 1
97 generalAttributeMatrixVectorIndexing 1
98 generalVaryingIndexing 1
99 generalSamplerIndexing 1
100 generalVariableIndexing 1
101 generalConstantMatrixVectorIndexing 1
File share/glslang/org.jgltut.tutaa/ShaderRendererAA.frag added (mode: 100644) (index 0000000..5d3d9d6)
1 #version 330 core
2
3 out vec4 outputColor;
4
5 void main()
6 {
7 outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
8 }
File share/glslang/org.jgltut.tutaa/ShaderRendererAA.vert added (mode: 100644) (index 0000000..93dff26)
1 #version 330 core
2
3 in vec4 position;
4
5 void main()
6 {
7 gl_Position = position;
8 }
File src/org.jgltut.tutaa/src/org/jgltut/tutaa/Application.java changed (mode: 100644) (index 5c31aa0..89d2d1a)
... ... final class Application implements AutoCloseable, Runnable
28 28 { {
29 29 stage.apply(); stage.apply();
30 30 while (!stage.isCancelled()) { while (!stage.isCancelled()) {
31 stage.validate();
32 renderer.validate();
31 33 renderer.run(); renderer.run();
32 34 stage.get(); stage.get();
33 35 } }
File src/org.jgltut.tutaa/src/org/jgltut/tutaa/ApplicationBuilder.java changed (mode: 100644) (index 6b7ed13..cd6c0c6)
... ... enum ApplicationBuilder {
32 32 return INSTANCE; return INSTANCE;
33 33 } }
34 34
35 public final void
36 setRendererBuilder(final Function<Stage, Renderer> rendererBuilder)
35 public final void setRendererBuilder(final Function<Stage, Renderer> rendererBuilder)
37 36 { {
38 37 if (null == rendererBuilder) { if (null == rendererBuilder) {
39 38 throw new IllegalArgumentException("empty argument"); throw new IllegalArgumentException("empty argument");
 
... ... enum ApplicationBuilder {
62 61 verify(); verify();
63 62
64 63 stageBuilder.setTitle("Java OpenGL tutorial"); stageBuilder.setTitle("Java OpenGL tutorial");
65 final var dimension = WindowDimension.DIMENSION0384X0288;
64 final var dimension = WindowDimension.DIMENSION1024X0768;
66 65 stageBuilder.setWindowDimension(dimension); stageBuilder.setWindowDimension(dimension);
67 66 final Stage stage = stageBuilder.get(); final Stage stage = stageBuilder.get();
68 67 assert (stage != null); assert (stage != null);
File src/org.jgltut.tutaa/src/org/jgltut/tutaa/Renderer.java changed (mode: 100644) (index f2dc89f..b620265)
1 1 package org.jgltut.tutaa; package org.jgltut.tutaa;
2 2
3 import org.lwjgl.opengl.GL33C;
4 import static org.lwjgl.opengl.GL33C.glGetError;
5
3 6 abstract class Renderer implements AutoCloseable, Runnable abstract class Renderer implements AutoCloseable, Runnable
4 7 { {
8 public final void validate() throws IllegalStateException
9 {
10 Integer errorCode = Integer.valueOf(glGetError());
11 if (null == errorCode) {
12 errorCode = -1;
13 }
14 switch (errorCode) {
15 case GL33C.GL_NO_ERROR: {
16 return;
17 }
18 case GL33C.GL_INVALID_ENUM: {
19 throw new IllegalStateException("invalid enum");
20 }
21 case GL33C.GL_INVALID_VALUE: {
22 throw new IllegalStateException("invalid value");
23 }
24 case GL33C.GL_INVALID_OPERATION: {
25 throw new IllegalStateException("invalid operation");
26 }
27 case GL33C.GL_INVALID_FRAMEBUFFER_OPERATION: {
28 throw new IllegalStateException(
29 "invalid framebuffer operation");
30 }
31 case GL33C.GL_OUT_OF_MEMORY: {
32 throw new IllegalStateException("out of memory");
33 }
34 default: {
35 throw new IllegalStateException(
36 "unknown OpenGL error #" +
37 errorCode.toString());
38 }
39 }
40 }
41
42 @Override public void close()
43 {
44 throw new IllegalStateException("close unimplemented");
45 }
5 46 } }
File src/org.jgltut.tutaa/src/org/jgltut/tutaa/RendererAA.java changed (mode: 100644) (index 873b6d3..00acb16)
... ... import static org.lwjgl.opengl.GL33C.glEnableVertexAttribArray;
23 23 import static org.lwjgl.opengl.GL33C.glGenBuffers; import static org.lwjgl.opengl.GL33C.glGenBuffers;
24 24 import static org.lwjgl.opengl.GL33C.glUseProgram; import static org.lwjgl.opengl.GL33C.glUseProgram;
25 25 import static org.lwjgl.opengl.GL33C.glVertexAttribPointer; import static org.lwjgl.opengl.GL33C.glVertexAttribPointer;
26 import static org.lwjgl.opengl.GL33C.glGetError;
27 import static org.lwjgl.opengl.GL33C.GL_NO_ERROR;
26 28
27 29 final class RendererAA extends Renderer final class RendererAA extends Renderer
28 30 { {
 
... ... final class RendererAA extends Renderer
32 34 { {
33 35 } }
34 36
37 private final void validate() throws IllegalStateException
38 {
39 if (GL_NO_ERROR != glGetError()) {
40 throw new IllegalStateException("invalid renderer builder");
41 }
42 }
43
35 44 public final Renderer apply(final Stage stage) public final Renderer apply(final Stage stage)
36 45 { {
37 46 assert (stage != null); assert (stage != null);
 
... ... final class RendererAA extends Renderer
39 48 /* Close stack in RendererAA#close */ /* Close stack in RendererAA#close */
40 49 final var stack = MemoryStack.stackPush(); final var stack = MemoryStack.stackPush();
41 50 final int bufferHandle = glGenBuffers(); final int bufferHandle = glGenBuffers();
51 validate();
42 52 glBindBuffer(GL_ARRAY_BUFFER, bufferHandle); glBindBuffer(GL_ARRAY_BUFFER, bufferHandle);
53 validate();
43 54 final float[] vertexData = new float[] { final float[] vertexData = new float[] {
44 55 0.75f, 0.75f, 0.0f, 1.0f, 0.75f, 0.75f, 0.0f, 1.0f,
45 56 0.75f, -0.75f, 0.0f, 1.0f, 0.75f, -0.75f, 0.0f, 1.0f,
 
... ... final class RendererAA extends Renderer
47 58 }; };
48 59 final FloatBuffer floatBuffer = stack.callocFloat(vertexData.length); final FloatBuffer floatBuffer = stack.callocFloat(vertexData.length);
49 60 floatBuffer.put(vertexData, 0, vertexData.length); floatBuffer.put(vertexData, 0, vertexData.length);
61 floatBuffer.flip();
50 62 glBufferData(GL_ARRAY_BUFFER, floatBuffer, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, floatBuffer, GL_STATIC_DRAW);
63 validate();
51 64 glBindBuffer(GL_ARRAY_BUFFER, GL_FALSE); glBindBuffer(GL_ARRAY_BUFFER, GL_FALSE);
65 validate();
52 66
53 67 /* FIXME Shader program handle */ /* FIXME Shader program handle */
54 final int programHandle = -1;
68 final var spb = new ShaderProgramBuilder();
69 spb.setShaderFragSrc(SHADER_FRAG);
70 spb.setShaderVertSrc(SHADER_VERT);
71 final var sp = spb.get();
55 72 final var renderer = new RendererAA( final var renderer = new RendererAA(
56 stack, bufferHandle, programHandle);
73 floatBuffer, stack, bufferHandle, sp);
57 74 return renderer; return renderer;
58 75 } catch (Exception e) { } catch (Exception e) {
59 76 final String msg = "could not init renderer"; final String msg = "could not init renderer";
 
... ... final class RendererAA extends Renderer
62 79 } }
63 80 } }
64 81
82 private final static String SHADER_VERT =
83 "#version 330 core\n" +
84 "layout(location = 0) in vec4 position;\n" +
85 "void main()\n" +
86 "{\n" +
87 " gl_Position = position;\n" +
88 "}\n";
89
90 private final static String SHADER_FRAG =
91 "#version 330 core\n" +
92 "out vec4 outputColor;\n" +
93 "void main()\n" +
94 "{\n" +
95 " outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n" +
96 "}\n";
97
98 private final FloatBuffer floatBuffer;
65 99 private final MemoryStack memoryStack; private final MemoryStack memoryStack;
100 private final ShaderProgram program;
66 101 private final int bufferHandle; private final int bufferHandle;
67 private final int programHandle;
68 102
69 RendererAA(final MemoryStack memoryStack, final int bufferHandle,
70 final int programHandle)
103 RendererAA(final FloatBuffer floatBuffer, final MemoryStack memoryStack,
104 final int bufferHandle, final ShaderProgram program)
71 105 { {
72 106 assert (memoryStack != null); assert (memoryStack != null);
107 this.floatBuffer = floatBuffer;
73 108 this.memoryStack = memoryStack; this.memoryStack = memoryStack;
74 109 this.bufferHandle = bufferHandle; this.bufferHandle = bufferHandle;
75 this.programHandle = programHandle;
110 this.program = program;
76 111 } }
77 112
78 113 @Override public final void close() @Override public final void close()
 
... ... final class RendererAA extends Renderer
80 115 try { try {
81 116 memoryStack.close(); memoryStack.close();
82 117 glUseProgram(GL_FALSE); glUseProgram(GL_FALSE);
83 glDeleteProgram(programHandle);
84 118 glDeleteBuffers(bufferHandle); glDeleteBuffers(bufferHandle);
85
119 program.close();
86 120 } catch (Exception e) { } catch (Exception e) {
87 121 throw new RuntimeException(e); throw new RuntimeException(e);
88 122 } }
 
... ... final class RendererAA extends Renderer
90 124
91 125 @Override public final void run() @Override public final void run()
92 126 { {
127 validate();
93 128 glClearColor(0.0f, 0.0f, 95.0f / 255.0f, 0.0f); glClearColor(0.0f, 0.0f, 95.0f / 255.0f, 0.0f);
129 validate();
94 130 glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
131 validate();
95 132
96 glUseProgram(programHandle);
133 validate();
134 program.apply();
135 validate();
97 136
98 137 glBindBuffer(GL_ARRAY_BUFFER, bufferHandle); glBindBuffer(GL_ARRAY_BUFFER, bufferHandle);
138 validate();
139 glBufferData(GL_ARRAY_BUFFER, floatBuffer, GL_STATIC_DRAW);
140 validate();
99 141 glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
142 validate();
100 143 glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0); glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
144 validate();
101 145
102 146 glDrawArrays(GL_TRIANGLES, 0, 3); glDrawArrays(GL_TRIANGLES, 0, 3);
147 validate();
103 148
104 149 glDisableVertexAttribArray(0); glDisableVertexAttribArray(0);
105 glUseProgram(GL_FALSE);
150 validate();
151 program.unapply();
106 152 } }
107 153 } }
File src/org.jgltut.tutaa/src/org/jgltut/tutaa/ShaderProgram.java added (mode: 100644) (index 0000000..10bb03e)
1 package org.jgltut.tutaa;
2
3 import static org.lwjgl.opengl.GL33C.GL_FALSE;
4 import static org.lwjgl.opengl.GL33C.GL_TRUE;
5 import static org.lwjgl.opengl.GL33C.GL_VALIDATE_STATUS;
6 import static org.lwjgl.opengl.GL33C.glDeleteProgram;
7 import static org.lwjgl.opengl.GL33C.glGetAttribLocation;
8 import static org.lwjgl.opengl.GL33C.glGetProgramInfoLog;
9 import static org.lwjgl.opengl.GL33C.glGetProgrami;
10 import static org.lwjgl.opengl.GL33C.glIsProgram;
11 import static org.lwjgl.opengl.GL33C.glUseProgram;
12 import static org.lwjgl.opengl.GL33C.glValidateProgram;
13
14 final class ShaderProgram implements AutoCloseable
15 {
16 private boolean isClosed = false;
17
18 private final int programHandle;
19
20 ShaderProgram(final int programHandle)
21 {
22 this.programHandle = programHandle;
23 }
24
25 @Override public final void close()
26 {
27 if (isClosed) {
28 throw new IllegalStateException("already closed");
29 }
30 isClosed = true;
31 glDeleteProgram(programHandle);
32 }
33
34 public final void validate() throws IllegalStateException
35 {
36 if (isClosed) {
37 throw new IllegalStateException("already closed");
38 }
39 if (!glIsProgram(programHandle)) {
40 throw new IllegalStateException("not a program");
41 }
42 glValidateProgram(programHandle);
43 int res = glGetProgrami(programHandle, GL_VALIDATE_STATUS);
44 if (GL_TRUE != res) {
45 final int maxLength = 256;
46 final String logContent =
47 glGetProgramInfoLog(programHandle, maxLength);
48 final String msg = "invalid program:\n" + logContent;
49 throw new IllegalStateException(msg);
50 }
51 }
52
53 public final void apply()
54 {
55 if (isClosed) {
56 throw new IllegalStateException("already closed");
57 }
58 glUseProgram(programHandle);
59 }
60
61 protected final int getAttributeLocation(final String name)
62 {
63 if (isClosed) {
64 throw new IllegalStateException("already closed");
65 }
66 assert (name != null);
67 assert (!name.isEmpty());
68 return glGetAttribLocation(programHandle, name);
69 }
70
71 public final void unapply()
72 {
73 if (isClosed) {
74 throw new IllegalStateException("already closed");
75 }
76 glUseProgram(GL_FALSE);
77 }
78 }
File src/org.jgltut.tutaa/src/org/jgltut/tutaa/ShaderProgramBuilder.java added (mode: 100644) (index 0000000..9602d9a)
1 package org.jgltut.tutaa;
2
3 import static org.lwjgl.opengl.GL33C.GL_FALSE;
4 import static org.lwjgl.opengl.GL33C.GL_FRAGMENT_SHADER;
5 import static org.lwjgl.opengl.GL33C.GL_LINK_STATUS;
6 import static org.lwjgl.opengl.GL33C.GL_TRUE;
7 import static org.lwjgl.opengl.GL33C.GL_VERTEX_SHADER;
8 import static org.lwjgl.opengl.GL33C.glAttachShader;
9 import static org.lwjgl.opengl.GL33C.glAttachShader;
10 import static org.lwjgl.opengl.GL33C.glCompileShader;
11 import static org.lwjgl.opengl.GL33C.glCreateProgram;
12 import static org.lwjgl.opengl.GL33C.glCreateShader;
13 import static org.lwjgl.opengl.GL33C.glDeleteShader;
14 import static org.lwjgl.opengl.GL33C.glGetProgramInfoLog;
15 import static org.lwjgl.opengl.GL33C.glGetProgrami;
16 import static org.lwjgl.opengl.GL33C.glIsProgram;
17 import static org.lwjgl.opengl.GL33C.glIsShader;
18 import static org.lwjgl.opengl.GL33C.glLinkProgram;
19 import static org.lwjgl.opengl.GL33C.glShaderSource;
20
21 final class ShaderProgramBuilder
22 {
23 private ShaderProgram program;
24 private String shaderFragSrc;
25 private String shaderVertSrc;
26 private int programHandle;
27 private int shaderFragHandle;
28 private int shaderVertHandle;
29
30 ShaderProgramBuilder()
31 {
32 program = null;
33 shaderFragSrc = null;
34 shaderVertSrc = null;
35 programHandle = GL_FALSE;
36 shaderFragHandle = GL_FALSE;
37 shaderVertHandle = GL_FALSE;
38 }
39
40 public final void setShaderFragSrc(final String src)
41 {
42 if (null == src || src.isEmpty()) {
43 throw new IllegalArgumentException();
44 }
45 if (null == shaderFragSrc) {
46 shaderFragSrc = src;
47 } else {
48 final String msg = "cannot overwrite source";
49 throw new IllegalStateException(msg);
50 }
51 }
52
53 public final void setShaderVertSrc(final String src)
54 {
55 if (null == src || src.isEmpty()) {
56 throw new IllegalArgumentException();
57 }
58 if (null == shaderVertSrc) {
59 shaderVertSrc = src;
60 } else {
61 final String msg = "cannot overwrite source";
62 throw new IllegalStateException(msg);
63 }
64 }
65
66 private final int createShader(final int shaderType, final String src)
67 {
68 final int shaderHandle = glCreateShader(shaderType);
69 glShaderSource(shaderHandle, src);
70 glCompileShader(shaderHandle);
71 if (!glIsShader(shaderHandle)) {
72 throw new IllegalStateException("not a shader");
73 }
74 return shaderHandle;
75 }
76
77 private final void verify()
78 {
79 assert (shaderFragSrc != null && !shaderFragSrc.isEmpty());
80 assert (shaderVertSrc != null && !shaderVertSrc.isEmpty());
81 assert (null == program);
82 }
83
84 private final void validate() throws IllegalStateException
85 {
86 if (!glIsProgram(programHandle)) {
87 throw new IllegalStateException("not a program");
88 }
89 final int linkStatus =
90 glGetProgrami(programHandle, GL_LINK_STATUS);
91 if (GL_TRUE != linkStatus) {
92 final int maxLength = 256;
93 final String logContent =
94 glGetProgramInfoLog(programHandle, maxLength);
95 final String msg =
96 "could not link program:\n" + logContent;
97 throw new IllegalStateException(msg);
98 }
99 }
100
101 public final ShaderProgram get() throws Exception
102 {
103 if (program != null) {
104 return program;
105 }
106 verify();
107 shaderFragHandle =
108 createShader(GL_FRAGMENT_SHADER, shaderFragSrc);
109 shaderVertHandle =
110 createShader(GL_VERTEX_SHADER, shaderVertSrc);
111 programHandle = glCreateProgram();
112 glAttachShader(programHandle, shaderFragHandle);
113 glAttachShader(programHandle, shaderVertHandle);
114 glLinkProgram(programHandle);
115 glDeleteShader(shaderFragHandle);
116 glDeleteShader(shaderVertHandle);
117 validate();
118 program = new ShaderProgram(programHandle);
119 try {
120 program.validate();
121 } catch (Exception e) {
122 program.close();
123 throw e;
124 }
125 return program;
126 }
127 }
File src/org.jgltut.tutaa/src/org/jgltut/tutaa/ShaderReader.java added (mode: 100644) (index 0000000..505ffa4)
1 package org.jgltut.tutaa;
2
3 import java.io.InputStream;
4 import java.nio.ByteBuffer;
5 import java.nio.CharBuffer;
6 import java.nio.charset.Charset;
7 import java.nio.charset.CharsetDecoder;
8 import java.nio.charset.StandardCharsets;
9
10 final class ShaderReader
11 {
12 ShaderReader()
13 {
14 }
15
16 public final <T> String apply(final Class<T> rendererType,
17 final ShaderType shaderType)
18 throws IllegalArgumentException, IllegalStateException
19 {
20 if (null == rendererType) {
21 throw new IllegalArgumentException("empty argument");
22 }
23
24 if (null == shaderType) {
25 throw new IllegalArgumentException("empty argument");
26 }
27
28 final String resourceName = "Shader" +
29 rendererType.getSimpleName() + "." +
30 shaderType.getFileExtension();
31 final int capacity = 2048;
32 final String resourceContent;
33 try (final InputStream stream =
34 rendererType.getResourceAsStream(resourceName)) {
35 /* Use ByteBuffer#allocate specifically
36 * to ensure backing array is available. */
37 final ByteBuffer buffer = ByteBuffer.allocate(capacity);
38 int a = stream.available();
39 if (a <= 0) {
40 throw new IllegalStateException(
41 "empty shader source file");
42 }
43 while (a > 0) {
44 if (buffer.remaining() < a) {
45 throw new IllegalStateException(
46 "insufficient buffer capacity");
47 }
48 if (!buffer.hasArray()) {
49 throw new IllegalStateException(
50 "buffer backing array inaccessible");
51 }
52 stream.read(buffer.array(),
53 buffer.arrayOffset(), a);
54 a = stream.available();
55 }
56 buffer.compact();
57
58 final String charsetName =
59 StandardCharsets.UTF_8.name();
60 if (!Charset.isSupported(charsetName)) {
61 throw new IllegalStateException(
62 " charset not supported");
63 }
64 final Charset charset = Charset.forName(charsetName);
65 final CharsetDecoder decoder = charset.newDecoder();
66 final CharBuffer charBuffer = decoder.decode(buffer);
67 resourceContent = charBuffer.toString();
68 } catch (Exception e) {
69 final String msg = "could not read shader source";
70 throw new IllegalStateException(msg, e);
71 }
72
73 if (null == resourceContent || resourceContent.isEmpty()) {
74 throw new IllegalStateException();
75 }
76 return resourceContent;
77 }
78 }
File src/org.jgltut.tutaa/src/org/jgltut/tutaa/ShaderType.java added (mode: 100644) (index 0000000..9a625ee)
1 package org.jgltut.tutaa;
2
3 /**
4 * ShaderType enum lists OpenGL types of shaders supported by the framework.
5 */
6 enum ShaderType {
7 VERT {
8 @Override public final String getFileExtension()
9 {
10 return "vert";
11 }
12 },
13 FRAG {
14 @Override public final String getFileExtension()
15 {
16 return "frag";
17 }
18 };
19
20 abstract String getFileExtension();
21 }
22
File src/org.jgltut.tutaa/src/org/jgltut/tutaa/Stage.java changed (mode: 100644) (index 26e3a2b..c46eb03)
1 1 package org.jgltut.tutaa; package org.jgltut.tutaa;
2 2
3 import org.lwjgl.PointerBuffer;
4 import org.lwjgl.glfw.Callbacks;
3 5 import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
4 6 import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
5 7
 
... ... final class Stage implements AutoCloseable
30 32
31 33 @Override public final void close() @Override public final void close()
32 34 { {
35 Callbacks.glfwFreeCallbacks(windowHandle);
33 36 GLFW.glfwDestroyWindow(windowHandle); GLFW.glfwDestroyWindow(windowHandle);
34 37 GLFW.glfwTerminate(); GLFW.glfwTerminate();
35 38 } }
 
... ... final class Stage implements AutoCloseable
61 64 GLFW.glfwSwapBuffers(windowHandle); GLFW.glfwSwapBuffers(windowHandle);
62 65 GLFW.glfwPollEvents(); GLFW.glfwPollEvents();
63 66 } }
67
68 public final void validate() throws IllegalStateException
69 {
70 final PointerBuffer discardErrorMessage = null;
71 int someErrorCode = GLFW.glfwGetError(discardErrorMessage);
72 if (GLFW.GLFW_NO_ERROR != someErrorCode) {
73 throw new IllegalStateException("GLFW error");
74 }
75 }
64 76 } }
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/vrtc/jgltut

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/vrtc/jgltut

Clone this repository using git:
git clone git://git.rocketgit.com/user/vrtc/jgltut

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main