Use clang-format to reformat sources
This commit is contained in:
parent
2d439c3232
commit
eec1c251a3
6 changed files with 736 additions and 628 deletions
166
example02_threaded_raytracing/.clang-format
Normal file
166
example02_threaded_raytracing/.clang-format
Normal 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
|
||||||
|
...
|
||||||
|
|
|
@ -2,33 +2,35 @@
|
||||||
|
|
||||||
#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;
|
||||||
while(argc > 0) {
|
++argv;
|
||||||
|
while (argc > 0) {
|
||||||
found = false;
|
found = false;
|
||||||
for(const std::string &singleArg : singleArgs) {
|
for (const std::string &singleArg : singleArgs) {
|
||||||
if(std::strcmp(argv[0], singleArg.c_str()) == 0) {
|
if (std::strcmp(argv[0], singleArg.c_str()) == 0) {
|
||||||
result.insert({singleArg, EX02_ARG_PARSE_SINGLE_ARG_PLACEHOLDER});
|
result.insert({singleArg, EX02_ARG_PARSE_SINGLE_ARG_PLACEHOLDER});
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!found && argc > 1) {
|
if (!found && argc > 1) {
|
||||||
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;
|
||||||
|
|
|
@ -4,16 +4,17 @@
|
||||||
#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 {
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -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",
|
||||||
|
@ -39,15 +41,15 @@ int main(int argc, char **argv) {
|
||||||
"--output",
|
"--output",
|
||||||
});
|
});
|
||||||
|
|
||||||
if(auto iter = results.find("-h"); iter != results.end()) {
|
if (auto iter = results.find("-h"); iter != results.end()) {
|
||||||
printHelp();
|
printHelp();
|
||||||
return 0;
|
return 0;
|
||||||
} else if(auto iter = results.find("--help"); iter != results.end()) {
|
} else if (auto iter = results.find("--help"); iter != results.end()) {
|
||||||
printHelp();
|
printHelp();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto setThreadCount = [&threadCount] (auto iter) {
|
const auto setThreadCount = [&threadCount](auto iter) {
|
||||||
try {
|
try {
|
||||||
threadCount = std::stoi(iter->second);
|
threadCount = std::stoi(iter->second);
|
||||||
} catch (const std::invalid_argument &e) {
|
} catch (const std::invalid_argument &e) {
|
||||||
|
@ -61,45 +63,40 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
if(auto iter = results.find("-t"); iter != results.end()) {
|
if (auto iter = results.find("-t"); iter != results.end()) {
|
||||||
if(int result = setThreadCount(iter); result != 0) {
|
if (int result = setThreadCount(iter); result != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} else if(auto iter = results.find("--threads"); iter != results.end()) {
|
} else if (auto iter = results.find("--threads"); iter != results.end()) {
|
||||||
if(int result = setThreadCount(iter); result != 0) {
|
if (int result = setThreadCount(iter); result != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(outputWidth == 0) {
|
if (outputWidth == 0) {
|
||||||
std::cout << "ERROR: width cannot be 0" << std::endl;
|
std::cout << "ERROR: width cannot be 0" << std::endl;
|
||||||
return 7;
|
return 7;
|
||||||
}
|
}
|
||||||
if(auto iter = results.find("--height"); iter != results.end()) {
|
if (auto iter = results.find("--height"); iter != results.end()) {
|
||||||
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)"
|
||||||
|
@ -107,25 +104,25 @@ int main(int argc, char **argv) {
|
||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(outputHeight == 0) {
|
if (outputHeight == 0) {
|
||||||
std::cout << "ERROR: height cannot be 0" << std::endl;
|
std::cout << "ERROR: height cannot be 0" << std::endl;
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
if(auto iter = results.find("-o"); iter != results.end()) {
|
if (auto iter = results.find("-o"); iter != results.end()) {
|
||||||
outputFile = iter->second;
|
outputFile = iter->second;
|
||||||
} else if(auto iter = results.find("--output"); iter != results.end()) {
|
} else if (auto iter = results.find("--output"); iter != results.end()) {
|
||||||
outputFile = iter->second;
|
outputFile = iter->second;
|
||||||
}
|
}
|
||||||
if(outputFile.empty()) {
|
if (outputFile.empty()) {
|
||||||
std::cout << "ERROR: Output filename is empty" << std::endl;
|
std::cout << "ERROR: Output filename is empty" << std::endl;
|
||||||
return 12;
|
return 12;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
|
|
|
@ -1,45 +1,37 @@
|
||||||
#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) {
|
||||||
out << (int)data.at(i + j * width).r << ' '
|
out << (int)data.at(i + j * width).r << ' '
|
||||||
<< (int)data.at(i + j * width).g << ' '
|
<< (int)data.at(i + j * width).g << ' '
|
||||||
<< (int)data.at(i + j * width).b << ' ';
|
<< (int)data.at(i + j * width).b << ' ';
|
||||||
|
@ -70,25 +62,18 @@ 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
|
if (dist < falloffStart) {
|
||||||
+ pos.y * pos.y
|
const auto applyColor = [](auto *color, unsigned char *out) {
|
||||||
+ pos.z * pos.z);
|
unsigned int temp = (unsigned int)*out + (unsigned int)(*color * 255.0f);
|
||||||
if(dist < falloffStart) {
|
if (temp > 255) {
|
||||||
const auto applyColor = [] (auto *color, unsigned char *out) {
|
|
||||||
unsigned int temp = (unsigned int)*out
|
|
||||||
+ (unsigned int)(*color * 255.0f);
|
|
||||||
if(temp > 255) {
|
|
||||||
*out = 255;
|
*out = 255;
|
||||||
} else {
|
} else {
|
||||||
*out = temp;
|
*out = temp;
|
||||||
|
@ -97,11 +82,12 @@ void Ex02::RT::Internal::LightSource::applyLight(
|
||||||
applyColor(&color.x, &pixelOut.r);
|
applyColor(&color.x, &pixelOut.r);
|
||||||
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 =
|
||||||
if(temp > 255) {
|
(unsigned int)*out + (unsigned int)(*color * 255.0f * f);
|
||||||
|
if (temp > 255) {
|
||||||
*out = 255;
|
*out = 255;
|
||||||
} else {
|
} else {
|
||||||
*out = temp;
|
*out = temp;
|
||||||
|
@ -114,24 +100,20 @@ 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
|
if (dist < falloffStart) {
|
||||||
+ pos.y * pos.y
|
const auto applyColor = [](auto *color, unsigned char *out) {
|
||||||
+ pos.z * pos.z);
|
unsigned int temp = (unsigned int)*out + (unsigned int)(*color * 255.0f);
|
||||||
if(dist < falloffStart) {
|
if (temp > 255) {
|
||||||
const auto applyColor = [] (auto *color, unsigned char *out) {
|
|
||||||
unsigned int temp = (unsigned int)*out
|
|
||||||
+ (unsigned int)(*color * 255.0f);
|
|
||||||
if(temp > 255) {
|
|
||||||
*out = 255;
|
*out = 255;
|
||||||
} else {
|
} else {
|
||||||
*out = temp;
|
*out = temp;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if(mutex) {
|
if (mutex) {
|
||||||
std::lock_guard<std::mutex> lock(*mutex);
|
std::lock_guard<std::mutex> lock(*mutex);
|
||||||
applyColor(&color.x, &pixelOut.r);
|
applyColor(&color.x, &pixelOut.r);
|
||||||
applyColor(&color.y, &pixelOut.g);
|
applyColor(&color.y, &pixelOut.g);
|
||||||
|
@ -141,18 +123,19 @@ 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 =
|
||||||
if(temp > 255) {
|
(unsigned int)*out + (unsigned int)(*color * 255.0f * f);
|
||||||
|
if (temp > 255) {
|
||||||
*out = 255;
|
*out = 255;
|
||||||
} else {
|
} else {
|
||||||
*out = temp;
|
*out = temp;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
float f = (1.0f - (dist - falloffStart) / (falloffEnd - falloffStart));
|
float f = (1.0f - (dist - falloffStart) / (falloffEnd - falloffStart));
|
||||||
if(mutex) {
|
if (mutex) {
|
||||||
std::lock_guard<std::mutex> lock(*mutex);
|
std::lock_guard<std::mutex> lock(*mutex);
|
||||||
applyFalloffColor(&color.x, &pixelOut.r, f);
|
applyFalloffColor(&color.x, &pixelOut.r, f);
|
||||||
applyFalloffColor(&color.y, &pixelOut.g, f);
|
applyFalloffColor(&color.y, &pixelOut.g, f);
|
||||||
|
@ -165,55 +148,46 @@ 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;
|
||||||
float max = dist > dist2 ? dist : dist2;
|
float max = dist > dist2 ? dist : dist2;
|
||||||
if(min < 0.0f) {
|
if (min < 0.0f) {
|
||||||
if(max < 0.0f) {
|
if (max < 0.0f) {
|
||||||
return {};
|
return {};
|
||||||
} else {
|
} else {
|
||||||
return {rayPos + rayDirUnit * max};
|
return {rayPos + rayDirUnit * max};
|
||||||
|
@ -237,23 +211,20 @@ 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 {
|
||||||
return {{*collPos, toLight}};
|
return {{*collPos, toLight}};
|
||||||
|
@ -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};
|
||||||
|
@ -273,52 +243,46 @@ Ex02::RT::Image Ex02::RT::renderGraySphere(
|
||||||
const glm::vec3 rayPos{0.0f, 0.0f, 0.0f};
|
const glm::vec3 rayPos{0.0f, 0.0f, 0.0f};
|
||||||
const float lightFalloffStart = 4.5f;
|
const float lightFalloffStart = 4.5f;
|
||||||
const float lightFalloffEnd = 7.0f;
|
const float lightFalloffEnd = 7.0f;
|
||||||
// if(threadCount <= 1) {
|
// if(threadCount <= 1) {
|
||||||
for(unsigned int j = 0; j < outputHeight; ++j) {
|
for (unsigned int j = 0; j < outputHeight; ++j) {
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// } else {
|
// } else {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
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,28 +352,25 @@ 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}};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -418,69 +379,65 @@ Ex02::RT::Image Ex02::RT::renderColorsWithSpheres(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!closestResult) {
|
if (!closestResult) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cast ray to each light checking if colliding with other
|
// cast ray to each light checking if colliding with other
|
||||||
// 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;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(isBlocked) {
|
if (isBlocked) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if(threadCount <= 1) {
|
if (threadCount <= 1) {
|
||||||
for(unsigned int j = 0; j < outputHeight; ++j) {
|
for (unsigned int j = 0; j < outputHeight; ++j) {
|
||||||
yIteration(j, nullptr);
|
yIteration(j, nullptr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::vector<std::thread> threads;
|
std::vector<std::thread> threads;
|
||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
unsigned int range = outputHeight / threadCount;
|
unsigned int range = outputHeight / threadCount;
|
||||||
for(unsigned int threadIdx = 0; threadIdx < threadCount; ++threadIdx) {
|
for (unsigned int threadIdx = 0; threadIdx < threadCount; ++threadIdx) {
|
||||||
unsigned int start = range * threadIdx;
|
unsigned int start = range * threadIdx;
|
||||||
unsigned int end = range * (threadIdx + 1);
|
unsigned int end = range * (threadIdx + 1);
|
||||||
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(
|
||||||
for(unsigned int y = start; y < end; ++y) {
|
[&yIteration](unsigned int start, unsigned int end,
|
||||||
|
std::mutex *mutex) {
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,40 +7,40 @@
|
||||||
#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 {
|
||||||
|
|
||||||
struct Pixel {
|
struct Pixel {
|
||||||
Pixel();
|
Pixel();
|
||||||
|
|
||||||
unsigned char r,g,b;
|
unsigned char r, g, b;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Image {
|
class Image {
|
||||||
public:
|
public:
|
||||||
Image(unsigned int width, unsigned int height);
|
Image(unsigned int width, unsigned int height);
|
||||||
|
|
||||||
Pixel& getPixel(unsigned int x, unsigned int y);
|
Pixel &getPixel(unsigned int x, unsigned int y);
|
||||||
const Pixel& getPixel(unsigned int x, unsigned int y) const;
|
const Pixel &getPixel(unsigned int x, unsigned int y) const;
|
||||||
|
|
||||||
void writeToFile(const std::string &filename) const;
|
void writeToFile(const std::string &filename) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
std::vector<Pixel> data;
|
std::vector<Pixel> data;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
typedef std::optional<std::tuple<glm::vec3, glm::vec3>> RTSVisibleType;
|
typedef std::optional<std::tuple<glm::vec3, glm::vec3>> RTSVisibleType;
|
||||||
|
|
||||||
struct LightSource {
|
struct LightSource {
|
||||||
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue