Boom exam done!
@@ -9,6 +9,7 @@ set(SOURCES
|
|||||||
"src/Texture.cpp"
|
"src/Texture.cpp"
|
||||||
"src/GamePadController.cpp"
|
"src/GamePadController.cpp"
|
||||||
"src/Utils.cpp"
|
"src/Utils.cpp"
|
||||||
|
"src/HitTest.cpp"
|
||||||
"src/Material.cpp"
|
"src/Material.cpp"
|
||||||
"src/Math/Vector2.cpp"
|
"src/Math/Vector2.cpp"
|
||||||
"src/Math/Vector3.cpp"
|
"src/Math/Vector3.cpp"
|
||||||
@@ -50,6 +51,7 @@ file(GLOB_RECURSE RESOURCE_FILES
|
|||||||
"${RESOURCES_SOURCE_DIR}/*.png"
|
"${RESOURCES_SOURCE_DIR}/*.png"
|
||||||
"${RESOURCES_SOURCE_DIR}/*.obj"
|
"${RESOURCES_SOURCE_DIR}/*.obj"
|
||||||
"${RESOURCES_SOURCE_DIR}/*.fx"
|
"${RESOURCES_SOURCE_DIR}/*.fx"
|
||||||
|
"${RESOURCES_SOURCE_DIR}/*.mtl"
|
||||||
)
|
)
|
||||||
set(RESOURCES_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/resources/")
|
set(RESOURCES_OUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/resources/")
|
||||||
file(MAKE_DIRECTORY ${RESOURCES_OUT_DIR})
|
file(MAKE_DIRECTORY ${RESOURCES_OUT_DIR})
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
SamplerState gSampleState : SampleState;
|
SamplerState gSampleState : SampleState;
|
||||||
|
RasterizerState gRasterizerState : RasState;
|
||||||
|
|
||||||
float4x4 gWorldViewProj : WorldViewProjection;
|
float4x4 gWorldViewProj : WorldViewProjection;
|
||||||
float4x4 gWorldMatrix : WorldMatrix;
|
float4x4 gWorldMatrix : WorldMatrix;
|
||||||
@@ -39,12 +40,12 @@ struct VS_OUTPUT {
|
|||||||
|
|
||||||
//----------------------
|
//----------------------
|
||||||
// Rasterizer state
|
// Rasterizer state
|
||||||
//----------------------
|
// //----------------------
|
||||||
RasterizerState gRasterizerState
|
// RasterizerState gRasterizerState
|
||||||
{
|
// {
|
||||||
CullMode = none;
|
// CullMode = none;
|
||||||
FrontCounterClockwise = false; //default
|
// FrontCounterClockwise = false; //default
|
||||||
};
|
// };
|
||||||
|
|
||||||
|
|
||||||
//Vertex shader
|
//Vertex shader
|
||||||
|
|||||||
141
project/resources/SimpleDiffuse.fx
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
SamplerState gSampleState : SampleState;
|
||||||
|
RasterizerState gRasterizerState : RastState;
|
||||||
|
|
||||||
|
float4x4 gWorldViewProj : WorldViewProjection;
|
||||||
|
float4x4 gWorldMatrix : WorldMatrix;
|
||||||
|
|
||||||
|
texture2D gDiffuseMap : DiffuseMap;
|
||||||
|
texture2D gNormalMap : Normal;
|
||||||
|
texture2D gSpecularMap : Specular;
|
||||||
|
texture2D gGlossMap : Gloss;
|
||||||
|
|
||||||
|
float3 gLightDirection : LightDirection;
|
||||||
|
float3 gLightColor : LightColor;
|
||||||
|
float3 gCameraPosition : CameraPosition;
|
||||||
|
bool gUseNormal : UseNormal;
|
||||||
|
|
||||||
|
|
||||||
|
static const float3 gAmbient = float3(.03f, .03f, .03f);
|
||||||
|
static const float gLightIntensity = 7.f;
|
||||||
|
static const float PI = 3.14159f;
|
||||||
|
static const float gSpecularReflectance = 1.f;
|
||||||
|
static const float gShininess = 25.f;
|
||||||
|
|
||||||
|
//Input output
|
||||||
|
struct VS_INPUT {
|
||||||
|
float3 Position : POSITION;
|
||||||
|
float2 TexCoord : TEXCOORD;
|
||||||
|
float3 Normal : NORMAL;
|
||||||
|
float3 Tangent : TANGENT;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VS_OUTPUT {
|
||||||
|
float4 Position : SV_POSITION;
|
||||||
|
float4 WorldPosition : WORLDPOSITION;
|
||||||
|
float2 TexCoord : TEXCOORD;
|
||||||
|
float3 Normal : NORMAL;
|
||||||
|
float3 Tangent : TANGENT;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------
|
||||||
|
// Rasterizer state
|
||||||
|
//----------------------
|
||||||
|
// RasterizerState gRasterizerState
|
||||||
|
// {
|
||||||
|
// CullMode = none;
|
||||||
|
// FrontCounterClockwise = false; //default
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
//Vertex shader
|
||||||
|
VS_OUTPUT VS(VS_INPUT input){
|
||||||
|
VS_OUTPUT output = (VS_OUTPUT)0;
|
||||||
|
|
||||||
|
output.Position = mul(float4(input.Position, 1.f), gWorldViewProj);
|
||||||
|
output.WorldPosition = mul(float4(input.Position, 1.f), gWorldMatrix);
|
||||||
|
output.TexCoord = input.TexCoord;
|
||||||
|
output.Normal = mul(input.Normal, (float3x3) gWorldMatrix);
|
||||||
|
output.Tangent = mul(input.Tangent, (float3x3) gWorldMatrix);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 Phong(float ks, float exp, float3 l, float3 v, float3 n)
|
||||||
|
{
|
||||||
|
float3 reflected = reflect(l, n);
|
||||||
|
float cosAngle = dot(reflected, v);
|
||||||
|
return ks * pow(max(0.f, cosAngle), exp) * gLightColor;
|
||||||
|
}
|
||||||
|
float3 Lambert(float kd, float3 cd)
|
||||||
|
{
|
||||||
|
return (kd * cd) / PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float3 Shade(VS_OUTPUT input)
|
||||||
|
{
|
||||||
|
// Sample diffuse, specular, and gloss maps
|
||||||
|
float3 diffuseSample = gDiffuseMap.Sample(gSampleState, input.TexCoord).rgb;
|
||||||
|
float3 specularSample = gSpecularMap.Sample(gSampleState, input.TexCoord).rgb;
|
||||||
|
float glossSample = gGlossMap.Sample(gSampleState, input.TexCoord).x;
|
||||||
|
float3 normalSample = gNormalMap.Sample(gSampleState, input.TexCoord).rgb;
|
||||||
|
|
||||||
|
// Compute inversed view and light directions
|
||||||
|
float3 invViewDirection = normalize(gCameraPosition - input.WorldPosition.xyz);
|
||||||
|
float3 invLightDirection = -gLightDirection;
|
||||||
|
|
||||||
|
// Compute tangent space axes if normal mapping is used
|
||||||
|
float3 normal = input.Normal;
|
||||||
|
if (gUseNormal) {
|
||||||
|
float3 binormal = cross(input.Normal, input.Tangent);
|
||||||
|
float3x3 tangentSpaceAxis = float3x3(input.Tangent, binormal, input.Normal);
|
||||||
|
|
||||||
|
// Sample and transform normal map
|
||||||
|
normal = float3(2.f * normalSample.x - 1.f,
|
||||||
|
2.f * normalSample.y - 1.f,
|
||||||
|
2.f * normalSample.z - 1.f);
|
||||||
|
normal = mul(normal, tangentSpaceAxis);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute Lambert diffuse lighting
|
||||||
|
float3 diffuse = Lambert(gLightIntensity, diffuseSample);
|
||||||
|
|
||||||
|
// Compute Phong specular lighting
|
||||||
|
float ks = (specularSample.x + specularSample.y + specularSample.z) / 3.f;
|
||||||
|
float3 specular = Phong(ks, glossSample * gShininess, invLightDirection, invViewDirection, normal);
|
||||||
|
|
||||||
|
// Compute observed area based on the cosine of the light angle
|
||||||
|
float cosAngle = dot(invLightDirection, normal);
|
||||||
|
float3 observedArea = float3(cosAngle, cosAngle, cosAngle);
|
||||||
|
|
||||||
|
// Combine lighting components
|
||||||
|
float3 color = saturate(diffuse * observedArea + specular + gAmbient * cosAngle);
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 PS(VS_OUTPUT input) : SV_TARGET{
|
||||||
|
return gDiffuseMap.Sample(gSampleState, input.TexCoord);
|
||||||
|
}
|
||||||
|
|
||||||
|
DepthStencilState gDepthStencilState
|
||||||
|
{
|
||||||
|
//enable
|
||||||
|
DepthEnable = true;
|
||||||
|
DepthWriteMask = ALL;
|
||||||
|
DepthFunc = LESS;
|
||||||
|
//stencil
|
||||||
|
StencilEnable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
technique11 DefaultTechnique{
|
||||||
|
pass P0 {
|
||||||
|
SetDepthStencilState(gDepthStencilState, 0);
|
||||||
|
SetRasterizerState(gRasterizerState);
|
||||||
|
SetVertexShader( CompileShader( vs_5_0, VS() ) );
|
||||||
|
SetGeometryShader( NULL );
|
||||||
|
SetPixelShader( CompileShader( ps_5_0, PS() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
project/resources/T_BrickWall_C.png
Normal file
|
After Width: | Height: | Size: 635 KiB |
BIN
project/resources/T_Brick_C.png
Normal file
|
After Width: | Height: | Size: 663 KiB |
BIN
project/resources/T_Car_C.png
Normal file
|
After Width: | Height: | Size: 214 KiB |
BIN
project/resources/T_ChainBench_C.png
Normal file
|
After Width: | Height: | Size: 290 KiB |
BIN
project/resources/T_ChainBench_O.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
project/resources/T_ChickenCoopRoof_C.png
Normal file
|
After Width: | Height: | Size: 488 KiB |
BIN
project/resources/T_ChickenWireInside_C.png
Normal file
|
After Width: | Height: | Size: 274 KiB |
BIN
project/resources/T_ChickenWire_C.png
Normal file
|
After Width: | Height: | Size: 278 KiB |
BIN
project/resources/T_ChickenWire_O.png
Normal file
|
After Width: | Height: | Size: 177 KiB |
BIN
project/resources/T_Chicken_C.png
Normal file
|
After Width: | Height: | Size: 229 KiB |
BIN
project/resources/T_Chicken_O.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
project/resources/T_ClothesLine_C.png
Normal file
|
After Width: | Height: | Size: 305 KiB |
BIN
project/resources/T_DirtTrim_C.png
Normal file
|
After Width: | Height: | Size: 551 KiB |
BIN
project/resources/T_Dirt_C.png
Normal file
|
After Width: | Height: | Size: 378 KiB |
BIN
project/resources/T_Flowers_C.png
Normal file
|
After Width: | Height: | Size: 982 KiB |
BIN
project/resources/T_Flowers_wheel_O.png
Normal file
|
After Width: | Height: | Size: 759 KiB |
BIN
project/resources/T_Fountain_C.png
Normal file
|
After Width: | Height: | Size: 124 KiB |
BIN
project/resources/T_GardenFlowers_Grass_C.png
Normal file
|
After Width: | Height: | Size: 340 KiB |
BIN
project/resources/T_GardenFlowers_Grass_O.png
Normal file
|
After Width: | Height: | Size: 368 KiB |
BIN
project/resources/T_GlassPane_C.png
Normal file
|
After Width: | Height: | Size: 332 KiB |
BIN
project/resources/T_GroundGrass_C.png
Normal file
|
After Width: | Height: | Size: 645 KiB |
BIN
project/resources/T_Hay_C.png
Normal file
|
After Width: | Height: | Size: 793 KiB |
BIN
project/resources/T_HouseTrim_C.png
Normal file
|
After Width: | Height: | Size: 421 KiB |
BIN
project/resources/T_HouseUnique_C.png
Normal file
|
After Width: | Height: | Size: 440 KiB |
BIN
project/resources/T_Leaf_C.png
Normal file
|
After Width: | Height: | Size: 179 KiB |
BIN
project/resources/T_Leaf_O.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
project/resources/T_LocustBark_C.png
Normal file
|
After Width: | Height: | Size: 280 KiB |
BIN
project/resources/T_Path_C.png
Normal file
|
After Width: | Height: | Size: 610 KiB |
BIN
project/resources/T_Rocks_Wall_C.png
Normal file
|
After Width: | Height: | Size: 409 KiB |
BIN
project/resources/T_Roof_C.png
Normal file
|
After Width: | Height: | Size: 502 KiB |
BIN
project/resources/T_Sand_C.png
Normal file
|
After Width: | Height: | Size: 431 KiB |
BIN
project/resources/T_SingleBrick_C.png
Normal file
|
After Width: | Height: | Size: 165 KiB |
BIN
project/resources/T_TableCloth_C.png
Normal file
|
After Width: | Height: | Size: 672 KiB |
BIN
project/resources/T_TableUnique_c.png
Normal file
|
After Width: | Height: | Size: 456 KiB |
BIN
project/resources/T_Vase_C.png
Normal file
|
After Width: | Height: | Size: 329 KiB |
BIN
project/resources/T_Vines_C.png
Normal file
|
After Width: | Height: | Size: 383 KiB |
BIN
project/resources/T_Vines_O.png
Normal file
|
After Width: | Height: | Size: 166 KiB |
BIN
project/resources/T_Water_C.png
Normal file
|
After Width: | Height: | Size: 326 KiB |
BIN
project/resources/T_WoodSeamless_C.png
Normal file
|
After Width: | Height: | Size: 395 KiB |
BIN
project/resources/T_WorldTrimm_C.png
Normal file
|
After Width: | Height: | Size: 243 KiB |
39
project/resources/converter.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
from PIL import Image
|
||||||
|
import os
|
||||||
|
import pprint
|
||||||
|
|
||||||
|
# Set the folder containing images
|
||||||
|
folder_path = 'converted' # Replace with your folder path
|
||||||
|
output_folder = os.path.join(folder_path, 'dingus')
|
||||||
|
|
||||||
|
# Create the 'dingus' folder if it doesn't exist
|
||||||
|
if not os.path.exists(output_folder):
|
||||||
|
os.makedirs(output_folder)
|
||||||
|
|
||||||
|
# Initialize a pretty printer
|
||||||
|
pp = pprint.PrettyPrinter(indent=4)
|
||||||
|
|
||||||
|
# Iterate through all files in the folder
|
||||||
|
for filename in os.listdir(folder_path):
|
||||||
|
if filename.endswith(('.png', '.jpg', '.jpeg', '.bmp', '.tiff')): # Add more formats if needed
|
||||||
|
file_path = os.path.join(folder_path, filename)
|
||||||
|
|
||||||
|
# Open the image
|
||||||
|
try:
|
||||||
|
with Image.open(file_path) as img:
|
||||||
|
# Ensure the image is in 'RGBA' mode (32-bit with 4 channels: R, G, B, A)
|
||||||
|
img = img.convert('RGBA')
|
||||||
|
|
||||||
|
# Create the save path as a PNG in the 'dingus' folder
|
||||||
|
save_path = os.path.join(output_folder, f'{os.path.splitext(filename)[0]}.png')
|
||||||
|
|
||||||
|
# Save the image as PNG
|
||||||
|
img.save(save_path, 'PNG')
|
||||||
|
|
||||||
|
# Pretty-print the successful conversion
|
||||||
|
pp.pprint(f"Successfully converted and saved: {save_path}")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
pp.pprint(f"Error processing {filename}: {e}")
|
||||||
|
|
||||||
|
print("Conversion complete!")
|
||||||
352
project/resources/scene.mtl
Normal file
@@ -0,0 +1,352 @@
|
|||||||
|
# Blender 4.3.2 MTL File: '1GD16E_Verhulst_Bram_Diorama.blend'
|
||||||
|
# www.blender.org
|
||||||
|
|
||||||
|
newmtl M_Baksteen
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_SingleBrick_C.png
|
||||||
|
|
||||||
|
newmtl M_Brick
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_Brick_C.png
|
||||||
|
|
||||||
|
newmtl M_Car
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_Car_C.png
|
||||||
|
|
||||||
|
newmtl M_Chicken
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_Chicken_C.png
|
||||||
|
map_d T_Chicken_O.png
|
||||||
|
|
||||||
|
newmtl M_ChickenRoof
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_ChickenCoopRoof_C.png
|
||||||
|
|
||||||
|
newmtl M_ChickenWireFence
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_ChickenWire_C.png
|
||||||
|
map_d T_ChickenWire_O.png
|
||||||
|
|
||||||
|
newmtl M_Cliff
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_BrickWall_C.png
|
||||||
|
|
||||||
|
newmtl M_ClothesLine
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_ClothesLine_C.png
|
||||||
|
|
||||||
|
newmtl M_Dirt
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_Dirt_C.png
|
||||||
|
|
||||||
|
newmtl M_DirtTrimm
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_DirtTrim_C.png
|
||||||
|
|
||||||
|
newmtl M_Fountain
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_Fountain_C.png
|
||||||
|
|
||||||
|
newmtl M_GardenFlowers
|
||||||
|
Ns 200.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_GardenFlowers_Grass_C.png
|
||||||
|
map_d T_GardenFlowers_Grass_O.png
|
||||||
|
|
||||||
|
newmtl M_GlassPane
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 0.376859
|
||||||
|
illum 1
|
||||||
|
map_Kd T_GlassPane_C.png
|
||||||
|
|
||||||
|
newmtl M_Grass
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_GroundGrass_C.png
|
||||||
|
|
||||||
|
newmtl M_GrassFlowers
|
||||||
|
Ns 1000.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_Flowers_C.png
|
||||||
|
map_d T_Flowers_wheel_O.png
|
||||||
|
|
||||||
|
newmtl M_Hay
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_Hay_C.png
|
||||||
|
|
||||||
|
newmtl M_HouseTrim
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_HouseTrim_C.png
|
||||||
|
|
||||||
|
newmtl M_HouseUnique
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_HouseUnique_C.png
|
||||||
|
|
||||||
|
newmtl M_IndoorChickenWire
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_ChickenWireInside_C.png
|
||||||
|
|
||||||
|
newmtl M_LawnMower_Ladder_pots
|
||||||
|
Ns 200.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Kd 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
|
||||||
|
newmtl M_Path
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_Path_C.png
|
||||||
|
|
||||||
|
newmtl M_PlantPot
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.450000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_Vase_C.png
|
||||||
|
|
||||||
|
newmtl M_Plants
|
||||||
|
Ns 0.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_Flowers_C.png
|
||||||
|
map_d T_Flowers_wheel_O.png
|
||||||
|
|
||||||
|
newmtl M_Rocks_Wall
|
||||||
|
Ns 200.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_Rocks_Wall_C.png
|
||||||
|
|
||||||
|
newmtl M_RoofTiles
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_Roof_C.png
|
||||||
|
|
||||||
|
newmtl M_Sand
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_Sand_C.png
|
||||||
|
|
||||||
|
newmtl M_SwingChair
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_ChainBench_C.png
|
||||||
|
map_d T_ChainBench_O.png
|
||||||
|
|
||||||
|
newmtl M_TableCloth
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_TableCloth_C.png
|
||||||
|
|
||||||
|
newmtl M_TableUnique
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_TableUnique_c.png
|
||||||
|
|
||||||
|
newmtl M_TreeBark
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_LocustBark_C.png
|
||||||
|
|
||||||
|
newmtl M_TreeLeaf
|
||||||
|
Ns 0.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_Leaf_C.png
|
||||||
|
map_d T_Leaf_O.png
|
||||||
|
|
||||||
|
newmtl M_Vines
|
||||||
|
Ns 0.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_Vines_C.png
|
||||||
|
map_d T_Vines_O.png
|
||||||
|
|
||||||
|
newmtl M_Water
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 0.269091
|
||||||
|
illum 1
|
||||||
|
map_Kd T_Water_C.png
|
||||||
|
|
||||||
|
newmtl M_WoodPlanks
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_WoodSeamless_C.png
|
||||||
|
|
||||||
|
newmtl M_WorldTrimm
|
||||||
|
Ns 250.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Ks 0.000000 0.000000 0.000000
|
||||||
|
Ke 0.000000 0.000000 0.000000
|
||||||
|
Ni 1.500000
|
||||||
|
d 1.000000
|
||||||
|
illum 1
|
||||||
|
map_Kd T_WorldTrimm_C.png
|
||||||
@@ -163,7 +163,7 @@ void dae::Camera::Update(const dae::Timer *pTimer) {
|
|||||||
mousePosChange = true;
|
mousePosChange = true;
|
||||||
} else if (mouseState == SDL_BUTTON_X2) //lmb + rmb
|
} else if (mouseState == SDL_BUTTON_X2) //lmb + rmb
|
||||||
{
|
{
|
||||||
origin.y += static_cast<float>(mouseY) / 2;
|
origin.y -= static_cast<float>(mouseY) / 2;
|
||||||
|
|
||||||
mousePosChange = true;
|
mousePosChange = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Math/MathHelpers.h"
|
#include "Math/MathHelpers.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
namespace dae
|
namespace dae
|
||||||
{
|
{
|
||||||
@@ -11,7 +13,7 @@ namespace dae
|
|||||||
|
|
||||||
void MaxToOne()
|
void MaxToOne()
|
||||||
{
|
{
|
||||||
const float maxValue = std::max(r, std::max(g, b));
|
const float maxValue = (r > g) ? ((r > b) ? r : b) : ((g > b) ? g : b);
|
||||||
if (maxValue > 1.f)
|
if (maxValue > 1.f)
|
||||||
*this /= maxValue;
|
*this /= maxValue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ ID3DX11Effect *BaseEffect::LoadEffect(ID3D11Device *devicePtr, const std::wstrin
|
|||||||
std::wstringstream ss;
|
std::wstringstream ss;
|
||||||
for (UINT i{}; i < errorBlobPtr->GetBufferSize(); i++)
|
for (UINT i{}; i < errorBlobPtr->GetBufferSize(); i++)
|
||||||
ss << errorsPtr[i];
|
ss << errorsPtr[i];
|
||||||
|
|
||||||
OutputDebugStringW(ss.str().c_str());
|
OutputDebugStringW(ss.str().c_str());
|
||||||
|
|
||||||
errorBlobPtr->Release();
|
errorBlobPtr->Release();
|
||||||
@@ -66,7 +65,6 @@ ID3DX11Effect *BaseEffect::LoadEffect(ID3D11Device *devicePtr, const std::wstrin
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << "Effect loaded" << std::endl;
|
|
||||||
return effectPtr;
|
return effectPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,3 +91,7 @@ void BaseEffect::SetWorldMatrix(const dae::Matrix& matrix) const {
|
|||||||
void BaseEffect::ToggleNormals() {
|
void BaseEffect::ToggleNormals() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BaseEffect::NextCullMode() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ public:
|
|||||||
|
|
||||||
virtual void NextSamplingState();
|
virtual void NextSamplingState();
|
||||||
|
|
||||||
|
virtual void NextCullMode();
|
||||||
|
|
||||||
virtual void SetCameraPos(const dae::Vector3 &vector3) const;
|
virtual void SetCameraPos(const dae::Vector3 &vector3) const;
|
||||||
|
|
||||||
virtual void SetMaterial(Material *material);
|
virtual void SetMaterial(Material *material);
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ Effect::Effect(ID3D11Device *devicePtr, const std::wstring &filePath)
|
|||||||
if(!m_LightPosVariablePtr->IsValid())
|
if(!m_LightPosVariablePtr->IsValid())
|
||||||
std::wcout << L"gLightDirection Vector is not valid" << std::endl;
|
std::wcout << L"gLightDirection Vector is not valid" << std::endl;
|
||||||
|
|
||||||
m_SamplerVariablePtr = m_EffectPtr->GetVariableByName("gSampler")->AsSampler();
|
m_SamplerVariablePtr = m_EffectPtr->GetVariableByName("gSampleState")->AsSampler();
|
||||||
if(!m_SamplerVariablePtr->IsValid())
|
if(!m_SamplerVariablePtr->IsValid())
|
||||||
std::wcout << L"gSampler Sampler is not valid" << std::endl;
|
std::wcout << L"gSampleState Sampler is not valid" << std::endl;
|
||||||
|
|
||||||
m_MatWorldVariablePtr = m_EffectPtr->GetVariableByName("gWorldMatrix")->AsMatrix();
|
m_MatWorldVariablePtr = m_EffectPtr->GetVariableByName("gWorldMatrix")->AsMatrix();
|
||||||
if(!m_MatWorldVariablePtr->IsValid())
|
if(!m_MatWorldVariablePtr->IsValid())
|
||||||
@@ -46,9 +46,15 @@ Effect::Effect(ID3D11Device *devicePtr, const std::wstring &filePath)
|
|||||||
if(!m_UseNormalMapVariablePtr->IsValid())
|
if(!m_UseNormalMapVariablePtr->IsValid())
|
||||||
std::wcout << L"gUseNormalMap Scalar is not valid" << std::endl;
|
std::wcout << L"gUseNormalMap Scalar is not valid" << std::endl;
|
||||||
|
|
||||||
|
m_RasterizerVariablePtr = m_EffectPtr->GetVariableByName("gRasterizerState")->AsRasterizer();
|
||||||
|
if(!m_RasterizerVariablePtr->IsValid())
|
||||||
|
std::wcout << L"gRasterizerState Rasterizer is not valid" << std::endl;
|
||||||
|
|
||||||
m_UseNormalMapVariablePtr->SetBool(m_UseNormalMap);
|
m_UseNormalMapVariablePtr->SetBool(m_UseNormalMap);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constexpr int vectorSize{ 4 };
|
constexpr int vectorSize{ 4 };
|
||||||
constexpr float lightDirection[vectorSize]{ .577f, -.577f, .577f, 0.f };
|
constexpr float lightDirection[vectorSize]{ .577f, -.577f, .577f, 0.f };
|
||||||
m_LightPosVariablePtr->SetFloatVector(lightDirection);
|
m_LightPosVariablePtr->SetFloatVector(lightDirection);
|
||||||
@@ -57,6 +63,10 @@ Effect::Effect(ID3D11Device *devicePtr, const std::wstring &filePath)
|
|||||||
m_LightColorVariablePtr->SetFloatVector(lightColor);
|
m_LightColorVariablePtr->SetFloatVector(lightColor);
|
||||||
|
|
||||||
this->InitSamplers(devicePtr);
|
this->InitSamplers(devicePtr);
|
||||||
|
this->InitRasterizer(devicePtr);
|
||||||
|
|
||||||
|
m_SamplerVariablePtr->SetSampler(0,m_SamplerStates[static_cast<int>(m_TechniqueType)]);
|
||||||
|
m_RasterizerVariablePtr->SetRasterizerState(0,m_RasterizerStates[static_cast<int>(m_CullMode)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Effect::~Effect() {
|
Effect::~Effect() {
|
||||||
@@ -90,6 +100,9 @@ Effect::~Effect() {
|
|||||||
m_SamplerVariablePtr->Release();
|
m_SamplerVariablePtr->Release();
|
||||||
m_SamplerVariablePtr = nullptr;
|
m_SamplerVariablePtr = nullptr;
|
||||||
|
|
||||||
|
m_RasterizerVariablePtr->Release();
|
||||||
|
m_RasterizerVariablePtr = nullptr;
|
||||||
|
|
||||||
for(auto sampler : m_SamplerStates){
|
for(auto sampler : m_SamplerStates){
|
||||||
sampler->Release();
|
sampler->Release();
|
||||||
}
|
}
|
||||||
@@ -156,3 +169,32 @@ void Effect::InitSamplers(ID3D11Device *devicePtr) {
|
|||||||
|
|
||||||
m_SamplerVariablePtr->SetSampler(0,m_SamplerStates[static_cast<int>(m_TechniqueType)]);
|
m_SamplerVariablePtr->SetSampler(0,m_SamplerStates[static_cast<int>(m_TechniqueType)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Effect::NextCullMode() {
|
||||||
|
m_CullMode = static_cast<CullMode>((static_cast<int>(m_CullMode) + 1) % 3);
|
||||||
|
m_RasterizerVariablePtr->SetRasterizerState(0,m_RasterizerStates[static_cast<int>(m_CullMode)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Effect::InitRasterizer(ID3D11Device *devicePtr) {
|
||||||
|
D3D11_RASTERIZER_DESC rasterDesc = {};
|
||||||
|
rasterDesc.FillMode = D3D11_FILL_SOLID; // Solid fill
|
||||||
|
rasterDesc.FrontCounterClockwise = FALSE;
|
||||||
|
rasterDesc.DepthBias = D3D11_DEFAULT_DEPTH_BIAS;
|
||||||
|
rasterDesc.SlopeScaledDepthBias = D3D11_DEFAULT_SLOPE_SCALED_DEPTH_BIAS;
|
||||||
|
rasterDesc.DepthClipEnable = TRUE;
|
||||||
|
rasterDesc.ScissorEnable = FALSE;
|
||||||
|
rasterDesc.MultisampleEnable = FALSE;
|
||||||
|
rasterDesc.AntialiasedLineEnable = FALSE;
|
||||||
|
|
||||||
|
rasterDesc.CullMode = D3D11_CULL_BACK; // Cull back faces
|
||||||
|
|
||||||
|
devicePtr->CreateRasterizerState(&rasterDesc, &m_RasterizerStates[static_cast<int>(CullMode::Back)]);
|
||||||
|
|
||||||
|
rasterDesc.CullMode = D3D11_CULL_FRONT;
|
||||||
|
|
||||||
|
devicePtr->CreateRasterizerState(&rasterDesc, &m_RasterizerStates[static_cast<int>(CullMode::Front)]);
|
||||||
|
|
||||||
|
rasterDesc.CullMode = D3D11_CULL_NONE;
|
||||||
|
|
||||||
|
devicePtr->CreateRasterizerState(&rasterDesc, &m_RasterizerStates[static_cast<int>(CullMode::None)]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ enum class TechniqueType {
|
|||||||
Anisotropic = 2
|
Anisotropic = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class CullMode {
|
||||||
|
None = 0,
|
||||||
|
Front = 1,
|
||||||
|
Back = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Effect: public BaseEffect {
|
class Effect: public BaseEffect {
|
||||||
public:
|
public:
|
||||||
@@ -20,15 +26,18 @@ public:
|
|||||||
|
|
||||||
void SetCameraPos(const dae::Vector3 &pos) const override;
|
void SetCameraPos(const dae::Vector3 &pos) const override;
|
||||||
|
|
||||||
void SetMaterial(Material *material);
|
void SetMaterial(Material *material) override;
|
||||||
|
|
||||||
void ToggleNormals() override;
|
void ToggleNormals() override;
|
||||||
|
|
||||||
void NextSamplingState() override;
|
void NextSamplingState() override;
|
||||||
|
|
||||||
|
void NextCullMode() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void InitSamplers(ID3D11Device* devicePtr);
|
void InitSamplers(ID3D11Device* devicePtr);
|
||||||
|
void InitRasterizer(ID3D11Device* devicePtr);
|
||||||
|
|
||||||
ID3DX11EffectMatrixVariable *m_MatWorldVariablePtr{};
|
ID3DX11EffectMatrixVariable *m_MatWorldVariablePtr{};
|
||||||
|
|
||||||
@@ -45,9 +54,14 @@ private:
|
|||||||
|
|
||||||
ID3DX11EffectSamplerVariable *m_SamplerVariablePtr{};
|
ID3DX11EffectSamplerVariable *m_SamplerVariablePtr{};
|
||||||
|
|
||||||
|
ID3DX11EffectRasterizerVariable* m_RasterizerVariablePtr{};
|
||||||
|
|
||||||
TechniqueType m_TechniqueType{TechniqueType::Linear};
|
TechniqueType m_TechniqueType{TechniqueType::Linear};
|
||||||
|
|
||||||
std::array<ID3D11SamplerState*, 3> m_SamplerStates{};
|
std::array<ID3D11SamplerState*, 3> m_SamplerStates{};
|
||||||
|
std::array<ID3D11RasterizerState*, 3> m_RasterizerStates{};
|
||||||
|
|
||||||
|
CullMode m_CullMode{ CullMode::Back };
|
||||||
|
|
||||||
bool m_UseNormalMap{true};
|
bool m_UseNormalMap{true};
|
||||||
};
|
};
|
||||||
|
|||||||
72
project/src/HitTest.cpp
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#include "HitTest.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float CrossZ(const Vector3& p0, const Vector3& p1, const Vector3& point)
|
||||||
|
{
|
||||||
|
return (p1.x - p0.x) * (point.y - p0.y)
|
||||||
|
- (p1.y - p0.y) * (point.x - p0.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<Sample> TriangleHitTest(const Vector3& fragPos, const VertexOut& v0, const VertexOut& v1, const VertexOut& v2)
|
||||||
|
{
|
||||||
|
Vector3 weights;
|
||||||
|
|
||||||
|
weights.x = CrossZ(v2.position, v1.position, fragPos);
|
||||||
|
if ( weights.x > 0 )
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
weights.y = CrossZ(v0.position, v2.position, fragPos);
|
||||||
|
if ( weights.y > 0 )
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
weights.z = CrossZ(v1.position, v0.position, fragPos);
|
||||||
|
if ( weights.z > 0 )
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
const float totalWeight{ weights.x + weights.y + weights.z };
|
||||||
|
|
||||||
|
const float invTotalWeight{ 1.0f / totalWeight };
|
||||||
|
const Vector3 normWeights{
|
||||||
|
weights.x * invTotalWeight,
|
||||||
|
weights.y * invTotalWeight,
|
||||||
|
weights.z * invTotalWeight
|
||||||
|
};
|
||||||
|
|
||||||
|
const float depth =
|
||||||
|
1 / (normWeights.x / v0.position.w +
|
||||||
|
normWeights.y / v1.position.w +
|
||||||
|
normWeights.z / v2.position.w);
|
||||||
|
|
||||||
|
const Vector2 uv =
|
||||||
|
v0.uv * depth * normWeights.x / v0.position.w +
|
||||||
|
v1.uv * depth * normWeights.y / v1.position.w +
|
||||||
|
v2.uv * depth * normWeights.z / v2.position.w;
|
||||||
|
|
||||||
|
const float interpolatedDepth = 1 / (normWeights.x / v0.position.w + normWeights.y / v1.position.w + normWeights.z / v2.position.w);
|
||||||
|
|
||||||
|
auto interpolate =
|
||||||
|
[&]<typename Type>(const Type& val0, const Type& val1, const Type& val2) -> Type
|
||||||
|
{
|
||||||
|
return (val0 / v0.position.w * normWeights.x +
|
||||||
|
val1 / v1.position.w * normWeights.y +
|
||||||
|
val2 / v2.position.w * normWeights.z) * interpolatedDepth;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//Invert the normal
|
||||||
|
const Vector3 normal = interpolate(v0.normal, v1.normal, v2.normal).Normalized();
|
||||||
|
const Vector3 tangent = interpolate(v0.tangent, v1.tangent, v2.tangent).Normalized();
|
||||||
|
const Vector3 viewDir = interpolate(v0.viewDir, v1.viewDir, v2.viewDir).Normalized();
|
||||||
|
|
||||||
|
return Sample{
|
||||||
|
.uv = uv,
|
||||||
|
.normal = normal,
|
||||||
|
.tangent = tangent,
|
||||||
|
.viewDirection = viewDir,
|
||||||
|
.depth = depth,
|
||||||
|
.weight = normWeights,
|
||||||
|
.mesh = v0.mesh
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
28
project/src/HitTest.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef GP1_DIRECTX_HITTEST_H
|
||||||
|
#define GP1_DIRECTX_HITTEST_H
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <optional>
|
||||||
|
#include "ColorRGB.h"
|
||||||
|
#include "Math/Vector3.h"
|
||||||
|
#include "Math/Vector2.h"
|
||||||
|
#include "Mesh.h"
|
||||||
|
|
||||||
|
using namespace dae;
|
||||||
|
|
||||||
|
|
||||||
|
struct Sample
|
||||||
|
{
|
||||||
|
Vector2 uv{};
|
||||||
|
Vector3 normal{};
|
||||||
|
Vector3 tangent{};
|
||||||
|
Vector3 viewDirection{};
|
||||||
|
float depth{};
|
||||||
|
Vector3 weight{};
|
||||||
|
Mesh* mesh{};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
std::optional<Sample> TriangleHitTest(const Vector3& fragPos, const VertexOut& v0, const VertexOut& v1, const VertexOut& v2);
|
||||||
|
|
||||||
|
#endif //GP1_DIRECTX_HITTEST_H
|
||||||
@@ -164,5 +164,10 @@ namespace dae {
|
|||||||
if (index == 1) return y;
|
if (index == 1) return y;
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Vector3::operator==(const Vector3 &v) const {
|
||||||
|
return (x - v.x) < FLT_EPSILON && (y - v.y) < FLT_EPSILON && (z - v.z) < FLT_EPSILON;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ namespace dae
|
|||||||
Vector3& operator*=(float scale);
|
Vector3& operator*=(float scale);
|
||||||
float& operator[](int index);
|
float& operator[](int index);
|
||||||
float operator[](int index) const;
|
float operator[](int index) const;
|
||||||
|
bool operator==(const Vector3& v) const;
|
||||||
|
|
||||||
|
|
||||||
static const Vector3 UnitX;
|
static const Vector3 UnitX;
|
||||||
static const Vector3 UnitY;
|
static const Vector3 UnitY;
|
||||||
|
|||||||
@@ -98,5 +98,14 @@ namespace dae
|
|||||||
if (index == 2)return z;
|
if (index == 2)return z;
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Vector4::operator==(const Vector4 &v) const {
|
||||||
|
return
|
||||||
|
std::abs(x - v.x) <= FLT_EPSILON &&
|
||||||
|
std::abs(y - v.y) <= FLT_EPSILON &&
|
||||||
|
std::abs(z - v.z) <= FLT_EPSILON &&
|
||||||
|
std::abs(w - v.w) <= FLT_EPSILON;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
}
|
}
|
||||||
@@ -32,5 +32,6 @@ namespace dae
|
|||||||
Vector4& operator+=(const Vector4& v);
|
Vector4& operator+=(const Vector4& v);
|
||||||
float& operator[](int index);
|
float& operator[](int index);
|
||||||
float operator[](int index) const;
|
float operator[](int index) const;
|
||||||
|
bool operator==(const Vector4& v) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -136,3 +136,12 @@ void Mesh::SetWorldMatrix(const Matrix &matrix) {
|
|||||||
void Mesh::ToggleNormals() {
|
void Mesh::ToggleNormals() {
|
||||||
m_EffectPtr->ToggleNormals();
|
m_EffectPtr->ToggleNormals();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mesh::SetMaterial(Material *pMaterial) {
|
||||||
|
m_Material.reset(pMaterial);
|
||||||
|
m_EffectPtr->SetMaterial(pMaterial);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::CycleCullMode() {
|
||||||
|
m_EffectPtr->NextCullMode();
|
||||||
|
}
|
||||||
@@ -13,6 +13,11 @@ using namespace dae;
|
|||||||
struct VertexIn;
|
struct VertexIn;
|
||||||
struct VertexOut;
|
struct VertexOut;
|
||||||
|
|
||||||
|
enum class PrimitiveTopology {
|
||||||
|
TriangleList,
|
||||||
|
TriangleStrip
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -33,8 +38,21 @@ public:
|
|||||||
|
|
||||||
void NextSamplingState();
|
void NextSamplingState();
|
||||||
|
|
||||||
|
Material* GetMaterial() const { return m_Material.get(); }
|
||||||
|
|
||||||
void SetWorldMatrix(const Matrix &matrix);
|
void SetWorldMatrix(const Matrix &matrix);
|
||||||
|
|
||||||
|
std::vector<VertexIn>& GetVertices() { return m_VerticesIn; }
|
||||||
|
std::vector<Uint32>& GetIndices() { return m_Indices; }
|
||||||
|
PrimitiveTopology GetPrimitiveTopology() const { return m_PrimitiveTopology; }
|
||||||
|
|
||||||
|
void SetMaterial(Material *pMaterial);
|
||||||
|
|
||||||
|
void CycleCullMode();
|
||||||
|
|
||||||
|
void SetShouldRender(bool shouldRender) { m_ShouldRender = shouldRender; }
|
||||||
|
bool GetShouldRender() const { return m_ShouldRender; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BaseEffect *m_EffectPtr;
|
BaseEffect *m_EffectPtr;
|
||||||
|
|
||||||
@@ -49,6 +67,10 @@ private:
|
|||||||
UINT m_IndicesCount;
|
UINT m_IndicesCount;
|
||||||
|
|
||||||
std::shared_ptr<Material> m_Material{};
|
std::shared_ptr<Material> m_Material{};
|
||||||
|
|
||||||
|
PrimitiveTopology m_PrimitiveTopology{PrimitiveTopology::TriangleList};
|
||||||
|
|
||||||
|
bool m_ShouldRender{ true };
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexIn {
|
struct VertexIn {
|
||||||
@@ -65,5 +87,7 @@ struct VertexOut {
|
|||||||
Vector3 normal{};
|
Vector3 normal{};
|
||||||
Vector3 tangent{};
|
Vector3 tangent{};
|
||||||
Vector3 viewDir{};
|
Vector3 viewDir{};
|
||||||
|
Mesh* mesh{};
|
||||||
|
bool valid{ true };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
#include "Effects/Effect.h"
|
#include "Effects/Effect.h"
|
||||||
#include "Effects/FireEffect.h"
|
#include "Effects/FireEffect.h"
|
||||||
|
#include "HitTest.h"
|
||||||
|
|
||||||
namespace dae {
|
namespace dae {
|
||||||
|
|
||||||
@@ -63,6 +64,23 @@ namespace dae {
|
|||||||
FireEffect* fireEffect = new FireEffect(m_DevicePtr, L"resources/Fire.fx");
|
FireEffect* fireEffect = new FireEffect(m_DevicePtr, L"resources/Fire.fx");
|
||||||
m_meshes.push_back(new Mesh(m_DevicePtr, vertices, indices, FireMaterial, fireEffect));
|
m_meshes.push_back(new Mesh(m_DevicePtr, vertices, indices, FireMaterial, fireEffect));
|
||||||
|
|
||||||
|
m_pFireMesh = m_meshes.back();
|
||||||
|
|
||||||
|
//
|
||||||
|
// std::vector<std::unique_ptr<Utils::MaterialMesh>> materialMeshes;
|
||||||
|
// Utils::LoadObjWithMaterials("resources/scene.obj", materialMeshes, true, m_DevicePtr);
|
||||||
|
// for (const auto &mesh: materialMeshes) {
|
||||||
|
// if(mesh->vertices.size() > 0) {
|
||||||
|
// Effect *effect = new Effect(m_DevicePtr, L"resources/SimpleDiffuse.fx");
|
||||||
|
// std::shared_ptr<Material> material = std::make_shared<Material>();
|
||||||
|
// material->diffuseTexturePtr = Texture::LoadFromFile("./resources/" + mesh->diffuse_texture, m_DevicePtr);
|
||||||
|
// m_meshes.push_back(new Mesh(m_DevicePtr, mesh->vertices, mesh->indices, material, effect));
|
||||||
|
// Matrix worldMatrix = m_meshes.back()->GetWorldMatrix();
|
||||||
|
// worldMatrix *= Matrix::CreateScale(2.f, 2.f, 2.f);
|
||||||
|
// m_meshes.back()->SetWorldMatrix(worldMatrix);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
float aspectRatio = static_cast<float>(m_Width) / static_cast<float>(m_Height);
|
float aspectRatio = static_cast<float>(m_Width) / static_cast<float>(m_Height);
|
||||||
m_Camera = Camera({.0f, 5.0f, -64.f}, 45.f);
|
m_Camera = Camera({.0f, 5.0f, -64.f}, 45.f);
|
||||||
@@ -90,6 +108,12 @@ namespace dae {
|
|||||||
delete mesh;
|
delete mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//SDL
|
||||||
|
|
||||||
|
SDL_FreeSurface(m_pBackBuffer);
|
||||||
|
SDL_FreeSurface(m_pFrontBuffer);
|
||||||
|
|
||||||
|
delete[] m_pDepthBufferPixels;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,42 +132,191 @@ namespace dae {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Render() const {
|
void Renderer::Render() {
|
||||||
if (!m_IsInitialized)
|
if (!m_IsInitialized)
|
||||||
return;
|
return;
|
||||||
if (m_backendType == Backendtype::DirectX) {
|
if (m_backendType == Backendtype::DirectX) {
|
||||||
|
this->RenderDirectX();
|
||||||
|
} else {
|
||||||
|
this->RenderSDL();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::RenderDirectX() const {
|
||||||
//Clear back buffer
|
//Clear back buffer
|
||||||
|
if(m_UniformClearColor){
|
||||||
|
const float clearColor[] = {static_cast<float>(r) / 255.f, static_cast<float>(g) / 255.f, static_cast<float>(b) / 255.f, 1.f};
|
||||||
|
m_DeviceContextPtr->ClearRenderTargetView(m_RenderTargetViewPtr, clearColor);
|
||||||
|
} else {
|
||||||
const float clearColor[] = {1.f / 255.f, 0.f / 255.f, 76.f / 255.f, 1.f};
|
const float clearColor[] = {1.f / 255.f, 0.f / 255.f, 76.f / 255.f, 1.f};
|
||||||
m_DeviceContextPtr->ClearRenderTargetView(m_RenderTargetViewPtr, clearColor);
|
m_DeviceContextPtr->ClearRenderTargetView(m_RenderTargetViewPtr, clearColor);
|
||||||
|
}
|
||||||
|
|
||||||
m_DeviceContextPtr->ClearDepthStencilView(m_DepthStencilViewPtr, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
m_DeviceContextPtr->ClearDepthStencilView(m_DepthStencilViewPtr, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
||||||
|
|
||||||
Matrix viewProjMatrix = m_Camera.GetViewProjectionMatrix();
|
Matrix viewProjMatrix = m_Camera.GetViewProjectionMatrix();
|
||||||
for (auto mesh: m_meshes) {
|
for (auto mesh: m_meshes) {
|
||||||
|
if(mesh->GetShouldRender()){
|
||||||
Matrix modelMatrix = mesh->GetWorldMatrix();
|
Matrix modelMatrix = mesh->GetWorldMatrix();
|
||||||
Matrix worldViewProjMatrix = modelMatrix * viewProjMatrix;
|
Matrix worldViewProjMatrix = modelMatrix * viewProjMatrix;
|
||||||
|
|
||||||
mesh->Render(m_DeviceContextPtr, worldViewProjMatrix);
|
mesh->Render(m_DeviceContextPtr, worldViewProjMatrix);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Present
|
//Present
|
||||||
m_SwapChainPtr->Present(0, 0);
|
m_SwapChainPtr->Present(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::RenderSDL() {
|
||||||
|
SDL_FillRect(m_pBackBuffer, nullptr, m_ClearColor);
|
||||||
|
SDL_LockSurface(m_pBackBuffer);
|
||||||
|
std::fill_n(m_pDepthBufferPixels, m_Width * m_Height, std::numeric_limits<float>::max());
|
||||||
|
|
||||||
|
SDL_FillRect(m_pBackBuffer, nullptr, m_ClearColor);
|
||||||
|
|
||||||
|
ColorRGB finalColor{};
|
||||||
|
constexpr int numVerticies = 3;
|
||||||
|
|
||||||
|
m_VerticiesScreenSpace.clear();
|
||||||
|
|
||||||
|
|
||||||
|
for (auto* currentMesh: m_meshes) {
|
||||||
|
|
||||||
|
if(!currentMesh->GetShouldRender()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Matrix worldViewProjectionMatrix{ currentMesh->GetWorldMatrix() * m_Camera.GetViewProjectionMatrix() };
|
||||||
|
VertexTransformationFunction(worldViewProjectionMatrix, currentMesh, currentMesh->GetVertices(), m_VerticiesScreenSpace);
|
||||||
|
|
||||||
|
int numTriangles{};
|
||||||
|
|
||||||
|
switch (currentMesh->GetPrimitiveTopology()) {
|
||||||
|
case PrimitiveTopology::TriangleList:
|
||||||
|
numTriangles = static_cast<int>(currentMesh->GetIndices().size()) / numVerticies;
|
||||||
|
break;
|
||||||
|
case PrimitiveTopology::TriangleStrip:
|
||||||
|
numTriangles = static_cast<int>(currentMesh->GetIndices().size()) - 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (int triangleIndex{}; triangleIndex < numTriangles; ++triangleIndex) {
|
||||||
|
|
||||||
|
VertexOut vertex0, vertex1, vertex2;
|
||||||
|
|
||||||
|
switch (currentMesh->GetPrimitiveTopology()) {
|
||||||
|
case PrimitiveTopology::TriangleList:
|
||||||
|
vertex0 = m_VerticiesScreenSpace[currentMesh->GetIndices()[triangleIndex * numVerticies + 0]];
|
||||||
|
vertex1 = m_VerticiesScreenSpace[currentMesh->GetIndices()[triangleIndex * numVerticies + 1]];
|
||||||
|
vertex2 = m_VerticiesScreenSpace[currentMesh->GetIndices()[triangleIndex * numVerticies + 2]];
|
||||||
|
break;
|
||||||
|
case PrimitiveTopology::TriangleStrip:
|
||||||
|
vertex0 = m_VerticiesScreenSpace[currentMesh->GetIndices()[triangleIndex + 0]];
|
||||||
|
vertex1 = m_VerticiesScreenSpace[currentMesh->GetIndices()[triangleIndex + 1]];
|
||||||
|
vertex2 = m_VerticiesScreenSpace[currentMesh->GetIndices()[triangleIndex + 2]];
|
||||||
|
|
||||||
|
if (triangleIndex % 2 == 1) {
|
||||||
|
std::swap(vertex1, vertex2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vertex0.position == vertex1.position ||
|
||||||
|
vertex0.position == vertex2.position ||
|
||||||
|
vertex1.position == vertex2.position) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!vertex0.valid and !vertex1.valid and !vertex2.valid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const float minX{std::min(vertex0.position.x, std::min(vertex1.position.x, vertex2.position.x))};
|
||||||
|
const float minY{std::min(vertex0.position.y, std::min(vertex1.position.y, vertex2.position.y))};
|
||||||
|
|
||||||
|
const float maxX{std::max(vertex0.position.x, std::max(vertex1.position.x, vertex2.position.x))};
|
||||||
|
const float maxY{std::max(vertex0.position.y, std::max(vertex1.position.y, vertex2.position.y))};
|
||||||
|
|
||||||
|
|
||||||
|
const Vector3 side1{vertex1.position - vertex0.position};
|
||||||
|
const Vector3 side2{vertex2.position - vertex0.position};
|
||||||
|
|
||||||
|
const float totalArea{Vector3::Cross(side1, side2).z};
|
||||||
|
|
||||||
|
const int startX = std::max(0, static_cast<int>(minX)) - 1;
|
||||||
|
const int endX = std::min(m_Width - 1, static_cast<int>(maxX)) + 1;
|
||||||
|
|
||||||
|
const int startY = std::max(0, static_cast<int>(minY)) - 1;
|
||||||
|
const int endY = std::min(m_Height - 1, static_cast<int>(maxY)) + 1;
|
||||||
|
|
||||||
|
for (int px{startX}; px < endX; ++px) {
|
||||||
|
for (int py{startY}; py < endY; ++py) {
|
||||||
|
|
||||||
|
if(m_isHitbox){
|
||||||
|
//Hitboxes
|
||||||
|
m_pBackBufferPixels[px + (py * m_Width)] = SDL_MapRGB(m_pBackBuffer->format,
|
||||||
|
static_cast<uint8_t>(255),
|
||||||
|
static_cast<uint8_t>(255),
|
||||||
|
static_cast<uint8_t>(255));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (px < 0 || px >= m_Width || py < 0 || py >= m_Height) {
|
||||||
|
//TEMP fix for out of bounds
|
||||||
|
//This is to remove triangles having an incorrect edge on their bounding box
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 P{static_cast<float>(px) + 0.5f, static_cast<float>(py) + 0.5f, 1.f};
|
||||||
|
|
||||||
|
auto sample{ TriangleHitTest(P, vertex0, vertex1, vertex2) };
|
||||||
|
|
||||||
|
if (!sample.has_value()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vector3 fragPos{ static_cast<float>(px) + 0.5f, static_cast<float>(py) + 0.5f, 1.f };
|
||||||
|
|
||||||
|
int depthBufferIndex{ px + (py * m_Width) };
|
||||||
|
|
||||||
|
float min{.985f};
|
||||||
|
float max{1.f};
|
||||||
|
float depthBuffer{(sample.value().depth - min) * (max - min)};
|
||||||
|
float currentDepth = sample.value().depth;
|
||||||
|
|
||||||
|
if (m_pDepthBufferPixels[depthBufferIndex] > currentDepth) {
|
||||||
|
m_pDepthBufferPixels[depthBufferIndex] = currentDepth;
|
||||||
|
|
||||||
|
if (m_isDepthBuffer) {
|
||||||
|
finalColor = ColorRGB{depthBuffer, depthBuffer, depthBuffer};
|
||||||
} else {
|
} else {
|
||||||
SDL_FillRect(m_pBackBuffer, nullptr, Uint32(255 << 24) + Uint32(100 << 16) + Uint32(100 << 8) + Uint32(100));
|
finalColor = ShadePixel(sample.value());
|
||||||
|
}
|
||||||
|
|
||||||
//Lock BackBuffer
|
finalColor.MaxToOne();
|
||||||
for (int x = 0; x < 100; ++x) {
|
|
||||||
for (int y = 0; y < 100; ++y) {
|
m_pBackBufferPixels[px + (py * m_Width)] = SDL_MapRGB(m_pBackBuffer->format,
|
||||||
m_pBackBufferPixels[(x + 100) + (y + 150) * m_Width] = SDL_MapRGB(m_pBackBuffer->format, 255, 0, 0);
|
static_cast<uint8_t>(finalColor.r * 255),
|
||||||
|
static_cast<uint8_t>(finalColor.g * 255),
|
||||||
|
static_cast<uint8_t>(finalColor.b * 255));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_BlitSurface(m_pBackBuffer, nullptr, m_pFrontBuffer, nullptr);
|
SDL_UnlockSurface(m_pBackBuffer);
|
||||||
|
SDL_BlitSurface(m_pBackBuffer,nullptr, m_pFrontBuffer, nullptr);
|
||||||
SDL_UpdateWindowSurface(m_pWindow);
|
SDL_UpdateWindowSurface(m_pWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT Renderer::InitializeDirectX() {
|
HRESULT Renderer::InitializeDirectX() {
|
||||||
//1. Create device & deviceContext
|
//1. Create device & deviceContext
|
||||||
//=====
|
//=====
|
||||||
@@ -259,10 +432,163 @@ namespace dae {
|
|||||||
m_pBackBuffer = SDL_CreateRGBSurface(0, m_Width, m_Height, 32, 0, 0, 0, 0);
|
m_pBackBuffer = SDL_CreateRGBSurface(0, m_Width, m_Height, 32, 0, 0, 0, 0);
|
||||||
m_pBackBufferPixels = (uint32_t *) m_pBackBuffer->pixels;
|
m_pBackBufferPixels = (uint32_t *) m_pBackBuffer->pixels;
|
||||||
|
|
||||||
// m_pDepthBufferPixels = new float[m_Width * m_Height];
|
m_pDepthBufferPixels = new float[m_Width * m_Height];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Renderer::VertexTransformationFunction(const Matrix &WorldViewProjectionMatrix, Mesh* mesh,
|
||||||
|
std::vector<VertexIn> &vertices_in, std::vector<VertexOut> &vertices_out) const {
|
||||||
|
for (const VertexIn& vert : vertices_in)
|
||||||
|
{
|
||||||
|
VertexOut vertex_out{};
|
||||||
|
|
||||||
|
Vector4 vertPos{ WorldViewProjectionMatrix.TransformPoint({vert.position, 1}) };
|
||||||
|
|
||||||
|
const Vector3 normal{ mesh->GetWorldMatrix().TransformVector(vert.normal) };
|
||||||
|
const Vector3 tangent{ mesh->GetWorldMatrix().TransformVector(vert.tangent) };
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
vertPos.x /= vertPos.w;
|
||||||
|
vertPos.y /= vertPos.w;
|
||||||
|
vertPos.z /= vertPos.w;
|
||||||
|
|
||||||
|
bool isValid{ true };
|
||||||
|
|
||||||
|
//Check if the vertex is inside the screen
|
||||||
|
if (vertPos.x < -1.f || vertPos.x > 1.f ||
|
||||||
|
vertPos.y < -1.f || vertPos.y > 1.f ||
|
||||||
|
vertPos.z < 0.f || vertPos.z > 1.f)
|
||||||
|
isValid = false;
|
||||||
|
|
||||||
|
vertPos.x = ((vertPos.x + 1.f) / 2.f) * static_cast<float>(m_Width);
|
||||||
|
vertPos.y = ((1.f - vertPos.y) / 2.f) * static_cast<float>(m_Height);
|
||||||
|
|
||||||
|
vertex_out.position = vertPos;
|
||||||
|
vertex_out.uv = vert.uv;
|
||||||
|
vertex_out.normal = normal;
|
||||||
|
vertex_out.tangent = tangent;
|
||||||
|
vertex_out.mesh = mesh;
|
||||||
|
// vertex_out.viewDir = WorldViewProjectionMatrix.TransformVector(vert.viewDir);
|
||||||
|
vertex_out.valid = isValid;
|
||||||
|
|
||||||
|
vertices_out.push_back(vertex_out);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer::ToggleDepthBuffer() {
|
||||||
|
m_isDepthBuffer = !m_isDepthBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGB Renderer::ShadePixel(const Sample &sample) {
|
||||||
|
|
||||||
|
Material* currentMaterial = sample.mesh->GetMaterial();
|
||||||
|
|
||||||
|
if(currentMaterial->normalTexturePtr == nullptr && currentMaterial->specularTexturePtr == nullptr && currentMaterial->glossTexturePtr == nullptr){
|
||||||
|
return currentMaterial->diffuseTexturePtr->Sample(sample.uv);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 lightDirection = { .577f, -.577f, .577f};
|
||||||
|
Vector3 normal = sample.normal.Normalized();
|
||||||
|
constexpr float lightIntensity{ 7.f };
|
||||||
|
|
||||||
|
ColorRGB color{ 1, 1, 1 };
|
||||||
|
constexpr ColorRGB ambient{ .03f, .03f, .03f};
|
||||||
|
|
||||||
|
if(m_useNormals){
|
||||||
|
const ColorRGB normalSample{ sample.mesh->GetMaterial()->normalTexturePtr->Sample(sample.uv) };
|
||||||
|
const Vector4 normalMapSample{
|
||||||
|
2.f * normalSample.r - 1.f,
|
||||||
|
2.f * normalSample.g - 1.f,
|
||||||
|
2.f * normalSample.b - 1.f,
|
||||||
|
0.f
|
||||||
|
};
|
||||||
|
|
||||||
|
const Vector3 biNormal{ Vector3::Cross(normal, sample.tangent) };
|
||||||
|
const Matrix tangentToWorld{
|
||||||
|
Vector4{ sample.tangent, 0.f },
|
||||||
|
Vector4{ biNormal, 0.f },
|
||||||
|
Vector4{ normal, 0.f },
|
||||||
|
Vector4{ 0.f, 0.f, 0.f, 1.f }
|
||||||
|
};
|
||||||
|
normal = tangentToWorld.TransformVector(normalMapSample).Normalized();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const ColorRGB diffuseSample{ currentMaterial->diffuseTexturePtr->Sample(sample.uv) };
|
||||||
|
double invPi = 1.0 / PI;
|
||||||
|
const ColorRGB lambert{ diffuseSample * lightIntensity * invPi };
|
||||||
|
|
||||||
|
//TODO: ask why deviding by PI causses Segmentation fault
|
||||||
|
// const ColorRGB lambert{ diffuseSample * lightIntensity / PI };
|
||||||
|
|
||||||
|
|
||||||
|
float specularReflectance{ 1.f };
|
||||||
|
float shininess{ 25.f };
|
||||||
|
|
||||||
|
specularReflectance *= currentMaterial->glossTexturePtr->Sample(sample.uv).r;
|
||||||
|
shininess *= currentMaterial->specularTexturePtr->Sample(sample.uv).r;
|
||||||
|
|
||||||
|
const float cosAngle = Vector3::Dot(normal, -lightDirection);
|
||||||
|
|
||||||
|
const ColorRGB specular = specularReflectance * powf(cosAngle, shininess) * colors::White;
|
||||||
|
|
||||||
|
if (cosAngle < 0) {
|
||||||
|
return ambient;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(m_ShadeMode){
|
||||||
|
case ShadeMode::ObservedArea:
|
||||||
|
break;
|
||||||
|
case ShadeMode::Diffuse:
|
||||||
|
color = lambert;
|
||||||
|
break;
|
||||||
|
case ShadeMode::Specular:
|
||||||
|
color = specular;
|
||||||
|
break;
|
||||||
|
case ShadeMode::Combined:
|
||||||
|
color = lambert + specular + ambient;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
color *= ColorRGB{ cosAngle, cosAngle, cosAngle };
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::CycleCullMode() {
|
||||||
|
for(auto mesh: m_meshes){
|
||||||
|
mesh->CycleCullMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::ToggleBoundingBox() {
|
||||||
|
m_isHitbox = !m_isHitbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::CycleRenderingMode() {
|
||||||
|
switch (m_ShadeMode) {
|
||||||
|
case ShadeMode::ObservedArea:
|
||||||
|
m_ShadeMode = ShadeMode::Diffuse;
|
||||||
|
std::cout << "Diffuse" << std::endl;
|
||||||
|
break;
|
||||||
|
case ShadeMode::Diffuse:
|
||||||
|
m_ShadeMode = ShadeMode::Specular;
|
||||||
|
std::cout << "Specular" << std::endl;
|
||||||
|
break;
|
||||||
|
case ShadeMode::Specular:
|
||||||
|
m_ShadeMode = ShadeMode::Combined;
|
||||||
|
std::cout << "Combined" << std::endl;
|
||||||
|
break;
|
||||||
|
case ShadeMode::Combined:
|
||||||
|
m_ShadeMode = ShadeMode::ObservedArea;
|
||||||
|
std::cout << "Observed Area" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Renderer::SwitchBackend() {
|
void Renderer::SwitchBackend() {
|
||||||
if (m_backendType == Backendtype::DirectX) {
|
if (m_backendType == Backendtype::DirectX) {
|
||||||
m_backendType = Backendtype::SDL;
|
m_backendType = Backendtype::SDL;
|
||||||
@@ -278,6 +604,7 @@ namespace dae {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::ToggleNormals() {
|
void Renderer::ToggleNormals() {
|
||||||
|
m_useNormals = !m_useNormals;
|
||||||
for(auto mesh: m_meshes){
|
for(auto mesh: m_meshes){
|
||||||
mesh->ToggleNormals();
|
mesh->ToggleNormals();
|
||||||
}
|
}
|
||||||
@@ -290,4 +617,10 @@ namespace dae {
|
|||||||
void Renderer::ToggleUniformClearColor() {
|
void Renderer::ToggleUniformClearColor() {
|
||||||
m_UniformClearColor = !m_UniformClearColor;
|
m_UniformClearColor = !m_UniformClearColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer::ToggleFireFX() {
|
||||||
|
m_pFireMesh->SetShouldRender(!m_pFireMesh->GetShouldRender());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "Mesh.h"
|
#include "Mesh.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
|
#include "HitTest.h"
|
||||||
|
|
||||||
struct SDL_Window;
|
struct SDL_Window;
|
||||||
struct SDL_Surface;
|
struct SDL_Surface;
|
||||||
@@ -11,12 +12,19 @@ enum class Backendtype {
|
|||||||
SDL
|
SDL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ShadeMode{
|
||||||
|
ObservedArea,
|
||||||
|
Diffuse,
|
||||||
|
Specular,
|
||||||
|
Combined
|
||||||
|
};
|
||||||
|
|
||||||
namespace dae
|
namespace dae
|
||||||
{
|
{
|
||||||
class Renderer final
|
class Renderer final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Renderer(SDL_Window* pWindow);
|
explicit Renderer(SDL_Window* pWindow);
|
||||||
~Renderer();
|
~Renderer();
|
||||||
|
|
||||||
Renderer(const Renderer&) = delete;
|
Renderer(const Renderer&) = delete;
|
||||||
@@ -25,7 +33,7 @@ namespace dae
|
|||||||
Renderer& operator=(Renderer&&) noexcept = delete;
|
Renderer& operator=(Renderer&&) noexcept = delete;
|
||||||
|
|
||||||
void Update(const Timer* pTimer);
|
void Update(const Timer* pTimer);
|
||||||
void Render() const;
|
void Render();
|
||||||
|
|
||||||
//Switching Functions
|
//Switching Functions
|
||||||
void NextSamplingState();
|
void NextSamplingState();
|
||||||
@@ -37,31 +45,23 @@ namespace dae
|
|||||||
|
|
||||||
void ToggleUniformClearColor();
|
void ToggleUniformClearColor();
|
||||||
|
|
||||||
|
void ToggleDepthBuffer();
|
||||||
|
|
||||||
|
void CycleCullMode();
|
||||||
|
|
||||||
|
void ToggleBoundingBox();
|
||||||
|
|
||||||
|
void CycleRenderingMode();
|
||||||
|
|
||||||
|
void ToggleFireFX();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Common vars
|
||||||
SDL_Window* m_pWindow{};
|
SDL_Window* m_pWindow{};
|
||||||
|
|
||||||
int m_Width{};
|
int m_Width{};
|
||||||
int m_Height{};
|
int m_Height{};
|
||||||
|
|
||||||
bool m_IsInitialized{ false };
|
|
||||||
|
|
||||||
//DIRECTX
|
|
||||||
HRESULT InitializeDirectX();
|
|
||||||
void InitializeSDLRasterizer();
|
|
||||||
|
|
||||||
ID3D11Device* m_DevicePtr{};
|
|
||||||
ID3D11DeviceContext* m_DeviceContextPtr{};
|
|
||||||
IDXGISwapChain* m_SwapChainPtr{};
|
|
||||||
ID3D11Texture2D* m_DepthStencilBufferPtr{};
|
|
||||||
ID3D11DepthStencilView* m_DepthStencilViewPtr{};
|
|
||||||
ID3D11Resource* m_RenderTargetBufferPtr{};
|
|
||||||
ID3D11RenderTargetView* m_RenderTargetViewPtr{};
|
|
||||||
|
|
||||||
SDL_Surface* m_pFrontBuffer{ nullptr };
|
|
||||||
SDL_Surface* m_pBackBuffer{ nullptr };
|
|
||||||
uint32_t* m_pBackBufferPixels{};
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<Mesh*> m_meshes{};
|
std::vector<Mesh*> m_meshes{};
|
||||||
std::vector<std::shared_ptr<Material>> m_materials{};
|
std::vector<std::shared_ptr<Material>> m_materials{};
|
||||||
|
|
||||||
@@ -73,5 +73,51 @@ namespace dae
|
|||||||
float m_currentRotation{};
|
float m_currentRotation{};
|
||||||
bool m_UniformClearColor{ false };
|
bool m_UniformClearColor{ false };
|
||||||
|
|
||||||
|
|
||||||
|
//DirectX vars
|
||||||
|
|
||||||
|
bool m_IsInitialized{ false };
|
||||||
|
|
||||||
|
HRESULT InitializeDirectX();
|
||||||
|
void RenderDirectX() const;
|
||||||
|
|
||||||
|
//Storing the mesh so i can deactivate it;
|
||||||
|
Mesh* m_pFireMesh{};
|
||||||
|
|
||||||
|
ID3D11Device* m_DevicePtr{};
|
||||||
|
ID3D11DeviceContext* m_DeviceContextPtr{};
|
||||||
|
IDXGISwapChain* m_SwapChainPtr{};
|
||||||
|
ID3D11Texture2D* m_DepthStencilBufferPtr{};
|
||||||
|
ID3D11DepthStencilView* m_DepthStencilViewPtr{};
|
||||||
|
ID3D11Resource* m_RenderTargetBufferPtr{};
|
||||||
|
ID3D11RenderTargetView* m_RenderTargetViewPtr{};
|
||||||
|
|
||||||
|
//SDL vars
|
||||||
|
|
||||||
|
void InitializeSDLRasterizer();
|
||||||
|
void RenderSDL();
|
||||||
|
void VertexTransformationFunction(const Matrix& WorldViewProjectionMatrix, Mesh* mesh, std::vector<VertexIn> &vertices_in, std::vector<VertexOut> &vertices_out) const;
|
||||||
|
ColorRGB ShadePixel(const Sample& sample);
|
||||||
|
|
||||||
|
|
||||||
|
SDL_Surface* m_pFrontBuffer{ nullptr };
|
||||||
|
SDL_Surface* m_pBackBuffer{ nullptr };
|
||||||
|
uint32_t* m_pBackBufferPixels{};
|
||||||
|
|
||||||
|
bool m_useNormals{ true };
|
||||||
|
bool m_isHitbox{ false };
|
||||||
|
ShadeMode m_ShadeMode{ ShadeMode::Combined };
|
||||||
|
bool m_isDepthBuffer{ false };
|
||||||
|
|
||||||
|
|
||||||
|
Uint8 r{100};
|
||||||
|
Uint8 g{100};
|
||||||
|
Uint8 b{100};
|
||||||
|
Uint32 m_ClearColor{ Uint32(255 << 24) + Uint32(r << 16) + Uint32(g << 8) + Uint32(b) };
|
||||||
|
float* m_pDepthBufferPixels{};
|
||||||
|
|
||||||
|
std::vector<VertexOut> m_VerticiesScreenSpace{};
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include <algorithm>
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
|
|
||||||
Texture::~Texture() {
|
Texture::~Texture() {
|
||||||
@@ -11,6 +12,11 @@ Texture *Texture::LoadFromFile(const std::string &path, ID3D11Device *devicePtr)
|
|||||||
std::cerr << "Failed to load texture: " << path << std::endl;
|
std::cerr << "Failed to load texture: " << path << std::endl;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
if (surface->format->BytesPerPixel != 4)
|
||||||
|
{
|
||||||
|
std::cerr << "Texture::LoadFromFile > Texture is not in the right format: " << path << std::endl;
|
||||||
|
// throw std::runtime_error("Texture is not in the right format");
|
||||||
|
}
|
||||||
|
|
||||||
auto *texture = new Texture(surface, devicePtr);
|
auto *texture = new Texture(surface, devicePtr);
|
||||||
|
|
||||||
@@ -46,6 +52,22 @@ Texture::Texture(SDL_Surface *surfacePtr, ID3D11Device *devicePtr) {
|
|||||||
|
|
||||||
hr = devicePtr->CreateShaderResourceView(m_TexturePtr, &SRVDesc, &m_TextureResourceViewPtr);
|
hr = devicePtr->CreateShaderResourceView(m_TexturePtr, &SRVDesc, &m_TextureResourceViewPtr);
|
||||||
|
|
||||||
SDL_FreeSurface(surfacePtr);
|
m_SurfacePtr = surfacePtr;
|
||||||
|
m_pSurfacePixels = static_cast<Uint32 *>(surfacePtr->pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorRGB Texture::Sample(const Vector2 &uv) const {
|
||||||
|
Uint8 red, green, blue;
|
||||||
|
|
||||||
|
Vector2 wrapped = {fmod(uv.x, 1.0f), fmod(uv.y, 1.0f)};
|
||||||
|
|
||||||
|
if (wrapped.x < 0.0f) wrapped.x += 1.0f;
|
||||||
|
if (wrapped.y < 0.0f) wrapped.y += 1.0f;
|
||||||
|
|
||||||
|
SDL_GetRGB(m_pSurfacePixels[
|
||||||
|
static_cast<int>(wrapped.x * static_cast<float>(m_SurfacePtr->w - 1)) +
|
||||||
|
static_cast<int>(wrapped.y * static_cast<float>(m_SurfacePtr->h - 1)) * (m_SurfacePtr->w)
|
||||||
|
], m_SurfacePtr->format, &red, &green, &blue);
|
||||||
|
|
||||||
|
return ColorRGB{static_cast<float>(red) / 255.0f, static_cast<float>(green) / 255.0f, static_cast<float>(blue) / 255.0f};
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,10 @@
|
|||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
#include "SDL_surface.h"
|
#include "SDL_surface.h"
|
||||||
#include "SDL_image.h"
|
#include "SDL_image.h"
|
||||||
|
#include "ColorRGB.h"
|
||||||
|
#include "Math/Vector2.h"
|
||||||
|
|
||||||
|
using namespace dae;
|
||||||
|
|
||||||
class Texture {
|
class Texture {
|
||||||
public:
|
public:
|
||||||
@@ -17,11 +20,16 @@ public:
|
|||||||
|
|
||||||
inline ID3D11ShaderResourceView* GetSrv() const { return m_TextureResourceViewPtr; }
|
inline ID3D11ShaderResourceView* GetSrv() const { return m_TextureResourceViewPtr; }
|
||||||
|
|
||||||
|
ColorRGB Sample(const Vector2& uv) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Texture(SDL_Surface* surfacePtr, ID3D11Device* devicePtr);
|
Texture(SDL_Surface* surfacePtr, ID3D11Device* devicePtr);
|
||||||
|
|
||||||
ID3D11ShaderResourceView* m_TextureResourceViewPtr{};
|
ID3D11ShaderResourceView* m_TextureResourceViewPtr{};
|
||||||
ID3D11Texture2D* m_TexturePtr{};
|
ID3D11Texture2D* m_TexturePtr{};
|
||||||
|
|
||||||
|
SDL_Surface* m_SurfacePtr{ nullptr };
|
||||||
|
uint32_t* m_pSurfacePixels{ nullptr };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -256,5 +256,118 @@ namespace dae {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct MaterialMesh {
|
||||||
|
std::vector<VertexIn> vertices;
|
||||||
|
std::vector<uint32_t> indices;
|
||||||
|
int material_id = -1; // Material ID associated with this mesh
|
||||||
|
std::string diffuse_texture; // Path to the diffuse texture
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static bool LoadObjWithMaterials(const std::string &fileName, std::vector<std::unique_ptr<MaterialMesh>> &meshes,
|
||||||
|
bool flipAxisAndWinding = true, ID3D11Device* device = nullptr) {
|
||||||
|
tinyobj::attrib_t attrib;
|
||||||
|
std::vector<tinyobj::shape_t> shapes;
|
||||||
|
std::vector<tinyobj::material_t> materials;
|
||||||
|
std::string warn, err;
|
||||||
|
|
||||||
|
std::string basepath = "resources/";
|
||||||
|
|
||||||
|
if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, fileName.c_str(), basepath.c_str())) {
|
||||||
|
if (!warn.empty()) {
|
||||||
|
std::cerr << "Warning: " << warn << std::endl;
|
||||||
|
}
|
||||||
|
if (!err.empty()) {
|
||||||
|
std::cerr << "Error: " << err << std::endl;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear and prepare the meshes array
|
||||||
|
meshes.clear();
|
||||||
|
|
||||||
|
// Create Mesh objects for each material
|
||||||
|
meshes.resize(materials.size());
|
||||||
|
for (size_t i = 0; i < materials.size(); ++i) {
|
||||||
|
meshes[i] = std::make_unique<MaterialMesh>();
|
||||||
|
meshes[i]->material_id = static_cast<int>(i);
|
||||||
|
meshes[i]->diffuse_texture = materials[i].diffuse_texname;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default Mesh for faces with no material
|
||||||
|
auto defaultMesh = std::make_unique<MaterialMesh>();
|
||||||
|
defaultMesh->material_id = -1;
|
||||||
|
defaultMesh->diffuse_texture = "";
|
||||||
|
meshes.push_back(std::move(defaultMesh));
|
||||||
|
|
||||||
|
for (const auto &shape : shapes) {
|
||||||
|
size_t index_offset = 0;
|
||||||
|
|
||||||
|
for (size_t f = 0; f < shape.mesh.num_face_vertices.size(); f++) {
|
||||||
|
auto fv = size_t(shape.mesh.num_face_vertices[f]);
|
||||||
|
|
||||||
|
if (fv != 3) {
|
||||||
|
std::cerr << "Error: Only triangular faces are supported." << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int material_id = (f < shape.mesh.material_ids.size()) ? shape.mesh.material_ids[f] : -1;
|
||||||
|
if (material_id < 0 || material_id >= static_cast<int>(materials.size())) {
|
||||||
|
material_id = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* targetMesh = (material_id >= 0 && material_id < static_cast<int>(materials.size()))
|
||||||
|
? meshes[material_id].get()
|
||||||
|
: meshes.back().get(); // Use default mesh
|
||||||
|
|
||||||
|
uint32_t tempIndices[3];
|
||||||
|
VertexIn tempVertices[3];
|
||||||
|
|
||||||
|
for (size_t v = 0; v < fv; v++) {
|
||||||
|
tinyobj::index_t idx = shape.mesh.indices[index_offset + v];
|
||||||
|
|
||||||
|
VertexIn vertex;
|
||||||
|
|
||||||
|
if (idx.vertex_index >= 0) {
|
||||||
|
vertex.position = Vector3(
|
||||||
|
attrib.vertices[3 * idx.vertex_index + 0],
|
||||||
|
attrib.vertices[3 * idx.vertex_index + 1],
|
||||||
|
attrib.vertices[3 * idx.vertex_index + 2]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx.texcoord_index >= 0) {
|
||||||
|
vertex.uv = Vector2(
|
||||||
|
attrib.texcoords[2 * idx.texcoord_index + 0],
|
||||||
|
1.0f - attrib.texcoords[2 * idx.texcoord_index + 1] // Flip V
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx.normal_index >= 0) {
|
||||||
|
vertex.normal = Vector3(
|
||||||
|
attrib.normals[3 * idx.normal_index + 0],
|
||||||
|
attrib.normals[3 * idx.normal_index + 1],
|
||||||
|
attrib.normals[3 * idx.normal_index + 2]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
tempVertices[v] = vertex;
|
||||||
|
tempIndices[v] = static_cast<uint32_t>(targetMesh->vertices.size());
|
||||||
|
targetMesh->vertices.push_back(vertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push indices in the default order
|
||||||
|
targetMesh->indices.push_back(tempIndices[0]);
|
||||||
|
targetMesh->indices.push_back(tempIndices[1]);
|
||||||
|
targetMesh->indices.push_back(tempIndices[2]);
|
||||||
|
|
||||||
|
index_offset += fv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,6 +29,7 @@ int main(int argc, char *args[]) {
|
|||||||
const uint32_t width = 640;
|
const uint32_t width = 640;
|
||||||
const uint32_t height = 480;
|
const uint32_t height = 480;
|
||||||
|
|
||||||
|
|
||||||
SDL_Window *pWindow = SDL_CreateWindow(
|
SDL_Window *pWindow = SDL_CreateWindow(
|
||||||
"DirectX - Bram Verhulst - 2GD11E",
|
"DirectX - Bram Verhulst - 2GD11E",
|
||||||
SDL_WINDOWPOS_UNDEFINED,
|
SDL_WINDOWPOS_UNDEFINED,
|
||||||
@@ -49,6 +50,8 @@ int main(int argc, char *args[]) {
|
|||||||
const auto pTimer = new Timer();
|
const auto pTimer = new Timer();
|
||||||
const auto pRenderer = new Renderer(pWindow);
|
const auto pRenderer = new Renderer(pWindow);
|
||||||
|
|
||||||
|
bool printFPS = false;
|
||||||
|
|
||||||
//Start loop
|
//Start loop
|
||||||
pTimer->Start();
|
pTimer->Start();
|
||||||
float printTimer = 0.f;
|
float printTimer = 0.f;
|
||||||
@@ -73,6 +76,7 @@ int main(int argc, char *args[]) {
|
|||||||
}
|
}
|
||||||
if(scancode == SDL_SCANCODE_F9){
|
if(scancode == SDL_SCANCODE_F9){
|
||||||
// Cycle Cull mode
|
// Cycle Cull mode
|
||||||
|
pRenderer->CycleCullMode();
|
||||||
}
|
}
|
||||||
if(scancode == SDL_SCANCODE_F10){
|
if(scancode == SDL_SCANCODE_F10){
|
||||||
// Toggle Uniform Clear Color
|
// Toggle Uniform Clear Color
|
||||||
@@ -80,11 +84,13 @@ int main(int argc, char *args[]) {
|
|||||||
}
|
}
|
||||||
if(scancode == SDL_SCANCODE_F11){
|
if(scancode == SDL_SCANCODE_F11){
|
||||||
// toggle Print fps
|
// toggle Print fps
|
||||||
|
printFPS = !printFPS;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Hardware
|
//Hardware
|
||||||
if (scancode == SDL_SCANCODE_F3){
|
if (scancode == SDL_SCANCODE_F3){
|
||||||
// Toggle FireFX mesh
|
// Toggle FireFX mesh
|
||||||
|
pRenderer->ToggleFireFX();
|
||||||
}
|
}
|
||||||
if (scancode == SDL_SCANCODE_F4){
|
if (scancode == SDL_SCANCODE_F4){
|
||||||
//Toggle texture sampling states
|
//Toggle texture sampling states
|
||||||
@@ -93,25 +99,21 @@ int main(int argc, char *args[]) {
|
|||||||
//Software
|
//Software
|
||||||
if(scancode == SDL_SCANCODE_F5){
|
if(scancode == SDL_SCANCODE_F5){
|
||||||
//Cycle shading mode
|
//Cycle shading mode
|
||||||
|
pRenderer->CycleRenderingMode();
|
||||||
}
|
}
|
||||||
if(scancode == SDL_SCANCODE_F6){
|
if(scancode == SDL_SCANCODE_F6){
|
||||||
//Toggle normal mapping
|
//Toggle normal mapping
|
||||||
|
pRenderer->ToggleNormals();
|
||||||
}
|
}
|
||||||
if(scancode == SDL_SCANCODE_F7){
|
if(scancode == SDL_SCANCODE_F7){
|
||||||
//Toggle Depth Buffer
|
//Toggle Depth Buffer
|
||||||
|
pRenderer->ToggleDepthBuffer();
|
||||||
}
|
}
|
||||||
if(scancode == SDL_SCANCODE_F8) {
|
if(scancode == SDL_SCANCODE_F8) {
|
||||||
//Toggle BoundingBox
|
//Toggle BoundingBox
|
||||||
|
pRenderer->ToggleBoundingBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.key.keysym.scancode == SDL_SCANCODE_F2) {
|
|
||||||
}
|
|
||||||
if (e.key.keysym.scancode == SDL_SCANCODE_F3) {
|
|
||||||
|
|
||||||
}
|
|
||||||
if (e.key.keysym.scancode == SDL_SCANCODE_F4) {
|
|
||||||
pRenderer->ToggleNormals();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -129,7 +131,7 @@ int main(int argc, char *args[]) {
|
|||||||
//--------- Timer ---------
|
//--------- Timer ---------
|
||||||
pTimer->Update();
|
pTimer->Update();
|
||||||
printTimer += pTimer->GetElapsed();
|
printTimer += pTimer->GetElapsed();
|
||||||
if (printTimer >= 1.f) {
|
if (printTimer >= 1.f && printFPS) {
|
||||||
printTimer = 0.f;
|
printTimer = 0.f;
|
||||||
std::cout << "dFPS: " << pTimer->GetdFPS() << std::endl;
|
std::cout << "dFPS: " << pTimer->GetdFPS() << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||