Use clang-format to reformat sources

This commit is contained in:
Stephen Seo 2021-08-24 12:42:18 +09:00
parent 2d439c3232
commit eec1c251a3
6 changed files with 736 additions and 628 deletions

View file

@ -0,0 +1,166 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: None
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
AttributeMacros:
- __capability
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: true
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
StatementAttributeLikeMacros:
- Q_EMIT
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 1
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentCaseLabels: false
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentRequires: false
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: Inner
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PenaltyIndentedWhitespace: 0
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SortJavaStaticImport: Before
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceAroundPointerQualifiers: Default
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
BitFieldColonSpacing: Both
Standard: Latest
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
- NS_SWIFT_NAME
- CF_SWIFT_NAME
...

View file

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

View file

@ -4,8 +4,8 @@
#define EX02_ARG_PARSE_SINGLE_ARG_PLACEHOLDER "SINGLE_ARG_PLACEHOLDER" #define EX02_ARG_PARSE_SINGLE_ARG_PLACEHOLDER "SINGLE_ARG_PLACEHOLDER"
#include <string> #include <string>
#include <unordered_set>
#include <unordered_map> #include <unordered_map>
#include <unordered_set>
namespace Ex02 { namespace Ex02 {
namespace ArgParse { namespace ArgParse {
@ -13,7 +13,8 @@ namespace ArgParse {
typedef std::unordered_set<std::string> ArgsType; typedef std::unordered_set<std::string> ArgsType;
typedef std::unordered_map<std::string, std::string> ParseResult; typedef std::unordered_map<std::string, std::string> ParseResult;
ParseResult parseArgs(int argc, char **argv, const ArgsType &singleArgs, const ArgsType &doubleArgs); ParseResult parseArgs(int argc, char **argv, const ArgsType &singleArgs,
const ArgsType &doubleArgs);
} // namespace ArgParse } // namespace ArgParse
} // namespace Ex02 } // namespace Ex02

View file

@ -5,10 +5,12 @@
#include "rayTracer.hpp" #include "rayTracer.hpp"
void printHelp() { void printHelp() {
std::cout << "Usage:\n" std::cout
<< "Usage:\n"
"-h | --help Display this help message\n" "-h | --help Display this help message\n"
"-t <integer>\n" "-t <integer>\n"
" | --threads <integer> Set the number of threads to use (default 1)\n" " | --threads <integer> Set the number of threads to use "
"(default 1)\n"
"--width <integer> Set the width of the output image\n" "--width <integer> Set the width of the output image\n"
"--height <integer> Set the height of the output image\n" "--height <integer> Set the height of the output image\n"
"-o <filename>\n" "-o <filename>\n"
@ -23,14 +25,14 @@ int main(int argc, char **argv) {
std::string outputFile = "raytrace_out"; std::string outputFile = "raytrace_out";
{ {
auto results = Ex02::ArgParse::parseArgs( auto results = Ex02::ArgParse::parseArgs(argc, argv,
argc, {
argv, // single args
{ // single args
"-h", "-h",
"--help", "--help",
}, },
{ // double args {
// double args
"-t", "-t",
"--threads", "--threads",
"--width", "--width",
@ -71,22 +73,18 @@ int main(int argc, char **argv) {
} }
} }
if (threadCount <= 0) { if (threadCount <= 0) {
std::cout << "ERROR: Thread count set to invalid value (" std::cout << "ERROR: Thread count set to invalid value (" << threadCount
<< threadCount << ')' << std::endl;
<< ')'
<< std::endl;
return 3; return 3;
} }
if (auto iter = results.find("--width"); iter != results.end()) { if (auto iter = results.find("--width"); iter != results.end()) {
try { try {
outputWidth = std::stoul(iter->second); outputWidth = std::stoul(iter->second);
} catch (const std::invalid_argument &e) { } catch (const std::invalid_argument &e) {
std::cout << "ERROR: Failed to parse width (invalid)" std::cout << "ERROR: Failed to parse width (invalid)" << std::endl;
<< std::endl;
return 3; return 3;
} catch (const std::out_of_range &e) { } catch (const std::out_of_range &e) {
std::cout << "ERROR: Failed to parse width (out of range)" std::cout << "ERROR: Failed to parse width (out of range)" << std::endl;
<< std::endl;
return 4; return 4;
} }
} }
@ -98,8 +96,7 @@ int main(int argc, char **argv) {
try { try {
outputHeight = std::stoul(iter->second); outputHeight = std::stoul(iter->second);
} catch (const std::invalid_argument &e) { } catch (const std::invalid_argument &e) {
std::cout << "ERROR: Failed to parse height (invalid)" std::cout << "ERROR: Failed to parse height (invalid)" << std::endl;
<< std::endl;
return 5; return 5;
} catch (const std::out_of_range &e) { } catch (const std::out_of_range &e) {
std::cout << "ERROR: Failed to parse height (out of range)" std::cout << "ERROR: Failed to parse height (out of range)"
@ -124,8 +121,8 @@ int main(int argc, char **argv) {
// auto pixels = Ex02::RT::renderGraySphere( // auto pixels = Ex02::RT::renderGraySphere(
// outputWidth, outputHeight, threadCount); // outputWidth, outputHeight, threadCount);
auto pixels = Ex02::RT::renderColorsWithSpheres( auto pixels =
outputWidth, outputHeight, threadCount); Ex02::RT::renderColorsWithSpheres(outputWidth, outputHeight, threadCount);
pixels.writeToFile(outputFile); pixels.writeToFile(outputFile);

View file

@ -1,42 +1,34 @@
#include "rayTracer.hpp" #include "rayTracer.hpp"
#include <array>
#include <cmath> #include <cmath>
#include <fstream> #include <fstream>
#include <array>
#include <thread> #include <thread>
#include <glm/matrix.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/ext/matrix_transform.hpp> #include <glm/ext/matrix_transform.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/matrix.hpp>
const float PI = std::acos(-1.0f); const float PI = std::acos(-1.0f);
Ex02::RT::Pixel::Pixel() : Ex02::RT::Pixel::Pixel() : r(0), g(0), b(0) {}
r(0),
g(0),
b(0)
{}
Ex02::RT::Image::Image(unsigned int width, unsigned int height) : Ex02::RT::Image::Image(unsigned int width, unsigned int height) : width(width) {
width(width)
{
data.resize(width * height); data.resize(width * height);
} }
Ex02::RT::Pixel& Ex02::RT::Image::getPixel( Ex02::RT::Pixel &Ex02::RT::Image::getPixel(unsigned int x, unsigned int y) {
unsigned int x, unsigned int y) {
return data.at(x + y * width); return data.at(x + y * width);
} }
const Ex02::RT::Pixel& Ex02::RT::Image::getPixel( const Ex02::RT::Pixel &Ex02::RT::Image::getPixel(unsigned int x,
unsigned int x, unsigned int y) const { unsigned int y) const {
return data.at(x + y * width); return data.at(x + y * width);
} }
void Ex02::RT::Image::writeToFile(const std::string &filename) const { void Ex02::RT::Image::writeToFile(const std::string &filename) const {
std::ofstream out(filename + ".ppm"); std::ofstream out(filename + ".ppm");
out << "P3\n" << width << ' ' << data.size() / width << " 255" out << "P3\n" << width << ' ' << data.size() / width << " 255" << '\n';
<< '\n';
for (unsigned int j = 0; j < data.size() / width; ++j) { for (unsigned int j = 0; j < data.size() / width; ++j) {
for (unsigned int i = 0; i < width; ++i) { for (unsigned int i = 0; i < width; ++i) {
@ -70,24 +62,17 @@ glm::mat4x4 Ex02::RT::Internal::defaultMVP() {
} }
*/ */
Ex02::RT::Internal::LightSource::LightSource() : Ex02::RT::Internal::LightSource::LightSource()
pos{0.0f, 0.0f, 0.0f}, : pos{0.0f, 0.0f, 0.0f}, falloffStart(2.0f),
falloffStart(2.0f), falloffEnd(7.0f), color{1.0f, 1.0f, 1.0f} {}
falloffEnd(7.0f),
color{1.0f, 1.0f, 1.0f}
{}
void Ex02::RT::Internal::LightSource::applyLight( void Ex02::RT::Internal::LightSource::applyLight(glm::vec3 pos,
glm::vec3 pos, Pixel &pixelOut) const { Pixel &pixelOut) const {
pos = this->pos - pos; pos = this->pos - pos;
float dist = std::sqrt( float dist = std::sqrt(pos.x * pos.x + pos.y * pos.y + pos.z * pos.z);
pos.x * pos.x
+ pos.y * pos.y
+ pos.z * pos.z);
if (dist < falloffStart) { if (dist < falloffStart) {
const auto applyColor = [](auto *color, unsigned char *out) { const auto applyColor = [](auto *color, unsigned char *out) {
unsigned int temp = (unsigned int)*out unsigned int temp = (unsigned int)*out + (unsigned int)(*color * 255.0f);
+ (unsigned int)(*color * 255.0f);
if (temp > 255) { if (temp > 255) {
*out = 255; *out = 255;
} else { } else {
@ -98,9 +83,10 @@ void Ex02::RT::Internal::LightSource::applyLight(
applyColor(&color.y, &pixelOut.g); applyColor(&color.y, &pixelOut.g);
applyColor(&color.z, &pixelOut.b); applyColor(&color.z, &pixelOut.b);
} else if (dist >= falloffStart && dist <= falloffEnd) { } else if (dist >= falloffStart && dist <= falloffEnd) {
const auto applyFalloffColor = [] (auto *color, unsigned char *out, float f) { const auto applyFalloffColor = [](auto *color, unsigned char *out,
unsigned int temp = (unsigned int)*out float f) {
+ (unsigned int)(*color * 255.0f * f); unsigned int temp =
(unsigned int)*out + (unsigned int)(*color * 255.0f * f);
if (temp > 255) { if (temp > 255) {
*out = 255; *out = 255;
} else { } else {
@ -114,17 +100,13 @@ void Ex02::RT::Internal::LightSource::applyLight(
} }
} }
void Ex02::RT::Internal::LightSource::applyLight( void Ex02::RT::Internal::LightSource::applyLight(glm::vec3 pos, Pixel &pixelOut,
glm::vec3 pos, Pixel &pixelOut, std::mutex* mutex) const { std::mutex *mutex) const {
pos = this->pos - pos; pos = this->pos - pos;
float dist = std::sqrt( float dist = std::sqrt(pos.x * pos.x + pos.y * pos.y + pos.z * pos.z);
pos.x * pos.x
+ pos.y * pos.y
+ pos.z * pos.z);
if (dist < falloffStart) { if (dist < falloffStart) {
const auto applyColor = [](auto *color, unsigned char *out) { const auto applyColor = [](auto *color, unsigned char *out) {
unsigned int temp = (unsigned int)*out unsigned int temp = (unsigned int)*out + (unsigned int)(*color * 255.0f);
+ (unsigned int)(*color * 255.0f);
if (temp > 255) { if (temp > 255) {
*out = 255; *out = 255;
} else { } else {
@ -142,9 +124,10 @@ void Ex02::RT::Internal::LightSource::applyLight(
applyColor(&color.z, &pixelOut.b); applyColor(&color.z, &pixelOut.b);
} }
} else if (dist >= falloffStart && dist <= falloffEnd) { } else if (dist >= falloffStart && dist <= falloffEnd) {
const auto applyFalloffColor = [] (auto *color, unsigned char *out, float f) { const auto applyFalloffColor = [](auto *color, unsigned char *out,
unsigned int temp = (unsigned int)*out float f) {
+ (unsigned int)(*color * 255.0f * f); unsigned int temp =
(unsigned int)*out + (unsigned int)(*color * 255.0f * f);
if (temp > 255) { if (temp > 255) {
*out = 255; *out = 255;
} else { } else {
@ -165,49 +148,40 @@ void Ex02::RT::Internal::LightSource::applyLight(
} }
} }
Ex02::RT::Internal::Sphere::Sphere() : Ex02::RT::Internal::Sphere::Sphere() : pos{0.0f, 0.0f, 0.0f}, radius(2.5f) {}
pos{0.0f, 0.0f, 0.0f},
radius(2.5f)
{}
std::optional<glm::vec3> Ex02::RT::Internal::Sphere::rayToSphere( std::optional<glm::vec3>
glm::vec3 rayPos, glm::vec3 rayDirUnit) const { Ex02::RT::Internal::Sphere::rayToSphere(glm::vec3 rayPos,
glm::vec3 rayDirUnit) const {
return Ex02::RT::Internal::rayToSphere(rayPos, rayDirUnit, pos, radius); return Ex02::RT::Internal::rayToSphere(rayPos, rayDirUnit, pos, radius);
} }
Ex02::RT::Internal::RTSVisibleType Ex02::RT::Internal::Sphere::rayToSphereVisible( Ex02::RT::Internal::RTSVisibleType
glm::vec3 rayPos, glm::vec3 rayDirUnit, Ex02::RT::Internal::Sphere::rayToSphereVisible(glm::vec3 rayPos,
glm::vec3 rayDirUnit,
const LightSource &light) const { const LightSource &light) const {
return Ex02::RT::Internal::rayToSphereVisible( return Ex02::RT::Internal::rayToSphereVisible(rayPos, rayDirUnit, pos, radius,
rayPos, rayDirUnit, pos, radius, light.pos); light.pos);
} }
std::optional<glm::vec3> Ex02::RT::Internal::rayToSphere( std::optional<glm::vec3> Ex02::RT::Internal::rayToSphere(glm::vec3 rayPos,
glm::vec3 rayPos,
glm::vec3 rayDirUnit, glm::vec3 rayDirUnit,
glm::vec3 spherePos, glm::vec3 spherePos,
float sphereRadius) { float sphereRadius) {
// check if there is collision // check if there is collision
glm::vec3 tempVec = rayPos - spherePos; glm::vec3 tempVec = rayPos - spherePos;
float temp = float temp = rayDirUnit.x * tempVec.x + rayDirUnit.y * tempVec.y +
rayDirUnit.x * tempVec.x rayDirUnit.z * tempVec.z;
+ rayDirUnit.y * tempVec.y
+ rayDirUnit.z * tempVec.z;
float delta = temp * temp; float delta = temp * temp;
temp = temp = tempVec.x * tempVec.x + tempVec.y * tempVec.y + tempVec.z * tempVec.z -
tempVec.x * tempVec.x sphereRadius * sphereRadius;
+ tempVec.y * tempVec.y
+ tempVec.z * tempVec.z
- sphereRadius * sphereRadius;
delta -= temp; delta -= temp;
if (delta < 0.0f) { if (delta < 0.0f) {
return {}; return {};
} else { } else {
temp = temp = rayDirUnit.x * tempVec.x + rayDirUnit.y * tempVec.y +
rayDirUnit.x * tempVec.x rayDirUnit.z * tempVec.z;
+ rayDirUnit.y * tempVec.y
+ rayDirUnit.z * tempVec.z;
float dist = -temp - std::sqrt(delta); float dist = -temp - std::sqrt(delta);
float dist2 = -temp + std::sqrt(delta); float dist2 = -temp + std::sqrt(delta);
float min = dist > dist2 ? dist2 : dist; float min = dist > dist2 ? dist2 : dist;
@ -237,22 +211,19 @@ float Ex02::RT::Internal::distBetweenPositions(glm::vec3 a, glm::vec3 b) {
return std::sqrt(a.x * a.x + a.y * a.y + a.z * a.z); return std::sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
} }
Ex02::RT::Internal::RTSVisibleType Ex02::RT::Internal::rayToSphereVisible( Ex02::RT::Internal::RTSVisibleType
glm::vec3 rayPos, Ex02::RT::Internal::rayToSphereVisible(glm::vec3 rayPos, glm::vec3 rayDirUnit,
glm::vec3 rayDirUnit, glm::vec3 spherePos, float sphereRadius,
glm::vec3 spherePos,
float sphereRadius,
glm::vec3 lightPos) { glm::vec3 lightPos) {
auto collPos = rayToSphere(rayPos, rayDirUnit, spherePos, sphereRadius); auto collPos = rayToSphere(rayPos, rayDirUnit, spherePos, sphereRadius);
if (collPos) { if (collPos) {
glm::vec3 toLight = lightPos - *collPos; glm::vec3 toLight = lightPos - *collPos;
glm::vec3 toLightUnit = toLight / std::sqrt( glm::vec3 toLightUnit =
toLight.x * toLight.x toLight / std::sqrt(toLight.x * toLight.x + toLight.y * toLight.y +
+ toLight.y * toLight.y toLight.z * toLight.z);
+ toLight.z * toLight.z);
glm::vec3 toLightPos = *collPos + toLight / 3.0f; glm::vec3 toLightPos = *collPos + toLight / 3.0f;
auto collResult = Internal::rayToSphere( auto collResult =
toLightPos, toLightUnit, spherePos, sphereRadius); Internal::rayToSphere(toLightPos, toLightUnit, spherePos, sphereRadius);
if (collResult) { if (collResult) {
return {}; return {};
} else { } else {
@ -263,8 +234,7 @@ Ex02::RT::Internal::RTSVisibleType Ex02::RT::Internal::rayToSphereVisible(
} }
} }
Ex02::RT::Image Ex02::RT::renderGraySphere( Ex02::RT::Image Ex02::RT::renderGraySphere(unsigned int outputWidth,
unsigned int outputWidth,
unsigned int outputHeight, unsigned int outputHeight,
unsigned int threadCount) { unsigned int threadCount) {
const glm::vec3 spherePos{0.0f, 0.0f, -2.5f}; const glm::vec3 spherePos{0.0f, 0.0f, -2.5f};
@ -278,33 +248,28 @@ Ex02::RT::Image Ex02::RT::renderGraySphere(
float offsetY = ((float)j + 0.5f - ((float)outputHeight / 2.0f)); float offsetY = ((float)j + 0.5f - ((float)outputHeight / 2.0f));
for (unsigned int i = 0; i < outputWidth; ++i) { for (unsigned int i = 0; i < outputWidth; ++i) {
float offsetX = ((float)i + 0.5f - ((float)outputWidth / 2.0f)); float offsetX = ((float)i + 0.5f - ((float)outputWidth / 2.0f));
glm::vec3 rayDir{ glm::vec3 rayDir{offsetX, offsetY,
offsetX,
offsetY,
-(float)outputHeight * EX02_RAY_TRACER_VIEW_RATIO}; -(float)outputHeight * EX02_RAY_TRACER_VIEW_RATIO};
glm::vec3 rayDirUnit = rayDir / std::sqrt( glm::vec3 rayDirUnit =
rayDir.x * rayDir.x rayDir / std::sqrt(rayDir.x * rayDir.x + rayDir.y * rayDir.y +
+ rayDir.y * rayDir.y rayDir.z * rayDir.z);
+ rayDir.z * rayDir.z);
auto rayResult = Internal::rayToSphereVisible( auto rayResult = Internal::rayToSphereVisible(
rayPos, rayDirUnit, rayPos, rayDirUnit, spherePos, EX02_RAY_TRACER_GRAY_SPHERE_RADIUS,
spherePos, EX02_RAY_TRACER_GRAY_SPHERE_RADIUS,
lightPos); lightPos);
if (rayResult) { if (rayResult) {
glm::vec3 *toLight = &std::get<1>(rayResult.value()); glm::vec3 *toLight = &std::get<1>(rayResult.value());
float dist = std::sqrt( float dist =
toLight->x * toLight->x std::sqrt(toLight->x * toLight->x + toLight->y * toLight->y +
+ toLight->y * toLight->y toLight->z * toLight->z);
+ toLight->z * toLight->z);
if (dist < lightFalloffStart) { if (dist < lightFalloffStart) {
image.getPixel(i, j).r = 255; image.getPixel(i, j).r = 255;
image.getPixel(i, j).g = 255; image.getPixel(i, j).g = 255;
image.getPixel(i, j).b = 255; image.getPixel(i, j).b = 255;
} else if (dist >= lightFalloffStart && dist <= lightFalloffEnd) { } else if (dist >= lightFalloffStart && dist <= lightFalloffEnd) {
image.getPixel(i, j).r = image.getPixel(i, j).r =
(1.0f - (dist - lightFalloffStart) (1.0f - (dist - lightFalloffStart) /
/ (lightFalloffEnd - lightFalloffStart)) (lightFalloffEnd - lightFalloffStart)) *
* 255.0f; 255.0f;
image.getPixel(i, j).g = image.getPixel(i, j).r; image.getPixel(i, j).g = image.getPixel(i, j).r;
image.getPixel(i, j).b = image.getPixel(i, j).r; image.getPixel(i, j).b = image.getPixel(i, j).r;
} }
@ -317,8 +282,7 @@ Ex02::RT::Image Ex02::RT::renderGraySphere(
return image; return image;
} }
Ex02::RT::Image Ex02::RT::renderColorsWithSpheres( Ex02::RT::Image Ex02::RT::renderColorsWithSpheres(unsigned int outputWidth,
unsigned int outputWidth,
unsigned int outputHeight, unsigned int outputHeight,
unsigned int threadCount) { unsigned int threadCount) {
Image image(outputWidth, outputHeight); Image image(outputWidth, outputHeight);
@ -388,26 +352,23 @@ Ex02::RT::Image Ex02::RT::renderColorsWithSpheres(
lights[2].falloffStart = 3.0f; lights[2].falloffStart = 3.0f;
lights[2].falloffEnd = 7.0f; lights[2].falloffEnd = 7.0f;
const auto yIteration = [&spheres, &lights, &image, outputWidth, outputHeight, rayPos] (unsigned int j, std::mutex *mutex) { const auto yIteration = [&spheres, &lights, &image, outputWidth, outputHeight,
rayPos](unsigned int j, std::mutex *mutex) {
float offsetY = ((float)j + 0.5f - ((float)outputHeight / 2.0f)); float offsetY = ((float)j + 0.5f - ((float)outputHeight / 2.0f));
for (unsigned int i = 0; i < outputWidth; ++i) { for (unsigned int i = 0; i < outputWidth; ++i) {
float offsetX = ((float)i + 0.5f - ((float)outputWidth / 2.0f)); float offsetX = ((float)i + 0.5f - ((float)outputWidth / 2.0f));
glm::vec3 rayDir{ glm::vec3 rayDir{offsetX, offsetY,
offsetX,
offsetY,
-(float)outputHeight * EX02_RAY_TRACER_VIEW_RATIO}; -(float)outputHeight * EX02_RAY_TRACER_VIEW_RATIO};
glm::vec3 rayDirUnit = rayDir / std::sqrt( glm::vec3 rayDirUnit =
rayDir.x * rayDir.x rayDir / std::sqrt(rayDir.x * rayDir.x + rayDir.y * rayDir.y +
+ rayDir.y * rayDir.y rayDir.z * rayDir.z);
+ rayDir.z * rayDir.z);
// cast ray to all spheres, finding closest result // cast ray to all spheres, finding closest result
std::optional<std::tuple<glm::vec3, float, unsigned int>> closestResult; std::optional<std::tuple<glm::vec3, float, unsigned int>> closestResult;
for (unsigned int idx = 0; idx < spheres.size(); ++idx) { for (unsigned int idx = 0; idx < spheres.size(); ++idx) {
auto result = spheres[idx].rayToSphere(rayPos, rayDirUnit); auto result = spheres[idx].rayToSphere(rayPos, rayDirUnit);
if (result) { if (result) {
float dist = Internal::distBetweenPositions( float dist = Internal::distBetweenPositions(rayPos, spheres[idx].pos);
rayPos, spheres[idx].pos);
if (closestResult) { if (closestResult) {
if (dist < std::get<1>(*closestResult)) { if (dist < std::get<1>(*closestResult)) {
closestResult = {{*result, dist, idx}}; closestResult = {{*result, dist, idx}};
@ -426,17 +387,15 @@ Ex02::RT::Image Ex02::RT::renderColorsWithSpheres(
// spheres // spheres
for (const auto &light : lights) { for (const auto &light : lights) {
glm::vec3 toLight = light.pos - std::get<0>(*closestResult); glm::vec3 toLight = light.pos - std::get<0>(*closestResult);
glm::vec3 toLightUnit = toLight / std::sqrt( glm::vec3 toLightUnit =
toLight.x * toLight.x toLight / std::sqrt(toLight.x * toLight.x + toLight.y * toLight.y +
+ toLight.y * toLight.y toLight.z * toLight.z);
+ toLight.z * toLight.z);
bool isBlocked = false; bool isBlocked = false;
for (unsigned int idx = 0; idx < spheres.size(); ++idx) { for (unsigned int idx = 0; idx < spheres.size(); ++idx) {
if (idx == std::get<2>(*closestResult)) { if (idx == std::get<2>(*closestResult)) {
continue; continue;
} }
auto result = spheres[idx].rayToSphere( auto result = spheres[idx].rayToSphere(std::get<0>(*closestResult),
std::get<0>(*closestResult),
toLightUnit); toLightUnit);
if (result) { if (result) {
isBlocked = true; isBlocked = true;
@ -449,9 +408,7 @@ Ex02::RT::Image Ex02::RT::renderColorsWithSpheres(
// at this point, it is known that no spheres blocks ray // at this point, it is known that no spheres blocks ray
// to light // to light
light.applyLight( light.applyLight(std::get<0>(*closestResult), image.getPixel(i, j),
std::get<0>(*closestResult),
image.getPixel(i, j),
mutex); mutex);
} }
} }
@ -471,14 +428,14 @@ Ex02::RT::Image Ex02::RT::renderColorsWithSpheres(
if (threadIdx + 1 == threadCount) { if (threadIdx + 1 == threadCount) {
end = outputHeight; end = outputHeight;
} }
threads.emplace_back(std::thread([&yIteration] (unsigned int start, unsigned int end, std::mutex *mutex) { threads.emplace_back(std::thread(
[&yIteration](unsigned int start, unsigned int end,
std::mutex *mutex) {
for (unsigned int y = start; y < end; ++y) { for (unsigned int y = start; y < end; ++y) {
yIteration(y, mutex); yIteration(y, mutex);
} }
}, },
start, start, end, &mutex));
end,
&mutex));
} }
for (std::thread &thread : threads) { for (std::thread &thread : threads) {
thread.join(); thread.join();

View file

@ -7,15 +7,15 @@
#define EX02_RAY_TRACER_COLL_INCREMENT 2.0f #define EX02_RAY_TRACER_COLL_INCREMENT 2.0f
#define EX02_RAY_TRACER_GRAY_SPHERE_RADIUS 1.5f #define EX02_RAY_TRACER_GRAY_SPHERE_RADIUS 1.5f
#include <vector> #include <mutex>
#include <optional> #include <optional>
#include <string> #include <string>
#include <tuple> #include <tuple>
#include <mutex> #include <vector>
#include <glm/vec3.hpp>
#include <glm/mat4x4.hpp> #include <glm/mat4x4.hpp>
#include <glm/matrix.hpp> #include <glm/matrix.hpp>
#include <glm/vec3.hpp>
namespace Ex02 { namespace Ex02 {
namespace RT { namespace RT {
@ -61,49 +61,34 @@ namespace Internal {
glm::vec3 pos; glm::vec3 pos;
float radius; float radius;
std::optional<glm::vec3> rayToSphere( std::optional<glm::vec3> rayToSphere(glm::vec3 rayPos,
glm::vec3 rayPos, glm::vec3 rayDirUnit) const; glm::vec3 rayDirUnit) const;
RTSVisibleType rayToSphereVisible( RTSVisibleType rayToSphereVisible(glm::vec3 rayPos, glm::vec3 rayDirUnit,
glm::vec3 rayPos, glm::vec3 rayDirUnit,
const LightSource &light) const; const LightSource &light) const;
}; };
// returns pos of collision // returns pos of collision
std::optional<glm::vec3> rayToSphere( std::optional<glm::vec3> rayToSphere(glm::vec3 rayPos, glm::vec3 rayDirUnit,
glm::vec3 rayPos,
glm::vec3 rayDirUnit,
glm::vec3 spherePos, glm::vec3 spherePos,
float sphereRadius); float sphereRadius);
float angleBetweenRays( float angleBetweenRays(glm::vec3 a, glm::vec3 b);
glm::vec3 a,
glm::vec3 b);
float distBetweenPositions( float distBetweenPositions(glm::vec3 a, glm::vec3 b);
glm::vec3 a,
glm::vec3 b);
// first vec3 is result from rayToSphere(), second is ray to light source // first vec3 is result from rayToSphere(), second is ray to light source
RTSVisibleType rayToSphereVisible( RTSVisibleType rayToSphereVisible(glm::vec3 rayPos, glm::vec3 rayDirUnit,
glm::vec3 rayPos, glm::vec3 spherePos, float sphereRadius,
glm::vec3 rayDirUnit,
glm::vec3 spherePos,
float sphereRadius,
glm::vec3 lightPos); glm::vec3 lightPos);
} } // namespace Internal
Image renderGraySphere( Image renderGraySphere(unsigned int outputWidth, unsigned int outputHeight,
unsigned int outputWidth, unsigned int threadCount = 1);
unsigned int outputHeight,
unsigned int threadCount = 1
);
Image renderColorsWithSpheres( Image renderColorsWithSpheres(unsigned int outputWidth,
unsigned int outputWidth,
unsigned int outputHeight, unsigned int outputHeight,
unsigned int threadCount = 1 unsigned int threadCount = 1);
);
} // namespace RT } // namespace RT
} // namespace Ex02 } // namespace Ex02