Skip to content

Commit ca01d2d

Browse files
committed
Added initial source.
1 parent 4263365 commit ca01d2d

File tree

8 files changed

+1907
-0
lines changed

8 files changed

+1907
-0
lines changed

CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
2+
3+
project("GPUParticleSystem")
4+
5+
IF(APPLE)
6+
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++14")
7+
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
8+
ENDIF()
9+
10+
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib")
11+
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib")
12+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
13+
14+
add_subdirectory(external/dwSampleFramework)
15+
16+
include_directories("${DW_SAMPLE_FRAMEWORK_INCLUDES}")
17+
18+
add_subdirectory(src)

src/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
2+
3+
add_executable(GPUParticleSystem "main.cpp")
4+
5+
target_link_libraries(GPUParticleSystem dwSampleFramework)
6+
7+
add_custom_command(TARGET GPUParticleSystem POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/src/shader $<TARGET_FILE_DIR:ProgressivePathTracer>/shader)
8+
add_custom_command(TARGET GPUParticleSystem POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/src/shader ${CMAKE_SOURCE_DIR}/build/src/shader)

src/main.cpp

Lines changed: 351 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,351 @@
1+
#include <application.h>
2+
#include <mesh.h>
3+
#include <camera.h>
4+
#include <material.h>
5+
#include <utility.h>
6+
#include <memory>
7+
8+
class ProgressivePathTracer : public dw::Application
9+
{
10+
protected:
11+
12+
// -----------------------------------------------------------------------------------------------------------------------------------
13+
14+
bool init(int argc, const char* argv[]) override
15+
{
16+
if (!load_shaders())
17+
return false;
18+
19+
create_camera();
20+
create_image();
21+
create_quad();
22+
23+
int work_grp_cnt[3];
24+
25+
glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &work_grp_cnt[0]);
26+
glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &work_grp_cnt[1]);
27+
glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &work_grp_cnt[2]);
28+
29+
DW_LOG_INFO("Max Work Group Count, X: " + std::to_string(work_grp_cnt[0]) + ", Y:" + std::to_string(work_grp_cnt[1]) + ", Z:" + std::to_string(work_grp_cnt[2]));
30+
31+
int work_grp_size[3];
32+
33+
glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &work_grp_size[0]);
34+
glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &work_grp_size[1]);
35+
glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &work_grp_size[2]);
36+
37+
DW_LOG_INFO("Max Work Group Size, X: " + std::to_string(work_grp_size[0]) + ", Y:" + std::to_string(work_grp_size[1]) + ", Z:" + std::to_string(work_grp_size[2]));
38+
39+
int work_grp_inv;
40+
41+
glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &work_grp_inv);
42+
43+
DW_LOG_INFO("Max Work Group Invocations: " + std::to_string(work_grp_inv));
44+
45+
return true;
46+
}
47+
48+
// -----------------------------------------------------------------------------------------------------------------------------------
49+
50+
void update(double delta) override
51+
{
52+
// Check if camera had moved.
53+
check_camera_movement();
54+
55+
// Update camera.
56+
update_camera();
57+
58+
// Perform path tracing
59+
path_trace();
60+
61+
// Render image to screen
62+
render_to_backbuffer();
63+
64+
// Set back to false before checking movement next frame.
65+
m_camera_moved = false;
66+
}
67+
68+
// -----------------------------------------------------------------------------------------------------------------------------------
69+
70+
void shutdown() override
71+
{
72+
73+
}
74+
75+
// -----------------------------------------------------------------------------------------------------------------------------------
76+
77+
dw::AppSettings intial_app_settings() override
78+
{
79+
dw::AppSettings settings;
80+
81+
settings.resizable = false;
82+
settings.width = 1280;
83+
settings.height = 720;
84+
settings.title = "GPU Path Tracer - Dihara Wijetunga (c) 2018";
85+
86+
return settings;
87+
}
88+
89+
// -----------------------------------------------------------------------------------------------------------------------------------
90+
91+
void window_resized(int width, int height) override
92+
{
93+
// Override window resized method to update camera projection.
94+
m_main_camera->update_projection(60.0f, 0.1f, 1000.0f, float(m_width) / float(m_height));
95+
m_aspect_ratio = float(m_width) / float(m_height);
96+
m_resolution = glm::vec2(m_width, m_height);
97+
}
98+
99+
// -----------------------------------------------------------------------------------------------------------------------------------
100+
101+
void key_pressed(int code) override
102+
{
103+
// Handle forward movement.
104+
if (code == GLFW_KEY_W)
105+
m_heading_speed = m_camera_speed;
106+
else if (code == GLFW_KEY_S)
107+
m_heading_speed = -m_camera_speed;
108+
109+
// Handle sideways movement.
110+
if (code == GLFW_KEY_A)
111+
m_sideways_speed = -m_camera_speed;
112+
else if (code == GLFW_KEY_D)
113+
m_sideways_speed = m_camera_speed;
114+
}
115+
116+
// -----------------------------------------------------------------------------------------------------------------------------------
117+
118+
void key_released(int code) override
119+
{
120+
// Handle forward movement.
121+
if (code == GLFW_KEY_W || code == GLFW_KEY_S)
122+
m_heading_speed = 0.0f;
123+
124+
// Handle sideways movement.
125+
if (code == GLFW_KEY_A || code == GLFW_KEY_D)
126+
m_sideways_speed = 0.0f;
127+
}
128+
129+
// -----------------------------------------------------------------------------------------------------------------------------------
130+
131+
void mouse_pressed(int code) override
132+
{
133+
// Enable mouse look.
134+
if (code == GLFW_MOUSE_BUTTON_LEFT)
135+
m_mouse_look = true;
136+
}
137+
138+
// -----------------------------------------------------------------------------------------------------------------------------------
139+
140+
void mouse_released(int code) override
141+
{
142+
// Disable mouse look.
143+
if (code == GLFW_MOUSE_BUTTON_LEFT)
144+
m_mouse_look = false;
145+
}
146+
147+
// -----------------------------------------------------------------------------------------------------------------------------------
148+
149+
private:
150+
151+
// -----------------------------------------------------------------------------------------------------------------------------------
152+
153+
void check_camera_movement()
154+
{
155+
if (m_mouse_look && (m_mouse_delta_x != 0 || m_mouse_delta_y != 0) || m_heading_speed != 0.0f || m_sideways_speed != 0.0f)
156+
m_camera_moved = true;
157+
else
158+
m_camera_moved = false;
159+
}
160+
161+
// -----------------------------------------------------------------------------------------------------------------------------------
162+
163+
void path_trace()
164+
{
165+
m_image->bind_image(0, 0, 0, GL_READ_WRITE, GL_RGBA32F);
166+
167+
m_path_tracer_program->use();
168+
169+
if (m_camera_moved)
170+
m_num_frames = 0;
171+
172+
m_path_tracer_program->set_uniform("u_NumFrames", m_num_frames);
173+
m_path_tracer_program->set_uniform("u_Accum", float(m_num_frames) / float(m_num_frames + 1));
174+
m_path_tracer_program->set_uniform("u_FOV", glm::radians(m_main_camera->m_fov));
175+
m_path_tracer_program->set_uniform("u_AspectRatio", m_aspect_ratio);
176+
m_path_tracer_program->set_uniform("u_Resolution", m_resolution);
177+
m_path_tracer_program->set_uniform("u_InvViewMat", glm::inverse(m_main_camera->m_view));
178+
m_path_tracer_program->set_uniform("u_InvProjectionMat", glm::inverse(m_main_camera->m_projection));
179+
180+
glDispatchCompute(m_width, m_height, 1);
181+
182+
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
183+
184+
m_num_frames++;
185+
}
186+
187+
// -----------------------------------------------------------------------------------------------------------------------------------
188+
189+
void render_to_backbuffer()
190+
{
191+
glBindFramebuffer(GL_FRAMEBUFFER, 0);
192+
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
193+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
194+
195+
m_quad_vao->bind();
196+
197+
m_present_program->use();
198+
199+
if (m_present_program->set_uniform("s_Image", 0))
200+
m_image->bind(0);
201+
202+
glDrawArrays(GL_TRIANGLES, 0, 6);
203+
}
204+
205+
// -----------------------------------------------------------------------------------------------------------------------------------
206+
207+
bool load_shaders()
208+
{
209+
std::string src;
210+
211+
if (!dw::utility::read_text("shader/present_vs.glsl", src))
212+
{
213+
DW_LOG_ERROR("Failed to read present_vs.glsl");
214+
return false;
215+
}
216+
217+
m_present_vs = std::make_unique<dw::Shader>(GL_VERTEX_SHADER, src);
218+
219+
src.clear();
220+
221+
if (!dw::utility::read_text("shader/present_fs.glsl", src))
222+
{
223+
DW_LOG_ERROR("Failed to read present_fs.glsl");
224+
return false;
225+
}
226+
227+
m_present_fs = std::make_unique<dw::Shader>(GL_FRAGMENT_SHADER, src);
228+
229+
dw::Shader* present_shaders[] = { m_present_vs.get(), m_present_fs.get() };
230+
231+
m_present_program = std::make_unique<dw::Program>(2, present_shaders);
232+
233+
src.clear();
234+
235+
if (!dw::utility::read_text("shader/path_tracer_cs.glsl", src))
236+
{
237+
DW_LOG_ERROR("Failed to read path_tracer_cs.glsl");
238+
return false;
239+
}
240+
241+
m_path_tracer_cs = std::make_unique<dw::Shader>(GL_COMPUTE_SHADER, src);
242+
243+
dw::Shader* path_tracer_shader = m_path_tracer_cs.get();
244+
m_path_tracer_program = std::make_unique<dw::Program>(1, &path_tracer_shader);
245+
246+
return true;
247+
}
248+
249+
// -----------------------------------------------------------------------------------------------------------------------------------
250+
251+
void create_camera()
252+
{
253+
m_main_camera = std::make_unique<dw::Camera>(60.0f, 0.1f, 1000.0f, float(m_width) / float(m_height), glm::vec3(0.0f, 0.0f, 30.0f), glm::vec3(0.0f, 0.0, -1.0f));
254+
m_aspect_ratio = float(m_width) / float(m_height);
255+
m_resolution = glm::vec2(m_width, m_height);
256+
}
257+
258+
// -----------------------------------------------------------------------------------------------------------------------------------
259+
260+
void create_image()
261+
{
262+
m_image = std::make_unique<dw::Texture2D>(m_width, m_height, 1, 1, 1, GL_RGBA32F, GL_RGBA, GL_FLOAT);
263+
m_image->set_min_filter(GL_LINEAR);
264+
m_image->set_wrapping(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
265+
}
266+
267+
// -----------------------------------------------------------------------------------------------------------------------------------
268+
269+
void create_quad()
270+
{
271+
const float vertices[] =
272+
{
273+
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
274+
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
275+
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
276+
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
277+
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
278+
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f
279+
};
280+
281+
m_quad_vbo = std::make_unique<dw::VertexBuffer>(GL_STATIC_DRAW, sizeof(vertices), (void*)vertices);
282+
283+
dw::VertexAttrib quad_attribs[] =
284+
{
285+
{ 3, GL_FLOAT, false, 0, },
286+
{ 2, GL_FLOAT, false, sizeof(float) * 3 }
287+
};
288+
289+
m_quad_vao = std::make_unique<dw::VertexArray>(m_quad_vbo.get(), nullptr, sizeof(float) * 5, 2, quad_attribs);
290+
}
291+
292+
// -----------------------------------------------------------------------------------------------------------------------------------
293+
294+
void update_camera()
295+
{
296+
dw::Camera* current = m_main_camera.get();
297+
298+
float forward_delta = m_heading_speed * m_delta;
299+
float right_delta = m_sideways_speed * m_delta;
300+
301+
current->set_translation_delta(current->m_forward, forward_delta);
302+
current->set_translation_delta(current->m_right, right_delta);
303+
304+
if (m_mouse_look)
305+
{
306+
// Activate Mouse Look
307+
current->set_rotatation_delta(glm::vec3((float)(m_mouse_delta_y * m_camera_sensitivity * m_delta),
308+
(float)(m_mouse_delta_x * m_camera_sensitivity * m_delta),
309+
(float)(0.0f)));
310+
}
311+
else
312+
{
313+
current->set_rotatation_delta(glm::vec3((float)(0),
314+
(float)(0),
315+
(float)(0)));
316+
}
317+
318+
current->update();
319+
}
320+
321+
// -----------------------------------------------------------------------------------------------------------------------------------
322+
323+
private:
324+
// GPU Resources.
325+
std::unique_ptr<dw::Shader> m_present_vs;
326+
std::unique_ptr<dw::Shader> m_present_fs;
327+
std::unique_ptr<dw::Program> m_present_program;
328+
std::unique_ptr<dw::Shader> m_path_tracer_cs;
329+
std::unique_ptr<dw::Program> m_path_tracer_program;
330+
std::unique_ptr<dw::Texture> m_image;
331+
std::unique_ptr<dw::VertexBuffer> m_quad_vbo;
332+
std::unique_ptr<dw::VertexArray> m_quad_vao;
333+
334+
// Uniforms
335+
float m_aspect_ratio;
336+
glm::vec2 m_resolution;
337+
int32_t m_num_frames = 0;
338+
339+
// Camera controls.
340+
bool m_mouse_look = false;
341+
bool m_camera_moved = false;
342+
float m_heading_speed = 0.0f;
343+
float m_sideways_speed = 0.0f;
344+
float m_camera_sensitivity = 0.005f;
345+
float m_camera_speed = 0.1f;
346+
347+
// Camera.
348+
std::unique_ptr<dw::Camera> m_main_camera;
349+
};
350+
351+
DW_DECLARE_MAIN(ProgressivePathTracer)

0 commit comments

Comments
 (0)