Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
johhnry committed Apr 16, 2021
0 parents commit 32b7ad0
Show file tree
Hide file tree
Showing 34 changed files with 1,745 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.cache/
build
compile_commands.json
91 changes: 91 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Compute shaders : GPU ray tracing

OpenGL compute shaders exercise : real time GPU ray tracing.

<p align="center">
<img src="img/rt_cs1.gif">
</p>

<p align="center">
<img src="img/rt_cs2.gif">
</p>

## Description

This project was made at ArtFX - TD 4.

## Getting Started

### Dependencies

This project is using the following libraries :

- [GLFW](https://www.glfw.org/) (Window management)
- [GLEW](http://glew.sourceforge.net/) (OpenGL Extension Wrangler)

Install them :

```shell
$ sudo apt install libglfw3-dev libglew-dev
```

The build system is [Meson](https://mesonbuild.com/index.html).

To install Meson, do the following :

```shell
$ sudo apt-get install python3 python3-pip python3-setuptools \
python3-wheel ninja-build

$ pip3 install --user meson
```

### One line command

You can do the following steps with one line :

```shell
$ meson build && cd build && meson compile && cd .. && ./build/src/ray-tracing-cs
```

### Build

To configure the build directory, run :

```shell
$ meson build
```

Then compile it :

```shell
$ cd build && meson compile
```

### Execute the program

From the project folder, run the executable (for relative paths like shaders) :

```shell
$ ./build/src/ray-tracing-cs
```

### Arguments and options

There's two scenes for now, you can specify it with a number parameter (starting at 1):

```shell
$ ./build/src/ray-tracing-cs 2 // Second scene
```

You can also pass the resolution of the window (by default it's 1024x512 pixels):

```shell
$ ./build/src/ray-tracing-cs 1 1920 1080
```

### Sources and documentation

- [Ray Tracing in One Weekend](https://raytracing.github.io/books/RayTracingInOneWeekend.html) by [Peter Shirley](https://github.com/petershirley)
- [Introduction aux compute shaders](https://zestedesavoir.com/tutoriels/1554/introduction-aux-compute-shaders/) by denissalem
- [It's More Fun to Compute](https://antongerdelan.net/opengl/compute.html) by [Anton Gerdelan](https://antongerdelan.net/)
Binary file added img/rt_cs1.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/rt_cs2.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
project('ray-tracing-cs', 'cpp',
version : '1.0.0',
license: 'MIT',
default_options : ['warning_level=3',
'cpp_std=c++14'])

subdirs = [ 'src' ]

foreach dir : subdirs
subdir(dir)
endforeach
220 changes: 220 additions & 0 deletions src/app/Application.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
#include <bits/stdint-uintn.h>
#include <cstdlib>
#include <iostream>
#include <math.h>
#include <sstream>
#include <string>
#include <unistd.h>

#include "GL/glew.h"
#include <GLFW/glfw3.h>

#include "utils/FileUtils.hpp"
#include "log/Log.hpp"

#include "shader/ComputeProgram.hpp"
#include "shader/ComputeShader.hpp"
#include "shader/FragmentShader.hpp"
#include "shader/Program.hpp"
#include "shader/VertexShader.hpp"

#include "geometry/FullScreenVAO.hpp"
#include "texture/Texture.hpp"

#include "Application.hpp"


Application::Application(): window() {}

void Application::initializeGlfw(const uint32_t width, const uint32_t height)
{
int glfw = glfwInit();

if (glfw != GLFW_TRUE) {
throw "GLFW: Couldn't initialize correctly";
}

Log::success("GLFW: Successfully initialized");

// Setting glfw callbacks for errors
glfwSetErrorCallback(Log::errorCallBack);

Log::message("GLFW: Running version " + std::string(glfwGetVersionString()));

// OpenGL version
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

// Initialize window
window.initialize("Compute shaders : GPU ray tracing", width, height);

// Set frame interval swap
glfwSwapInterval(1);

// Enable depth
glEnable(GL_DEPTH_TEST);

// Enable multi sampling
glfwWindowHint(GLFW_SAMPLES, 4);
glEnable(GL_MULTISAMPLE);
}

void Application::initializeGlew()
{
GLenum err = glewInit();

if (err != GLEW_OK) {
std::string glfwError = std::string(reinterpret_cast<const char *>(glewGetErrorString(err)));
throw "GLEW initialization error : " + glfwError;
}

std::string glewVersion = std::string(reinterpret_cast<const char *>(glewGetString(GLEW_VERSION)));
Log::success("Using GLEW: " + glewVersion);
}

int Application::run(int argc, char **argv)
{
// Print arguments
std::string args = "";
for (int i = 0; i < argc; i++) args += std::string(argv[i]) + " ";
Log::info("Command parameters (" + std::to_string(argc) + ") : " + args);
std::cout << std::endl;

uint32_t windowWidth = 1024;
uint32_t windowHeight = 512;
int scene = 1;

// Get arguments
if (argc >= 2) {
std::istringstream sceneStream(argv[1]);
int sceneInput;
if (sceneStream >> sceneInput) scene = sceneInput;
}

if (argc >= 4) {
std::istringstream widthStream(argv[2]);
std::istringstream heightStream(argv[3]);
uint32_t widthInput, heightInput;

if (widthStream >> widthInput && heightStream >> heightInput) {
windowWidth = widthInput;
windowHeight = heightInput;
}
}

// Initialize both GLEW and GLFW
try {
initializeGlfw(windowWidth, windowHeight);
initializeGlew();
} catch (const std::string &error) {
Log::error(error);
return EXIT_FAILURE;
}

// Create texture
Texture texture2D(window.getWidth(), window.getHeight());

// Create VAO
FullScreenVAO fullScreenVAO;

// Create compute shader
ComputeShader::printWorkGroupsCapabilities();
ComputeProgram computeProgram(window.getWidth(), window.getHeight(), 1);
Program displayProgram;

// Compile different shaders
try {
// Compute shader
std::string csPath = "./src/glsl/compute" + std::to_string(scene) + ".glsl";
ComputeShader computeShader(csPath.c_str());
computeShader.compile();

computeProgram.attachShader(computeShader);
computeProgram.link();

// Vertex shader and fragment shader
VertexShader vertexShader("./src/glsl/vertex.glsl");
FragmentShader fragmentShader("./src/glsl/fragment.glsl");

vertexShader.compile();
fragmentShader.compile();

displayProgram.attachShader(vertexShader);
displayProgram.attachShader(fragmentShader);

displayProgram.link();
} catch (const std::string &error) {
Log::error(error);
return EXIT_FAILURE;
}

// Game loop
while (!glfwWindowShouldClose(window.getGLFWwindow())) {
// Get time
float timeValue = glfwGetTime() / 2.0;

// COMPUTE SHADER EXECUTION --------------------------
computeProgram.beginUse();

// Set uniforms
computeProgram.setFloat("time", timeValue);

switch (scene) {
case 1:
computeProgram.setVec3("cameraPos", std::cos(timeValue) * 5.0,
(std::cos(timeValue / 2.0) + 1) * 2,
std::sin(timeValue) * 5.0);
computeProgram.setVec3("cameraLookAt", std::sin(timeValue / 10.0), 0.0,
std::cos(timeValue / 10.0));
break;
case 2:
computeProgram.setVec3("cameraPos", std::cos(timeValue) * 5.0,
(std::sin(timeValue / 2.0) + 1) * 2,
std::cos(timeValue) * 5.0);
computeProgram.setVec3("cameraLookAt", std::sin(timeValue / 10.0), 0.0,
std::cos(timeValue / 10.0));
break;
default:
break;
}

// Bind texture and dispatch
texture2D.bind();
texture2D.bindImageTexture();

computeProgram.dispatch();
computeProgram.memoryBarrier();

texture2D.unbindImageTexture();
texture2D.unbind();

computeProgram.endUse();
// COMPUTE SHADER EXECUTION --------------------------

// GLFW events and clear window
glfwPollEvents();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// DISPLAY TEXTURE -----------------------------------
displayProgram.beginUse();
fullScreenVAO.bind();
texture2D.beginUse();

fullScreenVAO.draw();

texture2D.endUse();
fullScreenVAO.unbind();
displayProgram.endUse();
// DISPLAY TEXTURE -----------------------------------

// Swap buffers
glfwSwapBuffers(window.getGLFWwindow());
}

// Exit
Log::message("Exiting program...");
std::cout << std::endl;
return EXIT_SUCCESS;
}
30 changes: 30 additions & 0 deletions src/app/Application.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef COMPUTE_SHADER_SRC_APP_APPLICATION_HPP_
#define COMPUTE_SHADER_SRC_APP_APPLICATION_HPP_

#include "app/ApplicationWindow.hpp"


class Application
{
public:
Application();

Application(const Application &other) = delete;
Application(Application &&other) = delete;
Application& operator=(const Application &other) = delete;
Application& operator=(Application &&other) = delete;

virtual ~Application() noexcept {};

public:
void initializeGlfw(const uint32_t width, const uint32_t height);
void initializeGlew();

void loop();
int run(int argc, char *argv[]);

private:
ApplicationWindow window;
};

#endif /* COMPUTE_SHADER_SRC_APP_APPLICATION_HPP_ */
Loading

0 comments on commit 32b7ad0

Please sign in to comment.