WIP example02, simple ray tracing

This commit is contained in:
Stephen Seo 2021-08-20 21:25:24 +09:00
parent ca8ca5928c
commit d8ce741d76
7 changed files with 241 additions and 0 deletions

3
example02/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
build*/
compile_commands.json
.cache/

22
example02/CMakeLists.txt Normal file
View file

@ -0,0 +1,22 @@
cmake_minimum_required(VERSION 3.9)
project(Example02)
set(Example02_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/argParse.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/rayTracer.cpp")
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wpedantic")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
if(NOT CMAKE_BUILD_TYPE OR "${CMAKE_BUILD_TYPE}" MATCHES ^$)
set(CMAKE_BUILD_TYPE "Debug")
message("CMAKE_BUILD_TYPE is set to Debug by default")
endif()
add_executable(Example02
${Example02_SOURCES})
target_link_libraries(Example02 PUBLIC pthread)
target_compile_features(Example02 PUBLIC cxx_std_17)

View file

@ -0,0 +1,35 @@
#include "argParse.hpp"
#include <cstring>
Ex02::ArgParse::ParseResult Ex02::ArgParse::parseArgs(
int argc,
char **argv,
const Ex02::ArgParse::ArgsType &singleArgs,
const Ex02::ArgParse::ArgsType &doubleArgs) {
ParseResult result;
bool found;
--argc; ++argv;
while(argc > 0) {
found = false;
for(const std::string &singleArg : singleArgs) {
if(std::strcmp(argv[0], singleArg.c_str()) == 0) {
result.insert({singleArg, EX02_ARG_PARSE_SINGLE_ARG_PLACEHOLDER});
found = true;
break;
}
}
if(!found && argc > 1) {
for(const std::string &doubleArg: doubleArgs) {
if(std::strcmp(argv[0], doubleArg.c_str()) == 0) {
result.insert({doubleArg, argv[1]});
--argc; ++argv;
break;
}
}
}
--argc; ++argv;
}
return result;
}

View file

@ -0,0 +1,21 @@
#ifndef EXAMPLE_02_ARG_PARSE_HPP
#define EXAMPLE_02_ARG_PARSE_HPP
#define EX02_ARG_PARSE_SINGLE_ARG_PLACEHOLDER "SINGLE_ARG_PLACEHOLDER"
#include <string>
#include <unordered_set>
#include <unordered_map>
namespace Ex02 {
namespace ArgParse {
typedef std::unordered_set<std::string> ArgsType;
typedef std::unordered_map<std::string, std::string> ParseResult;
ParseResult parseArgs(int argc, char **argv, const ArgsType &singleArgs, const ArgsType &doubleArgs);
} // namespace ArgParse
} // namespace Ex02
#endif

72
example02/src/main.cpp Normal file
View file

@ -0,0 +1,72 @@
#include <iostream>
#include <string>
#include "argParse.hpp"
void printHelp() {
std::cout << "Usage:\n"
"-h | --help Display this help message\n"
"-t <integer>\n"
" | --threads <integer> Set the number of threads to use (default 1)"
<< std::endl;
}
int main(int argc, char **argv) {
int threadCount = 1;
{
auto results = Ex02::ArgParse::parseArgs(
argc,
argv,
{ // single args
"-h",
"--help",
},
{ // double args
"-t",
"--threads",
});
if(auto iter = results.find("-h"); iter != results.end()) {
printHelp();
return 0;
} else if(auto iter = results.find("--help"); iter != results.end()) {
printHelp();
return 0;
}
const auto setThreadCount = [&threadCount] (auto iter) {
try {
threadCount = std::stoi(iter->second);
} catch (const std::invalid_argument &e) {
std::cout << "ERROR: Failed to parse thread count (invalid)"
<< std::endl;
return 1;
} catch (const std::out_of_range &e) {
std::cout << "ERROR: Failed to parse thread count (out of range)"
<< std::endl;
return 2;
}
return 0;
};
if(auto iter = results.find("-t"); iter != results.end()) {
if(int result = setThreadCount(iter); result != 0) {
return result;
}
} else if(auto iter = results.find("--threads"); iter != results.end()) {
if(int result = setThreadCount(iter); result != 0) {
return result;
}
}
if(threadCount <= 0) {
std::cout << "ERROR: Thread count set to invalid value ("
<< threadCount
<< ')'
<< std::endl;
return 3;
}
}
return 0;
}

View file

@ -0,0 +1,52 @@
#include "rayTracer.hpp"
#include <cmath>
#include <glm/matrix.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/ext/matrix_transform.hpp>
const float PI = std::acos(-1.0f);
glm::vec3 Ex02::RT::Internal::defaultSpherePos() {
// the default model matrix pushes everything back 2 units,
// so it should be ok to define the sphere at location 0
return glm::vec3{0.0f, 0.0f, 0.0f};
}
glm::vec3 Ex02::RT::Internal::defaultLightPos() {
return glm::vec3{1.0f, 1.0f, 1.0f};
}
glm::mat4x4 Ex02::RT::Internal::defaultMVP() {
glm::mat4x4 mvp = glm::perspective(
PI / 2.0f,
1.0f,
EX02_RAY_TRACER_DEFAULT_NEAR_PLANE,
EX02_RAY_TRACER_DEFAULT_FAR_PLANE);
mvp *= glm::lookAt(
glm::vec3{0.0f, 0.0f, 0.0f},
glm::vec3{0.0f, 0.0f, -1.0f},
glm::vec3{0.0f, 1.0f, 0.0f});
// model pushes back by 2 units
mvp *= glm::translate(
glm::identity<glm::mat4x4>(),
glm::vec3{0.0f, 0.0f, -2.0f});
return mvp;
}
std::vector<unsigned char> Ex02::RT::renderGraySphere(
unsigned int outputWidth,
unsigned int outputHeight,
float sphereRadius,
int threadCount,
glm::vec3 spherePos,
glm::vec3 lightPos,
glm::mat4x4 mvp) {
std::vector<unsigned char> grayscalePixels;
return grayscalePixels;
}

View file

@ -0,0 +1,36 @@
#ifndef EX02_RAY_TRACER_HPP
#define EX02_RAY_TRACER_HPP
#define EX02_RAY_TRACER_DEFAULT_NEAR_PLANE 0.2f
#define EX02_RAY_TRACER_DEFAULT_FAR_PLANE 4.0f
#define EX02_RAY_TRACER_COLL_INCREMENT 2.0f
#include <vector>
#include <glm/vec3.hpp>
#include <glm/mat4x4.hpp>
#include <glm/matrix.hpp>
namespace Ex02 {
namespace RT {
namespace Internal {
glm::vec3 defaultSpherePos();
glm::vec3 defaultLightPos();
glm::mat4x4 defaultMVP();
}
std::vector<unsigned char> renderGraySphere(
unsigned int outputWidth,
unsigned int outputHeight,
float sphereRadius,
int threadCount = 1,
glm::vec3 spherePos = Internal::defaultSpherePos(),
glm::vec3 lightPos = Internal::defaultLightPos(),
glm::mat4x4 mvp = Internal::defaultMVP()
);
} // namespace RT
} // namespace Ex02
#endif