Fix
This commit is contained in:
@@ -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 },
|
||||
|
||||
@@ -64,7 +64,7 @@ void Renderer::Render() {
|
||||
ColorRGB finalColor{};
|
||||
constexpr int numVerticies = 3;
|
||||
|
||||
std::vector<Vertex> verticiesScreenSpace{};
|
||||
verticiesScreenSpace.clear();
|
||||
|
||||
for (const Mesh ¤tMesh: 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 };
|
||||
|
||||
@@ -121,6 +121,7 @@ namespace dae {
|
||||
|
||||
|
||||
std::vector<Mesh> m_worldMeshes{};
|
||||
std::vector<Vertex> verticiesScreenSpace{};
|
||||
|
||||
float* m_pDepthBufferPixels{};
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user