diff --git a/RedBook8th/Examples/Ex10_21.cpp b/RedBook8th/Examples/Ex10_21.cpp index 0752c78..bb0da64 100755 --- a/RedBook8th/Examples/Ex10_21.cpp +++ b/RedBook8th/Examples/Ex10_21.cpp @@ -20,9 +20,9 @@ Ex10_21::Ex10_21() Ex10_21::~Ex10_21() { - glUseProgram(0); - glDeleteBuffers(1, &vbo); - glDeleteProgram(prog); + glUseProgram(0); + glDeleteBuffers(1, &vbo); + glDeleteProgram(prog); glDeleteVertexArrays(1, &vao); } diff --git a/RedBook8th/Examples/Ex11_04.cpp b/RedBook8th/Examples/Ex11_04.cpp new file mode 100755 index 0000000..d38b7c1 --- /dev/null +++ b/RedBook8th/Examples/Ex11_04.cpp @@ -0,0 +1,188 @@ +/* +* Ex11_04.cpp +* +* Created on: Apr 12, 2014 +* Author: Andrew Zhabura +*/ + +#include "Ex11_04.h" + +#include "GL/LoadShaders.h" +#include "Auxiliary/vmath.h" +#include "Auxiliary/vermilion.h" + +#define MAX_FRAMEBUFFER_WIDTH 2048 +#define MAX_FRAMEBUFFER_HEIGHT 2048 + +Ex11_04::Ex11_04() + : OGLWindow("Example11_04", "Example 11.04 (M)") +{ +} + +Ex11_04::~Ex11_04() +{ + glUseProgram(0); + glDeleteProgram(render_scene_prog); + glDeleteBuffers(1, &quad_vbo); + glDeleteVertexArrays(1, &quad_vao); +} + +void Ex11_04::InitGL() +{ + if (! LoadGL() ) + return; + // Create the program for rendering the scene from the viewer's position + ShaderInfo scene_shaders[] = + { + { GL_VERTEX_SHADER, "Shaders/double_write.vs.glsl" }, + { GL_FRAGMENT_SHADER, "Shaders/double_write.fs.glsl" }, + { GL_NONE } + }; + + if (render_scene_prog != -1) + glDeleteProgram(render_scene_prog); + + render_scene_prog = LoadShaders(scene_shaders); + + render_scene_uniforms.model_matrix = glGetUniformLocation(render_scene_prog, "model_matrix"); + render_scene_uniforms.view_matrix = glGetUniformLocation(render_scene_prog, "view_matrix"); + render_scene_uniforms.projection_matrix = glGetUniformLocation(render_scene_prog, "projection_matrix"); + render_scene_uniforms.aspect = glGetUniformLocation(render_scene_prog, "aspect"); + render_scene_uniforms.time = glGetUniformLocation(render_scene_prog, "time"); + + ShaderInfo resolve_shaders[] = + { + { GL_VERTEX_SHADER, "Shaders/blit.vs.glsl" }, + { GL_FRAGMENT_SHADER, "Shaders/blit.fs.glsl" }, + { GL_NONE } + }; + + resolve_program = LoadShaders(resolve_shaders); + + // Create palette texture + glGenBuffers(1, &image_palette_buffer); + glBindBuffer(GL_TEXTURE_BUFFER, image_palette_buffer); + glBufferData(GL_TEXTURE_BUFFER, 256 * 4 * sizeof(float), NULL, GL_STATIC_DRAW); + glGenTextures(1, &image_palette_texture); + glBindTexture(GL_TEXTURE_BUFFER, image_palette_texture); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, image_palette_buffer); + + vmath::vec4 * data = (vmath::vec4 *)glMapBuffer(GL_TEXTURE_BUFFER, GL_WRITE_ONLY); + for (int i = 0; i < 256; i++) + { + data[i] = vmath::vec4((float)i); + } + glUnmapBuffer(GL_TEXTURE_BUFFER); + + // Create head pointer texture + glActiveTexture(GL_TEXTURE0); + glGenTextures(1, &output_texture); + glBindTexture(GL_TEXTURE_2D, output_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, MAX_FRAMEBUFFER_WIDTH, MAX_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); + glBindTexture(GL_TEXTURE_2D, 0); + + glBindImageTexture(0, output_texture, 0, GL_TRUE, 0, GL_READ_WRITE, GL_RGBA32F); + + // Create buffer for clearing the head pointer texture + glGenBuffers(1, &output_texture_clear_buffer); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, output_texture_clear_buffer); + glBufferData(GL_PIXEL_UNPACK_BUFFER, MAX_FRAMEBUFFER_WIDTH * MAX_FRAMEBUFFER_HEIGHT * sizeof(GLuint), NULL, GL_STATIC_DRAW); + + data = (vmath::vec4 *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); + memset(data, 0x00, MAX_FRAMEBUFFER_WIDTH * MAX_FRAMEBUFFER_HEIGHT * sizeof(GLuint)); + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + + // Create VAO containing quad for the final blit + glGenVertexArrays(1, &quad_vao); + glBindVertexArray(quad_vao); + + static const GLfloat quad_verts[] = + { + -1.0f, -1.0f, + 1.0f, -1.0f, + -1.0f, 1.0f, + 1.0f, 1.0f, + }; + + glGenBuffers(1, &quad_vbo); + glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(quad_verts), quad_verts, GL_STATIC_DRAW); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL); + glEnableVertexAttribArray(0); + + glClearDepth(1.0f); + + object.LoadFromVBM("Media/torus.vbm", 0, 1, 2); +} + +void Ex11_04::Display() +{ + float t; + + unsigned int current_time = GetTickCount(); + + t = (float)(current_time & 0xFFFFF) / (float)0x3FFF; + + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + + // Bind palette buffer + glBindImageTexture(0, image_palette_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); + + // Clear output image + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, output_texture_clear_buffer); + glBindTexture(GL_TEXTURE_2D, output_texture); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, current_width, current_height, GL_RGBA, GL_FLOAT, NULL); + glBindTexture(GL_TEXTURE_2D, 0); + + // Bind output image for read-write + glBindImageTexture(1, output_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); + + // Render + glUseProgram(render_scene_prog); + + float aspect = float(getHeight()) / getWidth(); + + vmath::mat4 model_matrix = vmath::translate(0.0f, 0.0f, -50.0f) * + vmath::rotate(t * 360.0f, 0.0f, 0.0f, 1.0f) * + vmath::rotate(t * 435.0f, 0.0f, 1.0f, 0.0f) * + vmath::rotate(t * 275.0f, 1.0f, 0.0f, 0.0f); + vmath::mat4 view_matrix = vmath::mat4::identity(); + vmath::mat4 projection_matrix = vmath::frustum(-1.0f, 1.0f, aspect, -aspect, 1.0f, 40.f); + + glUniformMatrix4fv(render_scene_uniforms.model_matrix, 1, GL_FALSE, model_matrix); + glUniformMatrix4fv(render_scene_uniforms.view_matrix, 1, GL_FALSE, view_matrix); + glUniformMatrix4fv(render_scene_uniforms.projection_matrix, 1, GL_FALSE, projection_matrix); + + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + + object.Render(0, 4 * 4 * 4); + + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + glBindImageTexture(0, output_texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); + + glBindVertexArray(quad_vao); + glUseProgram(resolve_program); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glFlush(); +} + +void Ex11_04::keyboard( unsigned char key, int x, int y ) +{ + switch( key ) { + case 'M': + for (int i = 0; i < c_repeat; ++i) + Display(); + break; + default: + OGLWindow::keyboard(key, x, y); + break; + } +} \ No newline at end of file diff --git a/RedBook8th/Examples/Ex11_04.h b/RedBook8th/Examples/Ex11_04.h new file mode 100755 index 0000000..1029774 --- /dev/null +++ b/RedBook8th/Examples/Ex11_04.h @@ -0,0 +1,60 @@ +/* +* Ex11_04.h +* +* Created on: Apr 12, 2014 +* Author: Andrew Zhabura +*/ + +#ifndef Ex11_04_h +#define Ex11_04_h + +#include "WinApi/OGLWindow.h" +#include +#include "Auxiliary/vbm.h" + +class Ex11_04 : public OGLWindow +{ +public: + Ex11_04(); + ~Ex11_04(); + void InitGL(); + virtual void keyboard( unsigned char key, int x, int y ); +private: + void Display(); + + // Program to construct the linked list (renders the transparent objects) + GLuint list_build_program; + + // Color palette buffer texture + GLuint image_palette_buffer; + GLuint image_palette_texture; + + // Output image and PBO for clearing it + GLuint output_texture; + GLuint output_texture_clear_buffer; + + // Program to render the scene + GLuint render_scene_prog; + struct + { + GLint aspect; + GLint time; + GLint model_matrix; + GLint view_matrix; + GLint projection_matrix; + } render_scene_uniforms; + + // Program to resolve + GLuint resolve_program; + + // Full Screen Quad + GLuint quad_vbo; + GLuint quad_vao; + + GLint current_width; + GLint current_height; + + VBObject object; +}; + +#endif // Ex11_04_h \ No newline at end of file diff --git a/RedBook8th/RedBook8th.vcxproj b/RedBook8th/RedBook8th.vcxproj index 87f7581..e0abde3 100755 --- a/RedBook8th/RedBook8th.vcxproj +++ b/RedBook8th/RedBook8th.vcxproj @@ -121,6 +121,7 @@ + @@ -183,6 +184,7 @@ + @@ -192,6 +194,10 @@ + + + + diff --git a/RedBook8th/RedBook8th.vcxproj.filters b/RedBook8th/RedBook8th.vcxproj.filters index 9e35f44..6182bbf 100755 --- a/RedBook8th/RedBook8th.vcxproj.filters +++ b/RedBook8th/RedBook8th.vcxproj.filters @@ -171,6 +171,9 @@ Examples + + Examples + @@ -346,6 +349,9 @@ Examples + + Examples + @@ -648,6 +654,18 @@ Shaders + + Shaders + + + Shaders + + + Shaders + + + Shaders + diff --git a/RedBook8th/Shaders/blit.fs.glsl b/RedBook8th/Shaders/blit.fs.glsl new file mode 100755 index 0000000..446d3e1 --- /dev/null +++ b/RedBook8th/Shaders/blit.fs.glsl @@ -0,0 +1,16 @@ +#version 430 core + +/* + * OpenGL Programming Guide - Double Write Example + */ + +// Buffer containing the rendered image +layout (binding = 0, rgba32f) uniform image2D output_image; + +// This is the output color +layout (location = 0) out vec4 color; + +void main(void) +{ + color = vec4(imageLoad(output_image, ivec2(gl_FragCoord.xy)).xxxx) / 255.0; +} diff --git a/RedBook8th/Shaders/blit.vs.glsl b/RedBook8th/Shaders/blit.vs.glsl new file mode 100755 index 0000000..5b98f13 --- /dev/null +++ b/RedBook8th/Shaders/blit.vs.glsl @@ -0,0 +1,8 @@ +#version 430 core + +in vec4 position; + +void main(void) +{ + gl_Position = position; +} diff --git a/RedBook8th/Shaders/double_write.fs.glsl b/RedBook8th/Shaders/double_write.fs.glsl new file mode 100755 index 0000000..f835505 --- /dev/null +++ b/RedBook8th/Shaders/double_write.fs.glsl @@ -0,0 +1,22 @@ +#version 430 core + +// Buffer containing a palette of colors to be used to mark primitives by ID +layout (binding = 0, rgba32f) uniform imageBuffer colors; + +// The buffer that we will write to +layout (binding = 1, rgba32f) uniform image2D output_buffer; + +out vec4 color; + +void main(void) +{ + // Load a color from the palette buffer based on primitive ID % 256 + vec4 col = imageLoad(colors, gl_PrimitiveID & 255); + + // Store the resulting fragment at two locations. First at the fragments + // window space coordinate shifted left... + imageStore(output_buffer, ivec2(gl_FragCoord.xy) - ivec2(200, 0), col); + + // ... then at the location shifted right + imageStore(output_buffer, ivec2(gl_FragCoord.xy) + ivec2(200, 0), col); +} diff --git a/RedBook8th/Shaders/double_write.vs.glsl b/RedBook8th/Shaders/double_write.vs.glsl new file mode 100755 index 0000000..d69b48f --- /dev/null +++ b/RedBook8th/Shaders/double_write.vs.glsl @@ -0,0 +1,38 @@ +#version 430 core + +layout (location = 0) in vec4 position; +layout (location = 1) in vec3 normal; +layout (location = 2) in vec2 map1; + +uniform mat4 model_matrix; +uniform mat4 view_matrix; +uniform mat4 projection_matrix; + +uniform float aspect; +uniform float time; + +out gl_PerVertex +{ + vec4 gl_Position; +}; + +out vec4 surface_color; +out vec3 frag_position; +out vec3 frag_normal; + +void main(void) +{ + vec4 offset = vec4(float(gl_InstanceID & 3) * 2.0, + float((gl_InstanceID >> 2) & 3) * 2.0, + float((gl_InstanceID >> 4) & 3) * 2.0, 0.0) - + vec4(4.0, 4.0, 4.0, 0.0); + + surface_color = normalize(offset) * 0.5 + vec4(0.5, 0.5, 0.5, 0.4); + + vec4 object_pos = (position + offset); + vec4 world_pos = model_matrix * object_pos; + frag_position = world_pos.xyz; + frag_normal = mat3(model_matrix * view_matrix) * normal; + + gl_Position = (projection_matrix * view_matrix) * world_pos; +} diff --git a/RedBook8th/WinApi/WinParent.cpp b/RedBook8th/WinApi/WinParent.cpp index d2b990a..ed72964 100755 --- a/RedBook8th/WinApi/WinParent.cpp +++ b/RedBook8th/WinApi/WinParent.cpp @@ -58,10 +58,11 @@ #include "Examples/Ex10_07.h" #include "Examples/Ex10_15.h" #include "Examples/Ex10_21.h" +#include "Examples/Ex11_04.h" #include "Examples/ExTest.h" -#define EXAMPLES_QTY 51 +#define EXAMPLES_QTY 52 #define CUR_EXAMPLE EXAMPLES_QTY-2 LRESULT CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); @@ -295,6 +296,8 @@ int WinParent::InitChilds(int nCmdShow) InitChild(child, r); child = new Ex10_21; InitChild(child, r); + child = new Ex11_04; + InitChild(child, r); child = new ExTest; InitChild(child, r);