Roi Atalla avatar Roi Atalla committed 96b4e2d

Created gl32 package and ported most of the code over.

Comments (0)

Files changed (34)

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter1/Example1_1.java

+package com.ra4king.opengl.arcsynthesis.gl32.chapter1;
+
+import static org.lwjgl.opengl.GL11.*;
+import static org.lwjgl.opengl.GL15.*;
+import static org.lwjgl.opengl.GL20.*;
+import static org.lwjgl.opengl.GL30.*;
+
+import java.nio.FloatBuffer;
+
+import org.lwjgl.BufferUtils;
+
+import com.ra4king.opengl.GLProgram;
+
+public class Example1_1 extends GLProgram {
+	public static void main(String[] args) {
+		new Example1_1().run(3,2);
+	}
+	
+	private int program, vbo;
+	
+	public Example1_1() {
+		super("Example 1.1", 500, 500, false);
+	}
+	
+	@Override
+	public void init() {
+		glClearColor(0, 0, 0, 0);
+		
+		int vs = glCreateShader(GL_VERTEX_SHADER);
+		glShaderSource(vs, readFromFile("example1.1.vert"));
+		
+		glCompileShader(vs);
+		
+		if(glGetShader(vs, GL_COMPILE_STATUS) == GL_FALSE) {
+			System.err.println("Failure in compiling vertex shader. Error log:\n" + glGetShaderInfoLog(vs, glGetShader(vs, GL_INFO_LOG_LENGTH)));
+			System.exit(0);
+		}
+		
+		int fs = glCreateShader(GL_FRAGMENT_SHADER);
+		glShaderSource(fs, readFromFile("example1.1.frag"));
+		
+		glCompileShader(fs);
+		
+		if(glGetShader(fs, GL_COMPILE_STATUS) == GL_FALSE) {
+			System.err.println("Failure in compiling fragment shader. Error log:\n" + glGetShaderInfoLog(fs, glGetShader(fs, GL_INFO_LOG_LENGTH)));
+			destroy();
+		}
+		
+		program = glCreateProgram();
+		glAttachShader(program, vs);
+		glAttachShader(program, fs);
+		
+		glBindAttribLocation(program, 0, "position");
+		
+		glLinkProgram(program);
+		
+		if(glGetProgram(program, GL_LINK_STATUS) == GL_FALSE) {
+			System.err.println("Failure in linking program. Error log:\n" + glGetProgramInfoLog(program, glGetProgram(program, GL_INFO_LOG_LENGTH)));
+			destroy();
+		}
+		
+		glDetachShader(program, vs);
+		glDetachShader(program, fs);
+		
+		glDeleteShader(vs);
+		glDeleteShader(fs);
+		
+		vbo = glGenBuffers();
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glBufferData(GL_ARRAY_BUFFER, (FloatBuffer)BufferUtils.createFloatBuffer(24).put(new float[] { 0.75f,  0.75f, 0.0f, 1.0f,
+																									   0.75f, -0.75f, 0.0f, 1.0f,
+																									  -0.75f, -0.75f, 0.0f, 1.0f}).flip(),GL_STATIC_DRAW);
+		
+		glBindVertexArray(glGenVertexArrays());
+		
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+	}
+	
+	@Override
+	public void render() {
+		glClear(GL_COLOR_BUFFER_BIT);
+		
+		glUseProgram(program);
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glEnableVertexAttribArray(0);
+		glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
+		
+		glDrawArrays(GL_TRIANGLES, 0, 3);
+		
+		glDisableVertexAttribArray(0);
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		
+		glUseProgram(0);
+	}
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter1/example1.1.frag

+#version 150
+
+out vec4 outputColor;
+
+void main()
+{
+	outputColor = vec4(1,1,1,1);
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter1/example1.1.vert

+#version 150
+
+in vec4 position;
+
+void main()
+{
+	gl_Position = position;
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter2/example1/Example2_1.java

+package com.ra4king.opengl.arcsynthesis.gl32.chapter2.example1;
+
+import static org.lwjgl.opengl.GL11.*;
+import static org.lwjgl.opengl.GL15.*;
+import static org.lwjgl.opengl.GL20.*;
+import static org.lwjgl.opengl.GL30.*;
+
+import java.nio.FloatBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.lwjgl.BufferUtils;
+
+import com.ra4king.opengl.GLProgram;
+import com.ra4king.opengl.util.ShaderProgram;
+
+public class Example2_1 extends GLProgram {
+	public static void main(String[] args) {
+		new Example2_1().run(3,2);
+	}
+	
+	private ShaderProgram program;
+	private int vbo;
+	
+	public Example2_1() {
+		super("Example 2.1", 500, 500, false);
+	}
+	
+	@Override
+	public void init() {
+		glClearColor(0, 0, 0, 0);
+		
+		Map<Integer,String> attributes = new HashMap<Integer,String>();
+		attributes.put(0, "position");
+		program = new ShaderProgram(readFromFile("example2.1.vert"),readFromFile("example2.1.frag"),attributes);
+		
+		vbo = glGenBuffers();
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glBufferData(GL_ARRAY_BUFFER, (FloatBuffer)BufferUtils.createFloatBuffer(12).put(new float[] { 0.75f,  0.75f, 0.0f, 1.0f,
+																									   0.75f, -0.75f, 0.0f, 1.0f,
+																									  -0.75f, -0.75f, 0.0f, 1.0f}).flip(),GL_STATIC_DRAW);
+		
+		glBindVertexArray(glGenVertexArrays());
+		
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+	}
+	
+	@Override
+	public void render() {
+		glClear(GL_COLOR_BUFFER_BIT);
+		
+		program.begin();
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glEnableVertexAttribArray(0);
+		glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
+		
+		glDrawArrays(GL_TRIANGLES, 0, 3);
+		
+		glDisableVertexAttribArray(0);
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		
+		program.end();
+	}
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter2/example1/example2.1.frag

+#version 150
+
+out vec4 outputColor;
+
+void main()
+{
+    float lerpValue = gl_FragCoord.y / 600.0f;
+        
+    outputColor = mix(vec4(1.0f, 1.0f, 1.0f, 1.0f), vec4(0.2f, 0.2f, 0.2f, 1.0f), lerpValue);
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter2/example1/example2.1.vert

+#version 150
+
+in vec4 position;
+
+void main()
+{
+	gl_Position = position;
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter2/example2/Example2_2.java

+package com.ra4king.opengl.arcsynthesis.gl32.chapter2.example2;
+
+import static org.lwjgl.opengl.GL11.*;
+import static org.lwjgl.opengl.GL15.*;
+import static org.lwjgl.opengl.GL20.*;
+import static org.lwjgl.opengl.GL30.*;
+
+import java.nio.FloatBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.lwjgl.BufferUtils;
+
+import com.ra4king.opengl.GLProgram;
+import com.ra4king.opengl.util.ShaderProgram;
+
+public class Example2_2 extends GLProgram {
+	public static void main(String[] args) {
+		new Example2_2().run(3,2);
+	}
+	
+	private ShaderProgram program;
+	private int vbo;
+	
+	public Example2_2() {
+		super("Example 2.2", 500, 500, false);
+	}
+	
+	@Override
+	public void init() {
+		glClearColor(0, 0, 0, 0);
+		
+		Map<Integer,String> attributes = new HashMap<Integer,String>();
+		attributes.put(0, "position");
+		attributes.put(1, "color");
+		program = new ShaderProgram(readFromFile("example2.2.vert"),readFromFile("example2.2.frag"),attributes);
+		
+		vbo = glGenBuffers();
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glBufferData(GL_ARRAY_BUFFER, (FloatBuffer)BufferUtils.createFloatBuffer(24).put(new float[] { 0.0f,    0.5f, 0.0f, 1.0f,
+																									   0.5f, -0.366f, 0.0f, 1.0f,
+																									  -0.5f, -0.366f, 0.0f, 1.0f,
+																									   1.0f,    0.0f, 0.0f, 1.0f,
+																									   0.0f,    1.0f, 0.0f, 1.0f,
+																									   0.0f,    0.0f, 1.0f, 1.0f}).flip(),GL_STATIC_DRAW);
+		
+		glBindVertexArray(glGenVertexArrays());
+		
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+	}
+	
+	@Override
+	public void render() {
+		glClear(GL_COLOR_BUFFER_BIT);
+		
+		program.begin();
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glEnableVertexAttribArray(0);
+		glEnableVertexAttribArray(1);
+		glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
+		glVertexAttribPointer(1, 4, GL_FLOAT, false, 0, 48);
+		
+		glDrawArrays(GL_TRIANGLES, 0, 3);
+		
+		glDisableVertexAttribArray(0);
+		glDisableVertexAttribArray(1);
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		
+		program.end();
+	}
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter2/example2/example2.2.frag

+#version 150
+
+smooth in vec4 theColor;
+
+out vec4 outputColor;
+
+void main()
+{
+	outputColor = theColor;
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter2/example2/example2.2.vert

+#version 150
+
+in vec4 position;
+in vec4 color;
+
+smooth out vec4 theColor;
+
+void main()
+{
+	gl_Position = position;
+	theColor = color;
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter3/example1/Example3_1.java

+package com.ra4king.opengl.arcsynthesis.gl32.chapter3.example1;
+
+import static org.lwjgl.opengl.GL11.*;
+import static org.lwjgl.opengl.GL15.*;
+import static org.lwjgl.opengl.GL20.*;
+import static org.lwjgl.opengl.GL30.*;
+
+import java.nio.FloatBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.lwjgl.BufferUtils;
+
+import com.ra4king.opengl.GLProgram;
+import com.ra4king.opengl.util.ShaderProgram;
+
+public class Example3_1 extends GLProgram {
+	public static void main(String[] args) {
+		new Example3_1().run(3,2);
+	}
+	
+	private ShaderProgram program;
+	
+	private FloatBuffer vertexData, newData;
+	private int vbo;
+	
+	private long elapsedTime;
+	
+	public Example3_1() {
+		super("Example 3.1", 500, 500, false);
+	}
+	
+	@Override
+	public void init() {
+		glClearColor(0, 0, 0, 0);
+		
+		Map<Integer,String> attributes = new HashMap<Integer,String>();
+		attributes.put(0, "position");
+		program = new ShaderProgram(readFromFile("example3.1.vert"),readFromFile("example3.1.frag"),attributes);
+		
+		vbo = glGenBuffers();
+		
+		vertexData = (FloatBuffer)BufferUtils.createFloatBuffer(12).put(new float[] { 0.25f,  0.25f, 0.0f, 1.0f,
+																					  0.25f, -0.25f, 0.0f, 1.0f,
+																					 -0.25f, -0.25f, 0.0f, 1.0f}).flip();
+		newData = BufferUtils.createFloatBuffer(12);
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STREAM_DRAW);
+		
+		glBindVertexArray(glGenVertexArrays());
+		
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+	}
+	
+	@Override
+	public void update(long deltaTime) {
+		elapsedTime += deltaTime;
+		
+		float loopDuration = 5;
+		float scale = (float)Math.PI * 2 / loopDuration;
+		float currentTimeThroughLoop = (elapsedTime/(float)1e9) % loopDuration;
+		
+		float xOffset = (float)Math.cos(currentTimeThroughLoop * scale) * 0.5f;
+		float yOffset = (float)Math.sin(currentTimeThroughLoop * scale) * 0.5f;
+		
+		newData.clear();
+		
+		for(int a = 0; a < 12; a += 4) {
+			newData.put(vertexData.get(a) + xOffset);
+			newData.put(vertexData.get(a+1) + yOffset);
+			newData.put(0);
+			newData.put(1);
+		}
+		
+		newData.flip();
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glBufferSubData(GL_ARRAY_BUFFER, 0, newData);
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+	}
+	
+	@Override
+	public void render() {
+		glClear(GL_COLOR_BUFFER_BIT);
+		
+		program.begin();
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glEnableVertexAttribArray(0);
+		glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
+		
+		glDrawArrays(GL_TRIANGLES, 0, 3);
+		
+		glDisableVertexAttribArray(0);
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		
+		program.end();
+	}
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter3/example1/example3.1.frag

+#version 150
+
+out vec4 outputColor;
+
+void main()
+{
+	outputColor = vec4(1, 1, 1, 1);
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter3/example1/example3.1.vert

+#version 150
+
+in vec4 position;
+
+void main()
+{
+	gl_Position = position;
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter3/example2/Example3_2.java

+package com.ra4king.opengl.arcsynthesis.gl32.chapter3.example2;
+
+import static org.lwjgl.opengl.GL11.*;
+import static org.lwjgl.opengl.GL15.*;
+import static org.lwjgl.opengl.GL20.*;
+import static org.lwjgl.opengl.GL30.*;
+
+import java.nio.FloatBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.lwjgl.BufferUtils;
+
+import com.ra4king.opengl.GLProgram;
+import com.ra4king.opengl.util.ShaderProgram;
+
+public class Example3_2 extends GLProgram {
+	public static void main(String[] args) {
+		new Example3_2().run(3,2);
+	}
+	
+	private ShaderProgram program;
+	private int offsetLocation;
+	private int vbo;
+	
+	private long elapsedTime;
+	
+	public Example3_2() {
+		super("Example 3.2", 500, 500, false);
+	}
+	
+	@Override
+	public void init() {
+		glClearColor(0, 0, 0, 0);
+		
+		Map<Integer,String> attributes = new HashMap<Integer,String>();
+		attributes.put(0, "position");
+		program = new ShaderProgram(readFromFile("example3.2.vert"),readFromFile("example3.2.frag"),attributes);
+		offsetLocation = glGetUniformLocation(program.getProgram(), "offset");
+		
+		vbo = glGenBuffers();
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glBufferData(GL_ARRAY_BUFFER, (FloatBuffer)BufferUtils.createFloatBuffer(12).put(new float[] { 0.25f,  0.25f, 0.0f, 1.0f,
+																									   0.25f, -0.25f, 0.0f, 1.0f,
+																									  -0.25f, -0.25f, 0.0f, 1.0f}).flip(), GL_STATIC_DRAW);
+		
+		glBindVertexArray(glGenVertexArrays());
+		
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+	}
+	
+	@Override
+	public void update(long deltaTime) {
+		elapsedTime += deltaTime;
+	}
+	
+	@Override
+	public void render() {
+		float loopDuration = 5;
+		float scale = (float)Math.PI * 2 / loopDuration;
+		float currentTimeThroughLoop = (elapsedTime/(float)1e9) % loopDuration;
+		
+		float xOffset = (float)Math.cos(currentTimeThroughLoop * scale) * 0.5f;
+		float yOffset = (float)Math.sin(currentTimeThroughLoop * scale) * 0.5f;
+		
+		glClear(GL_COLOR_BUFFER_BIT);
+		
+		program.begin();
+		
+		glUniform2f(offsetLocation, xOffset, yOffset);
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glEnableVertexAttribArray(0);
+		glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
+		
+		glDrawArrays(GL_TRIANGLES, 0, 3);
+		
+		glDisableVertexAttribArray(0);
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		
+		program.end();
+	}
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter3/example2/example3.2.frag

+#version 150
+
+out vec4 outputColor;
+
+void main()
+{
+	outputColor = vec4(1, 1, 1, 1);
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter3/example2/example3.2.vert

+#version 150
+
+in vec4 position;
+uniform vec2 offset;
+
+void main()
+{
+	gl_Position = position + vec4(offset, 0, 0);
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter3/example3/Example3_3.java

+package com.ra4king.opengl.arcsynthesis.gl32.chapter3.example3;
+
+import static org.lwjgl.opengl.GL11.*;
+import static org.lwjgl.opengl.GL15.*;
+import static org.lwjgl.opengl.GL20.*;
+import static org.lwjgl.opengl.GL30.*;
+
+import java.nio.FloatBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.lwjgl.BufferUtils;
+
+import com.ra4king.opengl.GLProgram;
+import com.ra4king.opengl.util.ShaderProgram;
+
+public class Example3_3 extends GLProgram {
+	public static void main(String[] args) {
+		new Example3_3().run(3,2);
+	}
+	
+	private ShaderProgram program;
+	private int timeLocation;
+	private int vbo;
+	
+	private long elapsedTime;
+	
+	public Example3_3() {
+		super("Example 3.3", 500, 500, false);
+	}
+	
+	@Override
+	public void init() {
+		glClearColor(0, 0, 0, 0);
+		
+		Map<Integer,String> attributes = new HashMap<Integer,String>();
+		attributes.put(0, "position");
+		program = new ShaderProgram(readFromFile("example3.3.vert"),readFromFile("example3.3.frag"),attributes);
+		timeLocation = glGetUniformLocation(program.getProgram(), "time");
+		
+		int loopDurationLocation = glGetUniformLocation(program.getProgram(), "loopDuration");
+		program.begin();
+		glUniform1f(loopDurationLocation, 5);
+		program.end();
+		
+		vbo = glGenBuffers();
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glBufferData(GL_ARRAY_BUFFER, (FloatBuffer)BufferUtils.createFloatBuffer(12).put(new float[] { 0.25f,  0.25f, 0.0f, 1.0f,
+																									   0.25f, -0.25f, 0.0f, 1.0f,
+																									  -0.25f, -0.25f, 0.0f, 1.0f}).flip(), GL_STATIC_DRAW);
+		
+		glBindVertexArray(glGenVertexArrays());
+		
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+	}
+	
+	@Override
+	public void update(long deltaTime) {
+		elapsedTime += deltaTime;
+	}
+	
+	@Override
+	public void render() {
+		glClear(GL_COLOR_BUFFER_BIT);
+		
+		program.begin();
+		
+		glUniform1f(timeLocation, elapsedTime/(float)1e9);
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glEnableVertexAttribArray(0);
+		glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
+		
+		glDrawArrays(GL_TRIANGLES, 0, 3);
+		
+		glDisableVertexAttribArray(0);
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		
+		program.end();
+	}
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter3/example3/example3.3.frag

+#version 150
+
+out vec4 outputColor;
+
+void main()
+{
+	outputColor = vec4(1, 1, 1, 1);
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter3/example3/example3.3.vert

+#version 150
+
+in vec4 position;
+uniform float loopDuration;
+uniform float time;
+
+void main()
+{
+	float timeScale = 3.14159f * 2.0f / loopDuration;
+	
+	float currTime = mod(time, loopDuration);
+	
+	gl_Position = position + vec4(cos(currTime * timeScale) * 0.5f,
+								  sin(currTime * timeScale) * 0.5f,
+								  0.0f,
+								  0.0f);
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter3/example4/Example3_4.java

+package com.ra4king.opengl.arcsynthesis.gl32.chapter3.example4;
+
+import static org.lwjgl.opengl.GL11.*;
+import static org.lwjgl.opengl.GL15.*;
+import static org.lwjgl.opengl.GL20.*;
+import static org.lwjgl.opengl.GL30.*;
+
+import java.nio.FloatBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.lwjgl.BufferUtils;
+
+import com.ra4king.opengl.GLProgram;
+import com.ra4king.opengl.util.ShaderProgram;
+
+public class Example3_4 extends GLProgram {
+	public static void main(String[] args) {
+		new Example3_4().run(3,2);
+	}
+	
+	private ShaderProgram program;
+	private int timeLocation;
+	private int vbo;
+	
+	private long elapsedTime;
+	
+	public Example3_4() {
+		super("Example 3.4", 500, 500, false);
+	}
+	
+	@Override
+	public void init() {
+		glClearColor(0, 0, 0, 0);
+		
+		Map<Integer,String> attributes = new HashMap<Integer,String>();
+		attributes.put(0, "position");
+		program = new ShaderProgram(readFromFile("example3.4.vert"),readFromFile("example3.4.frag"),attributes);
+		timeLocation = glGetUniformLocation(program.getProgram(), "time");
+		
+		int loopDurationLocation = glGetUniformLocation(program.getProgram(), "loopDuration");
+		int fragLoopDuration = glGetUniformLocation(program.getProgram(), "fragLoopDuration");
+		program.begin();
+		glUniform1f(loopDurationLocation, 5);
+		glUniform1f(fragLoopDuration, 10);
+		program.end();
+		
+		vbo = glGenBuffers();
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glBufferData(GL_ARRAY_BUFFER, (FloatBuffer)BufferUtils.createFloatBuffer(12).put(new float[] { 0.25f,  0.25f, 0.0f, 1.0f,
+																									   0.25f, -0.25f, 0.0f, 1.0f,
+																									  -0.25f, -0.25f, 0.0f, 1.0f}).flip(), GL_STATIC_DRAW);
+		
+		glBindVertexArray(glGenVertexArrays());
+		
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+	}
+	
+	@Override
+	public void update(long deltaTime) {
+		elapsedTime += deltaTime;
+	}
+	
+	@Override
+	public void render() {
+		glClear(GL_COLOR_BUFFER_BIT);
+		
+		program.begin();
+		
+		glUniform1f(timeLocation, elapsedTime/(float)1e9);
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glEnableVertexAttribArray(0);
+		glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
+		
+		glDrawArrays(GL_TRIANGLES, 0, 3);
+		
+		glDisableVertexAttribArray(0);
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		
+		program.end();
+	}
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter3/example4/example3.4.frag

+#version 150
+
+out vec4 outputColor;
+
+uniform float fragLoopDuration;
+uniform float time;
+
+const vec4 firstColor = vec4(1, 1, 1, 1);
+const vec4 secondColor = vec4(0, 1, 0, 1);
+
+void main()
+{
+	float currTime = mod(time, fragLoopDuration);
+	float currLerp = currTime/ fragLoopDuration;
+	
+	outputColor = mix(firstColor, secondColor, currLerp);
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter3/example4/example3.4.vert

+#version 150
+
+in vec4 position;
+uniform float loopDuration;
+uniform float time;
+
+void main()
+{
+	float timeScale = 3.14159f * 2.0f / loopDuration;
+	
+	float currTime = mod(time, loopDuration);
+	
+	gl_Position = position + vec4(cos(currTime * timeScale) * 0.5f,
+								  sin(currTime * timeScale) * 0.5f,
+								  0.0f,
+								  0.0f);
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter4/example1/Example4_1.java

+package com.ra4king.opengl.arcsynthesis.gl32.chapter4.example1;
+
+import java.nio.FloatBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.lwjgl.BufferUtils;
+
+import com.ra4king.opengl.GLProgram;
+import com.ra4king.opengl.util.ShaderProgram;
+
+import static org.lwjgl.opengl.GL11.*;
+import static org.lwjgl.opengl.GL15.*;
+import static org.lwjgl.opengl.GL20.*;
+import static org.lwjgl.opengl.GL30.*;
+
+public class Example4_1 extends GLProgram {
+	public static void main(String[] args) {
+		new Example4_1().run(3,2);
+	}
+	
+	private final float[] data = {
+			 0.25f,  0.25f, 0.75f, 1.0f,
+			 0.25f, -0.25f, 0.75f, 1.0f,
+			-0.25f,  0.25f, 0.75f, 1.0f,
+			
+			 0.25f, -0.25f, 0.75f, 1.0f,
+			-0.25f, -0.25f, 0.75f, 1.0f,
+			-0.25f,  0.25f, 0.75f, 1.0f,
+			
+			 0.25f,  0.25f, -0.75f, 1.0f,
+			-0.25f,  0.25f, -0.75f, 1.0f,
+			 0.25f, -0.25f, -0.75f, 1.0f,
+			
+			 0.25f, -0.25f, -0.75f, 1.0f,
+			-0.25f,  0.25f, -0.75f, 1.0f,
+			-0.25f, -0.25f, -0.75f, 1.0f,
+			
+			-0.25f,  0.25f,  0.75f, 1.0f,
+			-0.25f, -0.25f,  0.75f, 1.0f,
+			-0.25f, -0.25f, -0.75f, 1.0f,
+			
+			-0.25f,  0.25f,  0.75f, 1.0f,
+			-0.25f, -0.25f, -0.75f, 1.0f,
+			-0.25f,  0.25f, -0.75f, 1.0f,
+			
+			 0.25f,  0.25f,  0.75f, 1.0f,
+			 0.25f, -0.25f, -0.75f, 1.0f,
+			 0.25f, -0.25f,  0.75f, 1.0f,
+			 
+			 0.25f,  0.25f,  0.75f, 1.0f,
+			 0.25f,  0.25f, -0.75f, 1.0f,
+			 0.25f, -0.25f, -0.75f, 1.0f,
+			 
+			 0.25f,  0.25f, -0.75f, 1.0f,
+			 0.25f,  0.25f,  0.75f, 1.0f,
+			-0.25f,  0.25f,  0.75f, 1.0f,
+			
+			 0.25f,  0.25f, -0.75f, 1.0f,
+			-0.25f,  0.25f,  0.75f, 1.0f,
+			-0.25f,  0.25f, -0.75f, 1.0f,
+			
+			 0.25f, -0.25f, -0.75f, 1.0f,
+			-0.25f, -0.25f,  0.75f, 1.0f,
+			 0.25f, -0.25f,  0.75f, 1.0f,
+			 
+			 0.25f, -0.25f, -0.75f, 1.0f,
+			-0.25f, -0.25f, -0.75f, 1.0f,
+			-0.25f, -0.25f,  0.75f, 1.0f,
+			
+			0.0f, 0.0f, 1.0f, 1.0f,
+			0.0f, 0.0f, 1.0f, 1.0f,
+			0.0f, 0.0f, 1.0f, 1.0f,
+			
+			0.0f, 0.0f, 1.0f, 1.0f,
+			0.0f, 0.0f, 1.0f, 1.0f,
+			0.0f, 0.0f, 1.0f, 1.0f,
+			
+			0.8f, 0.8f, 0.8f, 1.0f,
+			0.8f, 0.8f, 0.8f, 1.0f,
+			0.8f, 0.8f, 0.8f, 1.0f,
+			
+			0.8f, 0.8f, 0.8f, 1.0f,
+			0.8f, 0.8f, 0.8f, 1.0f,
+			0.8f, 0.8f, 0.8f, 1.0f,
+			
+			0.0f, 1.0f, 0.0f, 1.0f,
+			0.0f, 1.0f, 0.0f, 1.0f,
+			0.0f, 1.0f, 0.0f, 1.0f,
+			
+			0.0f, 1.0f, 0.0f, 1.0f,
+			0.0f, 1.0f, 0.0f, 1.0f,
+			0.0f, 1.0f, 0.0f, 1.0f,
+			
+			0.5f, 0.5f, 0.0f, 1.0f,
+			0.5f, 0.5f, 0.0f, 1.0f,
+			0.5f, 0.5f, 0.0f, 1.0f,
+			
+			0.5f, 0.5f, 0.0f, 1.0f,
+			0.5f, 0.5f, 0.0f, 1.0f,
+			0.5f, 0.5f, 0.0f, 1.0f,
+			
+			1.0f, 0.0f, 0.0f, 1.0f,
+			1.0f, 0.0f, 0.0f, 1.0f,
+			1.0f, 0.0f, 0.0f, 1.0f,
+			
+			1.0f, 0.0f, 0.0f, 1.0f,
+			1.0f, 0.0f, 0.0f, 1.0f,
+			1.0f, 0.0f, 0.0f, 1.0f,
+			
+			0.0f, 1.0f, 1.0f, 1.0f,
+			0.0f, 1.0f, 1.0f, 1.0f,
+			0.0f, 1.0f, 1.0f, 1.0f,
+			
+			0.0f, 1.0f, 1.0f, 1.0f,
+			0.0f, 1.0f, 1.0f, 1.0f,
+			0.0f, 1.0f, 1.0f, 1.0f
+	};
+	
+	private ShaderProgram program;
+	private int offsetUniform;
+	
+	private int vbo;
+	
+	public Example4_1() {
+		super("Example 4.1", 500, 500, false);
+	}
+	
+	@Override
+	public void init() {
+		glClearColor(0, 0, 0, 0);
+		
+		Map<Integer,String> attributes = new HashMap<Integer,String>();
+		attributes.put(0, "position");
+		attributes.put(1, "color");
+		program = new ShaderProgram(readFromFile("example4.1.vert"),readFromFile("example4.1.frag"),attributes);
+		
+		offsetUniform = glGetUniformLocation(program.getProgram(), "offset");
+		
+		vbo = glGenBuffers();
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glBufferData(GL_ARRAY_BUFFER, (FloatBuffer)BufferUtils.createFloatBuffer(data.length).put(data).flip(), GL_STATIC_DRAW);
+		
+		glBindVertexArray(glGenVertexArrays());
+		
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		
+		glEnable(GL_CULL_FACE);
+		glCullFace(GL_BACK);
+		glFrontFace(GL_CW);
+	}
+	
+	@Override
+	public void render() {
+		glClear(GL_COLOR_BUFFER_BIT);
+		
+		program.begin();
+		
+		glUniform2f(offsetUniform, 0.5f, 0.25f);
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glEnableVertexAttribArray(0);
+		glEnableVertexAttribArray(1);
+		glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
+		glVertexAttribPointer(1, 4, GL_FLOAT, false, 0, data.length * 2);
+		
+		glDrawArrays(GL_TRIANGLES, 0, 36);
+		
+		glDisableVertexAttribArray(0);
+		glDisableVertexAttribArray(1);
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		
+		program.end();
+	}
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter4/example1/example4.1.frag

+#version 150
+
+smooth in vec4 theColor;
+
+out vec4 outputColor;
+
+void main()
+{
+	outputColor = theColor;
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter4/example1/example4.1.vert

+#version 150
+
+in vec4 position;
+in vec4 color;
+
+smooth out vec4 theColor;
+
+uniform vec2 offset;
+
+void main()
+{
+	gl_Position = position + vec4(offset, 0, 0);
+	theColor = color;
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter4/example2/Example4_2.java

+package com.ra4king.opengl.arcsynthesis.gl32.chapter4.example2;
+
+import static org.lwjgl.opengl.GL11.*;
+import static org.lwjgl.opengl.GL15.*;
+import static org.lwjgl.opengl.GL20.*;
+import static org.lwjgl.opengl.GL30.*;
+
+import java.nio.FloatBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.lwjgl.BufferUtils;
+
+import com.ra4king.opengl.GLProgram;
+import com.ra4king.opengl.util.ShaderProgram;
+
+public class Example4_2 extends GLProgram {
+	public static void main(String[] args) {
+		new Example4_2().run(3,2);
+	}
+	
+	private final float[] data = {
+			 0.25f,  0.25f, -1.25f, 1.0f,
+			 0.25f, -0.25f, -1.25f, 1.0f,
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			
+			 0.25f, -0.25f, -1.25f, 1.0f,
+			-0.25f, -0.25f, -1.25f, 1.0f,
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			
+			 0.25f,  0.25f, -2.75f, 1.0f,
+			-0.25f,  0.25f, -2.75f, 1.0f,
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			-0.25f,  0.25f, -2.75f, 1.0f,
+			-0.25f, -0.25f, -2.75f, 1.0f,
+			
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			-0.25f, -0.25f, -1.25f, 1.0f,
+			-0.25f, -0.25f, -2.75f, 1.0f,
+			
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			-0.25f, -0.25f, -2.75f, 1.0f,
+			-0.25f,  0.25f, -2.75f, 1.0f,
+			
+			 0.25f,  0.25f, -1.25f, 1.0f,
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			 0.25f, -0.25f, -1.25f, 1.0f,
+			
+			 0.25f,  0.25f, -1.25f, 1.0f,
+			 0.25f,  0.25f, -2.75f, 1.0f,
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			
+			 0.25f,  0.25f, -2.75f, 1.0f,
+			 0.25f,  0.25f, -1.25f, 1.0f,
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			
+			 0.25f,  0.25f, -2.75f, 1.0f,
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			-0.25f,  0.25f, -2.75f, 1.0f,
+			
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			-0.25f, -0.25f, -1.25f, 1.0f,
+			 0.25f, -0.25f, -1.25f, 1.0f,
+			
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			-0.25f, -0.25f, -2.75f, 1.0f,
+			-0.25f, -0.25f, -1.25f, 1.0f,
+			
+			0.0f, 0.0f, 1.0f, 1.0f,
+			0.0f, 0.0f, 1.0f, 1.0f,
+			0.0f, 0.0f, 1.0f, 1.0f,
+			
+			0.0f, 0.0f, 1.0f, 1.0f,
+			0.0f, 0.0f, 1.0f, 1.0f,
+			0.0f, 0.0f, 1.0f, 1.0f,
+			
+			0.8f, 0.8f, 0.8f, 1.0f,
+			0.8f, 0.8f, 0.8f, 1.0f,
+			0.8f, 0.8f, 0.8f, 1.0f,
+			
+			0.8f, 0.8f, 0.8f, 1.0f,
+			0.8f, 0.8f, 0.8f, 1.0f,
+			0.8f, 0.8f, 0.8f, 1.0f,
+			
+			0.0f, 1.0f, 0.0f, 1.0f,
+			0.0f, 1.0f, 0.0f, 1.0f,
+			0.0f, 1.0f, 0.0f, 1.0f,
+			
+			0.0f, 1.0f, 0.0f, 1.0f,
+			0.0f, 1.0f, 0.0f, 1.0f,
+			0.0f, 1.0f, 0.0f, 1.0f,
+			
+			0.5f, 0.5f, 0.0f, 1.0f,
+			0.5f, 0.5f, 0.0f, 1.0f,
+			0.5f, 0.5f, 0.0f, 1.0f,
+			
+			0.5f, 0.5f, 0.0f, 1.0f,
+			0.5f, 0.5f, 0.0f, 1.0f,
+			0.5f, 0.5f, 0.0f, 1.0f,
+			
+			1.0f, 0.0f, 0.0f, 1.0f,
+			1.0f, 0.0f, 0.0f, 1.0f,
+			1.0f, 0.0f, 0.0f, 1.0f,
+			
+			1.0f, 0.0f, 0.0f, 1.0f,
+			1.0f, 0.0f, 0.0f, 1.0f,
+			1.0f, 0.0f, 0.0f, 1.0f,
+			
+			0.0f, 1.0f, 1.0f, 1.0f,
+			0.0f, 1.0f, 1.0f, 1.0f,
+			0.0f, 1.0f, 1.0f, 1.0f,
+			
+			0.0f, 1.0f, 1.0f, 1.0f,
+			0.0f, 1.0f, 1.0f, 1.0f,
+			0.0f, 1.0f, 1.0f, 1.0f
+	};
+	
+	private ShaderProgram program;
+	private int offsetUniform;
+	
+	private int vbo;
+	
+	public Example4_2() {
+		super("Example 4.2", 500, 500, false);
+	}
+	
+	@Override
+	public void init() {
+		glClearColor(0, 0, 0, 0);
+		
+		Map<Integer,String> attributes = new HashMap<Integer,String>();
+		attributes.put(0, "position");
+		attributes.put(1, "color");
+		program = new ShaderProgram(readFromFile("example4.2.vert"),readFromFile("example4.2.frag"),attributes);
+		
+		offsetUniform = glGetUniformLocation(program.getProgram(), "offset");
+		
+		int frustumScaleUniform = glGetUniformLocation(program.getProgram(), "frustumScale");
+		int zNearUniform = glGetUniformLocation(program.getProgram(), "zNear");
+		int zFarUniform = glGetUniformLocation(program.getProgram(), "zFar");
+		
+		program.begin();
+		glUniform1f(frustumScaleUniform, 1);
+		glUniform1f(zNearUniform, 1);
+		glUniform1f(zFarUniform, 3);
+		program.end();
+		
+		vbo = glGenBuffers();
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glBufferData(GL_ARRAY_BUFFER, (FloatBuffer)BufferUtils.createFloatBuffer(data.length).put(data).flip(), GL_STATIC_DRAW);
+		
+		glBindVertexArray(glGenVertexArrays());
+		
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		
+		glEnable(GL_CULL_FACE);
+		glCullFace(GL_BACK);
+		glFrontFace(GL_CW);
+	}
+	
+	@Override
+	public void render() {
+		glClear(GL_COLOR_BUFFER_BIT);
+		
+		program.begin();
+		
+		glUniform2f(offsetUniform, 0.5f, 0.5f);
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glEnableVertexAttribArray(0);
+		glEnableVertexAttribArray(1);
+		glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
+		glVertexAttribPointer(1, 4, GL_FLOAT, false, 0, data.length * 2);
+		
+		glDrawArrays(GL_TRIANGLES, 0, 36);
+		
+		glDisableVertexAttribArray(0);
+		glDisableVertexAttribArray(1);
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		
+		program.end();
+	}
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter4/example2/example4.2.frag

+#version 150
+
+smooth in vec4 theColor;
+
+out vec4 outputColor;
+
+void main()
+{
+	outputColor = theColor;
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter4/example2/example4.2.vert

+#version 150
+
+in vec4 position;
+in vec4 color;
+
+smooth out vec4 theColor;
+
+uniform vec2 offset;
+uniform float zNear;
+uniform float zFar;
+uniform float frustumScale;
+
+void main()
+{
+	vec4 cameraPos = position + vec4(offset, 0, 0);
+	vec4 clipPos;
+	
+	clipPos.xy = cameraPos.xy * frustumScale;
+	clipPos.z = cameraPos.z * (zNear + zFar) / (zNear - zFar) + (2 * zNear * zFar) / (zNear - zFar);
+	clipPos.w = -cameraPos.z;
+	
+	gl_Position = clipPos;
+	theColor = color;
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter4/example3/Example4_3.java

+package com.ra4king.opengl.arcsynthesis.gl32.chapter4.example3;
+
+import static org.lwjgl.opengl.GL11.*;
+import static org.lwjgl.opengl.GL15.*;
+import static org.lwjgl.opengl.GL20.*;
+import static org.lwjgl.opengl.GL30.*;
+
+import java.nio.FloatBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.lwjgl.BufferUtils;
+
+import com.ra4king.opengl.GLProgram;
+import com.ra4king.opengl.util.ShaderProgram;
+
+public class Example4_3 extends GLProgram {
+	public static void main(String[] args) {
+		new Example4_3().run(3,2);
+	}
+	
+	private final float[] data = {
+			 0.25f,  0.25f, -1.25f, 1.0f,
+			 0.25f, -0.25f, -1.25f, 1.0f,
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			
+			 0.25f, -0.25f, -1.25f, 1.0f,
+			-0.25f, -0.25f, -1.25f, 1.0f,
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			
+			 0.25f,  0.25f, -2.75f, 1.0f,
+			-0.25f,  0.25f, -2.75f, 1.0f,
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			-0.25f,  0.25f, -2.75f, 1.0f,
+			-0.25f, -0.25f, -2.75f, 1.0f,
+			
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			-0.25f, -0.25f, -1.25f, 1.0f,
+			-0.25f, -0.25f, -2.75f, 1.0f,
+			
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			-0.25f, -0.25f, -2.75f, 1.0f,
+			-0.25f,  0.25f, -2.75f, 1.0f,
+			
+			 0.25f,  0.25f, -1.25f, 1.0f,
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			 0.25f, -0.25f, -1.25f, 1.0f,
+			
+			 0.25f,  0.25f, -1.25f, 1.0f,
+			 0.25f,  0.25f, -2.75f, 1.0f,
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			
+			 0.25f,  0.25f, -2.75f, 1.0f,
+			 0.25f,  0.25f, -1.25f, 1.0f,
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			
+			 0.25f,  0.25f, -2.75f, 1.0f,
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			-0.25f,  0.25f, -2.75f, 1.0f,
+			
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			-0.25f, -0.25f, -1.25f, 1.0f,
+			 0.25f, -0.25f, -1.25f, 1.0f,
+			
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			-0.25f, -0.25f, -2.75f, 1.0f,
+			-0.25f, -0.25f, -1.25f, 1.0f,
+			
+			0.0f, 0.0f, 1.0f, 1.0f,
+			0.0f, 0.0f, 1.0f, 1.0f,
+			0.0f, 0.0f, 1.0f, 1.0f,
+			
+			0.0f, 0.0f, 1.0f, 1.0f,
+			0.0f, 0.0f, 1.0f, 1.0f,
+			0.0f, 0.0f, 1.0f, 1.0f,
+			
+			0.8f, 0.8f, 0.8f, 1.0f,
+			0.8f, 0.8f, 0.8f, 1.0f,
+			0.8f, 0.8f, 0.8f, 1.0f,
+			
+			0.8f, 0.8f, 0.8f, 1.0f,
+			0.8f, 0.8f, 0.8f, 1.0f,
+			0.8f, 0.8f, 0.8f, 1.0f,
+			
+			0.0f, 1.0f, 0.0f, 1.0f,
+			0.0f, 1.0f, 0.0f, 1.0f,
+			0.0f, 1.0f, 0.0f, 1.0f,
+			
+			0.0f, 1.0f, 0.0f, 1.0f,
+			0.0f, 1.0f, 0.0f, 1.0f,
+			0.0f, 1.0f, 0.0f, 1.0f,
+			
+			0.5f, 0.5f, 0.0f, 1.0f,
+			0.5f, 0.5f, 0.0f, 1.0f,
+			0.5f, 0.5f, 0.0f, 1.0f,
+			
+			0.5f, 0.5f, 0.0f, 1.0f,
+			0.5f, 0.5f, 0.0f, 1.0f,
+			0.5f, 0.5f, 0.0f, 1.0f,
+			
+			1.0f, 0.0f, 0.0f, 1.0f,
+			1.0f, 0.0f, 0.0f, 1.0f,
+			1.0f, 0.0f, 0.0f, 1.0f,
+			
+			1.0f, 0.0f, 0.0f, 1.0f,
+			1.0f, 0.0f, 0.0f, 1.0f,
+			1.0f, 0.0f, 0.0f, 1.0f,
+			
+			0.0f, 1.0f, 1.0f, 1.0f,
+			0.0f, 1.0f, 1.0f, 1.0f,
+			0.0f, 1.0f, 1.0f, 1.0f,
+			
+			0.0f, 1.0f, 1.0f, 1.0f,
+			0.0f, 1.0f, 1.0f, 1.0f,
+			0.0f, 1.0f, 1.0f, 1.0f
+	};
+	
+	private ShaderProgram program;
+	private int offsetUniform;
+	
+	private int vbo;
+	
+	public Example4_3() {
+		super("Example 4.3", 500, 500, false);
+	}
+	
+	@Override
+	public void init() {
+		glClearColor(0, 0, 0, 0);
+		
+		Map<Integer,String> attributes = new HashMap<Integer,String>();
+		attributes.put(0, "position");
+		attributes.put(1, "color");
+		program = new ShaderProgram(readFromFile("example4.3.vert"),readFromFile("example4.3.frag"),attributes);
+		
+		offsetUniform = glGetUniformLocation(program.getProgram(), "offset");
+		
+		int perspectiveMatrixUniform = glGetUniformLocation(program.getProgram(), "perspectiveMatrix");
+		
+		float frustumScale = 1, zNear = 0.5f, zFar = 3;
+		FloatBuffer perspectiveMatrix = BufferUtils.createFloatBuffer(16);
+		perspectiveMatrix.put(0,frustumScale);
+		perspectiveMatrix.put(5,frustumScale);
+		perspectiveMatrix.put(10,(zFar + zNear) / (zNear - zFar));
+		perspectiveMatrix.put(14,(2 * zFar * zNear) / (zNear - zFar));
+		perspectiveMatrix.put(11,-1);
+		
+		program.begin();
+		glUniformMatrix4(perspectiveMatrixUniform, false, perspectiveMatrix);
+		program.end();
+		
+		vbo = glGenBuffers();
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glBufferData(GL_ARRAY_BUFFER, (FloatBuffer)BufferUtils.createFloatBuffer(data.length).put(data).flip(), GL_STATIC_DRAW);
+		
+		glBindVertexArray(glGenVertexArrays());
+		
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		
+		glEnable(GL_CULL_FACE);
+		glCullFace(GL_BACK);
+		glFrontFace(GL_CW);
+	}
+	
+	@Override
+	public void render() {
+		glClear(GL_COLOR_BUFFER_BIT);
+		
+		program.begin();
+		
+		glUniform2f(offsetUniform, 0.5f, 0.5f);
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glEnableVertexAttribArray(0);
+		glEnableVertexAttribArray(1);
+		glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
+		glVertexAttribPointer(1, 4, GL_FLOAT, false, 0, data.length * 2);
+		
+		glDrawArrays(GL_TRIANGLES, 0, 36);
+		
+		glDisableVertexAttribArray(0);
+		glDisableVertexAttribArray(1);
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		
+		program.end();
+	}
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter4/example3/example4.3.frag

+#version 150
+
+smooth in vec4 theColor;
+
+out vec4 outputColor;
+
+void main()
+{
+	outputColor = theColor;
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter4/example3/example4.3.vert

+#version 150
+
+in vec4 position;
+in vec4 color;
+
+smooth out vec4 theColor;
+
+uniform vec2 offset;
+uniform mat4 perspectiveMatrix;
+
+void main()
+{
+	gl_Position = perspectiveMatrix * (position + vec4(offset, 0, 0));
+	theColor = color;
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter4/example4/Example4_4.java

+package com.ra4king.opengl.arcsynthesis.gl32.chapter4.example4;
+
+import static org.lwjgl.opengl.GL11.*;
+import static org.lwjgl.opengl.GL15.*;
+import static org.lwjgl.opengl.GL20.*;
+import static org.lwjgl.opengl.GL30.*;
+
+import java.nio.FloatBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.lwjgl.BufferUtils;
+
+import com.ra4king.opengl.GLProgram;
+import com.ra4king.opengl.util.ShaderProgram;
+
+public class Example4_4 extends GLProgram {
+	public static void main(String[] args) {
+		new Example4_4().run(3,2);
+	}
+	
+	private final float[] data = {
+			 0.25f,  0.25f, -1.25f, 1.0f,
+			 0.25f, -0.25f, -1.25f, 1.0f,
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			
+			 0.25f, -0.25f, -1.25f, 1.0f,
+			-0.25f, -0.25f, -1.25f, 1.0f,
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			
+			 0.25f,  0.25f, -2.75f, 1.0f,
+			-0.25f,  0.25f, -2.75f, 1.0f,
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			-0.25f,  0.25f, -2.75f, 1.0f,
+			-0.25f, -0.25f, -2.75f, 1.0f,
+			
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			-0.25f, -0.25f, -1.25f, 1.0f,
+			-0.25f, -0.25f, -2.75f, 1.0f,
+			
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			-0.25f, -0.25f, -2.75f, 1.0f,
+			-0.25f,  0.25f, -2.75f, 1.0f,
+			
+			 0.25f,  0.25f, -1.25f, 1.0f,
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			 0.25f, -0.25f, -1.25f, 1.0f,
+			
+			 0.25f,  0.25f, -1.25f, 1.0f,
+			 0.25f,  0.25f, -2.75f, 1.0f,
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			
+			 0.25f,  0.25f, -2.75f, 1.0f,
+			 0.25f,  0.25f, -1.25f, 1.0f,
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			
+			 0.25f,  0.25f, -2.75f, 1.0f,
+			-0.25f,  0.25f, -1.25f, 1.0f,
+			-0.25f,  0.25f, -2.75f, 1.0f,
+			
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			-0.25f, -0.25f, -1.25f, 1.0f,
+			 0.25f, -0.25f, -1.25f, 1.0f,
+			
+			 0.25f, -0.25f, -2.75f, 1.0f,
+			-0.25f, -0.25f, -2.75f, 1.0f,
+			-0.25f, -0.25f, -1.25f, 1.0f,
+			
+			0.0f, 0.0f, 1.0f, 1.0f,
+			0.0f, 0.0f, 1.0f, 1.0f,
+			0.0f, 0.0f, 1.0f, 1.0f,
+			
+			0.0f, 0.0f, 1.0f, 1.0f,
+			0.0f, 0.0f, 1.0f, 1.0f,
+			0.0f, 0.0f, 1.0f, 1.0f,
+			
+			0.8f, 0.8f, 0.8f, 1.0f,
+			0.8f, 0.8f, 0.8f, 1.0f,
+			0.8f, 0.8f, 0.8f, 1.0f,
+			
+			0.8f, 0.8f, 0.8f, 1.0f,
+			0.8f, 0.8f, 0.8f, 1.0f,
+			0.8f, 0.8f, 0.8f, 1.0f,
+			
+			0.0f, 1.0f, 0.0f, 1.0f,
+			0.0f, 1.0f, 0.0f, 1.0f,
+			0.0f, 1.0f, 0.0f, 1.0f,
+			
+			0.0f, 1.0f, 0.0f, 1.0f,
+			0.0f, 1.0f, 0.0f, 1.0f,
+			0.0f, 1.0f, 0.0f, 1.0f,
+			
+			0.5f, 0.5f, 0.0f, 1.0f,
+			0.5f, 0.5f, 0.0f, 1.0f,
+			0.5f, 0.5f, 0.0f, 1.0f,
+			
+			0.5f, 0.5f, 0.0f, 1.0f,
+			0.5f, 0.5f, 0.0f, 1.0f,
+			0.5f, 0.5f, 0.0f, 1.0f,
+			
+			1.0f, 0.0f, 0.0f, 1.0f,
+			1.0f, 0.0f, 0.0f, 1.0f,
+			1.0f, 0.0f, 0.0f, 1.0f,
+			
+			1.0f, 0.0f, 0.0f, 1.0f,
+			1.0f, 0.0f, 0.0f, 1.0f,
+			1.0f, 0.0f, 0.0f, 1.0f,
+			
+			0.0f, 1.0f, 1.0f, 1.0f,
+			0.0f, 1.0f, 1.0f, 1.0f,
+			0.0f, 1.0f, 1.0f, 1.0f,
+			
+			0.0f, 1.0f, 1.0f, 1.0f,
+			0.0f, 1.0f, 1.0f, 1.0f,
+			0.0f, 1.0f, 1.0f, 1.0f
+	};
+	
+	private ShaderProgram program;
+	private int offsetUniform;
+	
+	private int vbo;
+	
+	private FloatBuffer perspectiveMatrix;
+	private int perspectiveMatrixUniform;
+	private float frustumScale = 1;
+	
+	public Example4_4() {
+		super("Example 4.4", 500, 500, true);
+	}
+	
+	@Override
+	public void init() {
+		glClearColor(0, 0, 0, 0);
+		
+		Map<Integer,String> attributes = new HashMap<Integer,String>();
+		attributes.put(0, "position");
+		attributes.put(1, "color");
+		program = new ShaderProgram(readFromFile("example4.4.vert"),readFromFile("example4.4.frag"),attributes);
+		
+		offsetUniform = glGetUniformLocation(program.getProgram(), "offset");
+		
+		perspectiveMatrixUniform = glGetUniformLocation(program.getProgram(), "perspectiveMatrix");
+		
+		float zNear = 0.5f, zFar = 3;
+		perspectiveMatrix = BufferUtils.createFloatBuffer(16);
+		perspectiveMatrix.put(0,frustumScale);
+		perspectiveMatrix.put(5,frustumScale);
+		perspectiveMatrix.put(10,(zFar + zNear) / (zNear - zFar));
+		perspectiveMatrix.put(14,(2 * zFar * zNear) / (zNear - zFar));
+		perspectiveMatrix.put(11,-1);
+		
+		program.begin();
+		glUniformMatrix4(perspectiveMatrixUniform, false, perspectiveMatrix);
+		program.end();
+		
+		vbo = glGenBuffers();
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glBufferData(GL_ARRAY_BUFFER, (FloatBuffer)BufferUtils.createFloatBuffer(data.length).put(data).flip(), GL_STATIC_DRAW);
+		
+		glBindVertexArray(glGenVertexArrays());
+		
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		
+		glEnable(GL_CULL_FACE);
+		glCullFace(GL_BACK);
+		glFrontFace(GL_CW);
+	}
+	
+	@Override
+	public void resized() {
+		super.resized();
+		
+		perspectiveMatrix.put(0,frustumScale / ((float)getWidth() / getHeight()));
+		
+		program.begin();
+		glUniformMatrix4(perspectiveMatrixUniform, false, perspectiveMatrix);
+		program.end();
+	}
+	
+	@Override
+	public void render() {
+		glClear(GL_COLOR_BUFFER_BIT);
+		
+		program.begin();
+		
+		glUniform2f(offsetUniform, 1.5f, 0.5f);
+		
+		glBindBuffer(GL_ARRAY_BUFFER, vbo);
+		glEnableVertexAttribArray(0);
+		glEnableVertexAttribArray(1);
+		glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
+		glVertexAttribPointer(1, 4, GL_FLOAT, false, 0, data.length * 2);
+		
+		glDrawArrays(GL_TRIANGLES, 0, 36);
+		
+		glDisableVertexAttribArray(0);
+		glDisableVertexAttribArray(1);
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		
+		program.end();
+	}
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter4/example4/example4.4.frag

+#version 150
+
+smooth in vec4 theColor;
+
+out vec4 outputColor;
+
+void main()
+{
+	outputColor = theColor;
+}

src/main/java/com/ra4king/opengl/arcsynthesis/gl32/chapter4/example4/example4.4.vert

+#version 150
+
+in vec4 position;
+in vec4 color;
+
+smooth out vec4 theColor;
+
+uniform vec2 offset;
+uniform mat4 perspectiveMatrix;
+
+void main()
+{
+	gl_Position = perspectiveMatrix * (position + vec4(offset, 0, 0));
+	theColor = color;
+}

src/main/java/com/ra4king/opengl/util/ShaderProgram.java

 import static org.lwjgl.opengl.GL11.*;
 import static org.lwjgl.opengl.GL20.*;
 
+import java.util.Map;
+
 public class ShaderProgram {
 	private int program;
 	
 	public ShaderProgram(String vertexShader, String fragmentShader) {
+		this(vertexShader,fragmentShader,null);
+	}
+	
+	public ShaderProgram(String vertexShader, String fragmentShader, Map<Integer,String> attributes) {
 		int vs = glCreateShader(GL_VERTEX_SHADER);
 		glShaderSource(vs, vertexShader);
 		
 		glAttachShader(program, vs);
 		glAttachShader(program, fs);
 		
+		if(attributes != null)
+			for(Integer i : attributes.keySet())
+				glBindAttribLocation(program, i, attributes.get(i));
+		
 		glLinkProgram(program);
 		
 		if(glGetProgram(program, GL_LINK_STATUS) == GL_FALSE)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.