This commit is contained in:
2024-12-11 17:30:25 +01:00
parent 98f3fc50cd
commit bbf119b3d4
4 changed files with 136 additions and 155 deletions

View File

@@ -152,16 +152,6 @@ namespace dae {
}
Matrix Matrix::CreatePerspectiveFovLH(float fovy, float aspect, float zn, float zf) {
// const float yScale = 1.f / tanf(fovy / 2.f);
// const float xScale = yScale / aspect;
//
// return {
// {xScale, 0, 0, 0},
// {0, yScale, 0, 0},
// {0, 0, zf / (zf - zn), 1},
// {0, 0, -zn * zf / (zf - zn), 0}
// };
return Matrix(
{ 1.f / (aspect * fovy), 0, 0, 0 },
{ 0, 1.f / fovy, 0, 0 },

View File

@@ -64,7 +64,7 @@ void Renderer::Render() {
ColorRGB finalColor{};
constexpr int numVerticies = 3;
std::vector<Vertex> verticiesScreenSpace{};
verticiesScreenSpace.clear();
for (const Mesh &currentMesh: m_worldMeshes) {
@@ -184,6 +184,24 @@ void Renderer::Render() {
}
}
float min{std::numeric_limits<float>::max()};
float max{std::numeric_limits<float>::min()};
for (int i{}; i < m_Width * m_Height; ++i) {
if (m_pDepthBufferPixels[i] == std::numeric_limits<float>::max()) {
continue;
}
min = std::min(min, m_pDepthBufferPixels[i]);
max = std::max(max, m_pDepthBufferPixels[i]);
}
for (int i{}; i < m_Width * m_Height; ++i) {
if (m_pDepthBufferPixels[i] == std::numeric_limits<float>::max()) {
continue;
}
m_pDepthBufferPixels[i] = (m_pDepthBufferPixels[i] - min) / (max - min);
}
//RENDER LOGIC
@@ -240,7 +258,7 @@ bool Renderer::SaveBufferToImage() const {
return SDL_SaveBMP(m_pBackBuffer, "Rasterizer_ColorBuffer.bmp");
}
ColorRGB Renderer::shadePixel(const Sample &sample) {
ColorRGB Renderer::shadePixel(const Sample& sample) {
Vector3 lightDirection = { .577f, -.577f, .577f};
Vector3 normal = sample.normal.Normalized();
constexpr float lightIntensity{ 7.f };

View File

@@ -121,6 +121,7 @@ namespace dae {
std::vector<Mesh> m_worldMeshes{};
std::vector<Vertex> verticiesScreenSpace{};
float* m_pDepthBufferPixels{};

View File

@@ -1,4 +1,5 @@
#pragma once
#include <cassert>
#include <fstream>
#include "Maths.h"
@@ -6,171 +7,142 @@
//#define DISABLE_OBJ
namespace dae
{
namespace Utils
{
//Just parses vertices and indices
namespace dae {
namespace Utils {
//Just parses vertices and indices
#pragma warning(push)
#pragma warning(disable : 4505) //Warning unreferenced local function
static bool ParseOBJ(const std::string& filename, std::vector<Vertex>& vertices, std::vector<uint32_t>& indices, bool flipAxisAndWinding = true)
{
#ifdef DISABLE_OBJ
//TODO: Enable the code below after uncommenting all the vertex attributes of DataTypes::Vertex
// >> Comment/Remove '#define DISABLE_OBJ'
assert(false && "OBJ PARSER not enabled! Check the comments in Utils::ParseOBJ");
static bool ParseOBJ(const std::string &filename, std::vector<Vertex> &vertices, std::vector<uint32_t> &indices,
bool flipAxisAndWinding = true) {
std::ifstream file(filename);
if (!file)
return false;
#else
std::vector<Vector3> positions{};
std::vector<Vector3> normals{};
std::vector<Vector2> UVs{};
std::ifstream file(filename);
if (!file)
return false;
vertices.clear();
indices.clear();
std::vector<Vector3> positions{};
std::vector<Vector3> normals{};
std::vector<Vector2> UVs{};
std::string sCommand;
// start a while iteration ending when the end of file is reached (ios::eof)
while (!file.eof()) {
//read the first word of the string, use the >> operator (istream::operator>>)
file >> sCommand;
//use conditional statements to process the different commands
if (sCommand == "#") {
// Ignore Comment
} else if (sCommand == "v") {
//Vertex
float x, y, z;
file >> x >> y >> z;
vertices.clear();
indices.clear();
positions.emplace_back(x, y, z);
} else if (sCommand == "vt") {
// Vertex TexCoord
float u, v;
file >> u >> v;
UVs.emplace_back(u, 1 - v);
} else if (sCommand == "vn") {
// Vertex Normal
float x, y, z;
file >> x >> y >> z;
std::string sCommand;
// start a while iteration ending when the end of file is reached (ios::eof)
while (!file.eof())
{
//read the first word of the string, use the >> operator (istream::operator>>)
file >> sCommand;
//use conditional statements to process the different commands
if (sCommand == "#")
{
// Ignore Comment
}
else if (sCommand == "v")
{
//Vertex
float x, y, z;
file >> x >> y >> z;
normals.emplace_back(x, y, z);
} else if (sCommand == "f") {
//if a face is read:
//construct the 3 vertices, add them to the vertex array
//add three indices to the index array
//add the material index as attibute to the attribute array
//
// Faces or triangles
Vertex vertex{};
size_t iPosition, iTexCoord, iNormal;
positions.emplace_back(x, y, z);
}
else if (sCommand == "vt")
{
// Vertex TexCoord
float u, v;
file >> u >> v;
UVs.emplace_back(u, 1 - v);
}
else if (sCommand == "vn")
{
// Vertex Normal
float x, y, z;
file >> x >> y >> z;
uint32_t tempIndices[3];
for (size_t iFace = 0; iFace < 3; iFace++) {
// OBJ format uses 1-based arrays
file >> iPosition;
vertex.position = positions[iPosition - 1].ToVector4();
normals.emplace_back(x, y, z);
}
else if (sCommand == "f")
{
//if a face is read:
//construct the 3 vertices, add them to the vertex array
//add three indices to the index array
//add the material index as attibute to the attribute array
//
// Faces or triangles
Vertex vertex{};
size_t iPosition, iTexCoord, iNormal;
if ('/' == file.peek())//is next in buffer == '/' ?
{
file.ignore();//read and ignore one element ('/')
uint32_t tempIndices[3];
for (size_t iFace = 0; iFace < 3; iFace++)
{
// OBJ format uses 1-based arrays
file >> iPosition;
vertex.position = positions[iPosition - 1].ToVector4();
if ('/' != file.peek()) {
// Optional texture coordinate
file >> iTexCoord;
vertex.uv = UVs[iTexCoord - 1];
}
if ('/' == file.peek())//is next in buffer == '/' ?
{
file.ignore();//read and ignore one element ('/')
if ('/' == file.peek()) {
file.ignore();
if ('/' != file.peek())
{
// Optional texture coordinate
file >> iTexCoord;
vertex.uv = UVs[iTexCoord - 1];
}
// Optional vertex normal
file >> iNormal;
vertex.normal = normals[iNormal - 1];
}
}
if ('/' == file.peek())
{
file.ignore();
vertices.push_back(vertex);
tempIndices[iFace] = uint32_t(vertices.size()) - 1;
//indices.push_back(uint32_t(vertices.size()) - 1);
}
// Optional vertex normal
file >> iNormal;
vertex.normal = normals[iNormal - 1];
}
}
indices.push_back(tempIndices[0]);
if (flipAxisAndWinding) {
indices.push_back(tempIndices[2]);
indices.push_back(tempIndices[1]);
} else {
indices.push_back(tempIndices[1]);
indices.push_back(tempIndices[2]);
}
}
//read till end of line and ignore all remaining chars
file.ignore(1000, '\n');
}
vertices.push_back(vertex);
tempIndices[iFace] = uint32_t(vertices.size()) - 1;
//indices.push_back(uint32_t(vertices.size()) - 1);
}
//Cheap Tangent Calculations
for (uint32_t i = 0; i < indices.size(); i += 3) {
uint32_t index0 = indices[i];
uint32_t index1 = indices[size_t(i) + 1];
uint32_t index2 = indices[size_t(i) + 2];
indices.push_back(tempIndices[0]);
if (flipAxisAndWinding)
{
indices.push_back(tempIndices[2]);
indices.push_back(tempIndices[1]);
}
else
{
indices.push_back(tempIndices[1]);
indices.push_back(tempIndices[2]);
}
}
//read till end of line and ignore all remaining chars
file.ignore(1000, '\n');
}
const Vector3 &p0 = vertices[index0].position;
const Vector3 &p1 = vertices[index1].position;
const Vector3 &p2 = vertices[index2].position;
const Vector2 &uv0 = vertices[index0].uv;
const Vector2 &uv1 = vertices[index1].uv;
const Vector2 &uv2 = vertices[index2].uv;
//Cheap Tangent Calculations
for (uint32_t i = 0; i < indices.size(); i += 3)
{
uint32_t index0 = indices[i];
uint32_t index1 = indices[size_t(i) + 1];
uint32_t index2 = indices[size_t(i) + 2];
const Vector3 edge0 = p1 - p0;
const Vector3 edge1 = p2 - p0;
const Vector2 diffX = Vector2(uv1.x - uv0.x, uv2.x - uv0.x);
const Vector2 diffY = Vector2(uv1.y - uv0.y, uv2.y - uv0.y);
float r = 1.f / Vector2::Cross(diffX, diffY);
const Vector3& p0 = vertices[index0].position;
const Vector3& p1 = vertices[index1].position;
const Vector3& p2 = vertices[index2].position;
const Vector2& uv0 = vertices[index0].uv;
const Vector2& uv1 = vertices[index1].uv;
const Vector2& uv2 = vertices[index2].uv;
Vector3 tangent = (edge0 * diffY.y - edge1 * diffY.x) * r;
vertices[index0].tangent += tangent;
vertices[index1].tangent += tangent;
vertices[index2].tangent += tangent;
}
const Vector3 edge0 = p1 - p0;
const Vector3 edge1 = p2 - p0;
const Vector2 diffX = Vector2(uv1.x - uv0.x, uv2.x - uv0.x);
const Vector2 diffY = Vector2(uv1.y - uv0.y, uv2.y - uv0.y);
float r = 1.f / Vector2::Cross(diffX, diffY);
//Fix the tangents per vertex now because we accumulated
for (auto &v: vertices) {
v.tangent = Vector3::Reject(v.tangent, v.normal).Normalized();
Vector3 tangent = (edge0 * diffY.y - edge1 * diffY.x) * r;
vertices[index0].tangent += tangent;
vertices[index1].tangent += tangent;
vertices[index2].tangent += tangent;
}
if (flipAxisAndWinding) {
v.position.z *= -1.f;
v.normal.z *= -1.f;
v.tangent.z *= -1.f;
}
//Fix the tangents per vertex now because we accumulated
for (auto& v : vertices)
{
v.tangent = Vector3::Reject(v.tangent, v.normal).Normalized();
}
if(flipAxisAndWinding)
{
v.position.z *= -1.f;
v.normal.z *= -1.f;
v.tangent.z *= -1.f;
}
}
return true;
#endif
}
return true;
}
#pragma warning(pop)
}
}
}