mirror of
https://github.com/UOH-CS-Level5/551455-graphics-programming-2526-the-repo-Zyb3rWolfi.git
synced 2025-11-29 00:43:08 +00:00
Finished lighting shaders
This commit is contained in:
parent
4de01aa53b
commit
fe63a6d938
@ -6,6 +6,8 @@
|
|||||||
<Path>TheLabs/Textures</Path>
|
<Path>TheLabs/Textures</Path>
|
||||||
</attachedFolders>
|
</attachedFolders>
|
||||||
<explicitIncludes />
|
<explicitIncludes />
|
||||||
<explicitExcludes />
|
<explicitExcludes>
|
||||||
|
<Path>TheLabs/Shapes/Bus.cs</Path>
|
||||||
|
</explicitExcludes>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
29
TheRepo/TheLabs/Lighting.cs
Normal file
29
TheRepo/TheLabs/Lighting.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using LearnOpenTK.Common;
|
||||||
|
using OpenTK.Graphics.OpenGL;
|
||||||
|
using OpenTK.Mathematics;
|
||||||
|
|
||||||
|
namespace TheLabs;
|
||||||
|
|
||||||
|
public struct Lighting
|
||||||
|
{
|
||||||
|
public Vector3 position;
|
||||||
|
public Vector3 ambientColour;
|
||||||
|
public Vector3 diffuseColour;
|
||||||
|
public Vector3 specularColour;
|
||||||
|
|
||||||
|
public Lighting(Vector3 pos, Vector3 ambient, Vector3 diffuse, Vector3 specular)
|
||||||
|
{
|
||||||
|
position = pos;
|
||||||
|
ambientColour = ambient;
|
||||||
|
diffuseColour = diffuse;
|
||||||
|
specularColour = specular;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Apply(Shader shader)
|
||||||
|
{
|
||||||
|
GL.Uniform3(GL.GetUniformLocation(shader.Handle, "uPointLight.position"), ref position);
|
||||||
|
GL.Uniform3(GL.GetUniformLocation(shader.Handle, "uPointLight.ambientColour"), ref ambientColour);
|
||||||
|
GL.Uniform3(GL.GetUniformLocation(shader.Handle, "uPointLight.diffuseColour"), ref diffuseColour);
|
||||||
|
GL.Uniform3(GL.GetUniformLocation(shader.Handle, "uPointLight.specularColour"), ref specularColour);
|
||||||
|
}
|
||||||
|
}
|
||||||
30
TheRepo/TheLabs/Material.cs
Normal file
30
TheRepo/TheLabs/Material.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using LearnOpenTK.Common;
|
||||||
|
using OpenTK.Graphics.OpenGL;
|
||||||
|
using OpenTK.Mathematics;
|
||||||
|
|
||||||
|
namespace TheLabs;
|
||||||
|
|
||||||
|
public struct Material
|
||||||
|
{
|
||||||
|
public Vector3 ambientColour;
|
||||||
|
public Vector3 diffuseColour;
|
||||||
|
public Vector3 specularColour;
|
||||||
|
public float shininess;
|
||||||
|
|
||||||
|
public Material(Vector3 ambient, Vector3 diffuse, Vector3 specular, float shininessFactor)
|
||||||
|
{
|
||||||
|
ambientColour = ambient;
|
||||||
|
diffuseColour = diffuse;
|
||||||
|
specularColour = specular;
|
||||||
|
shininess = shininessFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Apply(Shader shader)
|
||||||
|
{
|
||||||
|
GL.Uniform3(GL.GetUniformLocation(shader.Handle, "uMaterial.ambientColour"), ref ambientColour);
|
||||||
|
GL.Uniform3(GL.GetUniformLocation(shader.Handle, "uMaterial.diffuseColour"), ref diffuseColour);
|
||||||
|
GL.Uniform3(GL.GetUniformLocation(shader.Handle, "uMaterial.specularColour"), ref specularColour);
|
||||||
|
GL.Uniform1(GL.GetUniformLocation(shader.Handle, "uMaterial.shininess"), shininess);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -11,39 +11,37 @@ namespace TheLabs
|
|||||||
{
|
{
|
||||||
public class MyExampleWindow : GameWindow
|
public class MyExampleWindow : GameWindow
|
||||||
{
|
{
|
||||||
// Create the vertices for our triangle. These are listed in normalized device coordinates (NDC)
|
|
||||||
// In NDC, (0, 0) is the center of the screen.
|
|
||||||
// Negative X coordinates move to the left, positive X move to the right.
|
|
||||||
// Negative Y coordinates move to the bottom, positive Y move to the top.
|
|
||||||
// OpenGL only supports rendering in 3D, so to create a flat triangle, the Z coordinate will be kept as 0.
|
|
||||||
|
|
||||||
|
// -- Scene Graph Nodes
|
||||||
private SceneNode _rootNode;
|
private SceneNode _rootNode;
|
||||||
private SceneNode _characterNode;
|
private SceneNode _characterNode;
|
||||||
private SceneNode _buildingNode;
|
private SceneNode _buildingNode;
|
||||||
|
|
||||||
|
// -- OpenGL Resources
|
||||||
private Shader _shader;
|
private Shader _shader;
|
||||||
private Camera _camera;
|
private Camera _camera;
|
||||||
|
|
||||||
// - Resources that only need to be created once
|
// - Resources that only need to be created once
|
||||||
private Mesh _exampleObject;
|
private Mesh _exampleObject;
|
||||||
private Mesh _buildingObject;
|
private Mesh _buildingObject;
|
||||||
private Texture _texture;
|
private Texture _texture;
|
||||||
private RenderObject _render;
|
private RenderObject _render;
|
||||||
private RenderObject _buildingRender;
|
private RenderObject _buildingRender;
|
||||||
float _rotation = 0.0f;
|
|
||||||
|
|
||||||
// -- Scene Objects
|
|
||||||
|
|
||||||
|
// Camera parameters
|
||||||
private Vector3 _cameraPosition = new Vector3(0.0f, 0.0f, -3.0f);
|
private Vector3 _cameraPosition = new Vector3(0.0f, 0.0f, -3.0f);
|
||||||
private Vector3 _cameraFront = new Vector3(0.0f, 0.0f, -1.0f);
|
private Vector3 _cameraFront = new Vector3(0.0f, 0.0f, -1.0f);
|
||||||
|
|
||||||
private Vector3 _cameraUp = Vector3.UnitY;
|
private Vector3 _cameraUp = Vector3.UnitY;
|
||||||
|
|
||||||
private float _yaw = -90.0f;
|
private float _yaw = -90.0f;
|
||||||
private float _pitch = 0.0f;
|
|
||||||
|
|
||||||
private float _cameraSpeed = 2.5f;
|
private float _cameraSpeed = 2.5f;
|
||||||
private float _rotationSpeed = 50.0f;
|
private float _rotationSpeed = 50.0f;
|
||||||
|
|
||||||
private float _mouseSensitivity = 0.1f;
|
private float _mouseSensitivity = 0.1f;
|
||||||
|
private float _pitch = 0.0f;
|
||||||
|
private float _rotation = 0.0f;
|
||||||
|
|
||||||
|
// Materials and Lighting
|
||||||
|
private Lighting _mainLight;
|
||||||
|
private Material _defaultMaterial;
|
||||||
|
|
||||||
// This prevents a large camera jump when the window first gets focus
|
// This prevents a large camera jump when the window first gets focus
|
||||||
private bool _firstMove = true;
|
private bool _firstMove = true;
|
||||||
@ -58,24 +56,42 @@ namespace TheLabs
|
|||||||
{
|
{
|
||||||
// This is called when the window is created and is where we can set up OpenGL resources.
|
// This is called when the window is created and is where we can set up OpenGL resources.
|
||||||
base.OnLoad();
|
base.OnLoad();
|
||||||
//GL.Disable(EnableCap.CullFace);
|
|
||||||
|
|
||||||
//GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
|
// --- Set up Lighting and Material ---
|
||||||
|
_mainLight = new Lighting(new Vector3(1.2f, 1.0f, 2.0f),
|
||||||
|
new Vector3(0.3f),
|
||||||
|
new Vector3(1.5f),
|
||||||
|
new Vector3(1.0f));
|
||||||
|
|
||||||
|
_defaultMaterial = new Material(
|
||||||
|
new Vector3(0.5f, 0.5f, 0.5f) * 0.1f,
|
||||||
|
new Vector3(0.5f, 0.5f, 0.5f) * 0.6f,
|
||||||
|
new Vector3(1.0f, 1.0f, 1.0f),
|
||||||
|
32.0f);
|
||||||
|
|
||||||
|
// --- Set up OpenGL State ---
|
||||||
GL.ClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
GL.ClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||||
GL.Enable(EnableCap.DepthTest);
|
GL.Enable(EnableCap.DepthTest);
|
||||||
|
|
||||||
|
// --- Set up Camera ---
|
||||||
_camera = new Camera(_cameraPosition, _cameraFront, _cameraUp);
|
_camera = new Camera(_cameraPosition, _cameraFront, _cameraUp);
|
||||||
|
|
||||||
|
// -- Load Shaders, Textures, and Create Scene Objects ---
|
||||||
_shader = new Shader("Shaders/shader.vert", "Shaders/shader.frag");
|
_shader = new Shader("Shaders/shader.vert", "Shaders/shader.frag");
|
||||||
_texture = new Texture("Textures/placeholder.png");
|
_texture = new Texture("Textures/placeholder.png");
|
||||||
|
|
||||||
|
// --- Create Scene Graph ---
|
||||||
_rootNode = new SceneNode();
|
_rootNode = new SceneNode();
|
||||||
_buildingObject = ShapeFactory.CreateTexturedCube();
|
|
||||||
_buildingRender = new RenderObject(_buildingObject, _shader, _texture);
|
|
||||||
|
|
||||||
|
// Create Example Object
|
||||||
|
_buildingObject = ShapeFactory.CreateTexturedSphere();
|
||||||
|
_buildingRender = new RenderObject(_buildingObject, _shader, _texture, _defaultMaterial, _mainLight);
|
||||||
_buildingNode = new SceneNode(_buildingRender);
|
_buildingNode = new SceneNode(_buildingRender);
|
||||||
_buildingNode.Position = new Vector3(2.0f, -1.0f, 0.0f);
|
_buildingNode.Position = new Vector3(2.0f, -1.0f, 0.0f);
|
||||||
_buildingNode.Scale = new Vector3(0.1f, 0.1f, 0.1f);
|
_buildingNode.Scale = new Vector3(0.1f, 0.1f, 0.1f);
|
||||||
_rootNode.AddChild(_buildingNode);
|
_rootNode.AddChild(_buildingNode);
|
||||||
|
|
||||||
|
// Create Character Object
|
||||||
CursorState = CursorState.Grabbed;
|
CursorState = CursorState.Grabbed;
|
||||||
|
|
||||||
|
|
||||||
@ -89,8 +105,6 @@ namespace TheLabs
|
|||||||
base.OnRenderFrame(e);
|
base.OnRenderFrame(e);
|
||||||
// Clear the color buffer and the depth buffer
|
// Clear the color buffer and the depth buffer
|
||||||
GL.Clear(ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit);
|
GL.Clear(ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit);
|
||||||
//_cubeObject.Rotation = Quaternion.FromEulerAngles(_rotation * 0.5f, _rotation, 0); //
|
|
||||||
//_cubeObject2.Rotation = Quaternion.FromEulerAngles(-_rotation * 0.5f, -_rotation, 0);
|
|
||||||
|
|
||||||
// --- Set up Camera ---
|
// --- Set up Camera ---
|
||||||
Matrix4 view = _camera.LookAt();
|
Matrix4 view = _camera.LookAt();
|
||||||
@ -101,15 +115,17 @@ namespace TheLabs
|
|||||||
{
|
{
|
||||||
aspectRatio = 1.0f; // Default to 1:1 if window is minimized
|
aspectRatio = 1.0f; // Default to 1:1 if window is minimized
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3. Create the projection matrix
|
||||||
Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView(
|
Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView(
|
||||||
MathHelper.DegreesToRadians(45f),
|
MathHelper.DegreesToRadians(45f),
|
||||||
aspectRatio,
|
aspectRatio,
|
||||||
0.1f,
|
0.1f,
|
||||||
100.0f
|
100.0f
|
||||||
);
|
);
|
||||||
// --- Draw Scene Objects ---
|
|
||||||
_rootNode.Draw(view, projection, Matrix4.Identity);
|
|
||||||
|
|
||||||
|
// --- Draw Scene Objects ---
|
||||||
|
_rootNode.Draw(view, projection, Matrix4.Identity, _mainLight);
|
||||||
SwapBuffers();
|
SwapBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,17 +9,21 @@ public class RenderObject
|
|||||||
public Mesh Mesh;
|
public Mesh Mesh;
|
||||||
public Shader Shader;
|
public Shader Shader;
|
||||||
public Texture Texture;
|
public Texture Texture;
|
||||||
|
public Material Material;
|
||||||
|
public Lighting Lighting;
|
||||||
|
|
||||||
public Vector3 Position = Vector3.Zero;
|
public Vector3 Position = Vector3.Zero;
|
||||||
public Matrix4 Transform = Matrix4.Identity;
|
public Matrix4 Transform = Matrix4.Identity;
|
||||||
public Quaternion Rotation = Quaternion.Identity;
|
public Quaternion Rotation = Quaternion.Identity;
|
||||||
public Vector3 Scale = Vector3.One;
|
public Vector3 Scale = Vector3.One;
|
||||||
|
|
||||||
public RenderObject(Mesh mesh, Shader shader, Texture texture)
|
public RenderObject(Mesh mesh, Shader shader, Texture texture, Material material, Lighting lighting)
|
||||||
{
|
{
|
||||||
Mesh = mesh;
|
Mesh = mesh;
|
||||||
Shader = shader;
|
Shader = shader;
|
||||||
Texture = texture;
|
Texture = texture;
|
||||||
|
Material = material;
|
||||||
|
Lighting = lighting;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RenderObject(Mesh mesh, Shader shader)
|
public RenderObject(Mesh mesh, Shader shader)
|
||||||
@ -28,14 +32,20 @@ public class RenderObject
|
|||||||
Shader = shader;
|
Shader = shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(Matrix4 view, Matrix4 projection)
|
public void Draw(Matrix4 view, Matrix4 projection, Lighting light)
|
||||||
{
|
{
|
||||||
// 1. Activate Shader
|
Vector3 pink = new Vector3(0.5f, 0.5f, 0.5f);
|
||||||
|
Material mat = new Material(pink * 0.1f, pink * 0.6f, Vector3.One, 32.0f);
|
||||||
|
|
||||||
Shader.Use();
|
Shader.Use();
|
||||||
// 2. Bind Texture
|
|
||||||
Texture.Use();
|
Texture.Use();
|
||||||
Shader.SetInt("uTexture", 0);
|
Shader.SetInt("uTexture", 0);
|
||||||
// 3. Calculate Model Matrix
|
|
||||||
|
Material.Apply(Shader);
|
||||||
|
light.Apply(Shader);
|
||||||
|
|
||||||
|
Vector3 cameraPos = view.Inverted().ExtractTranslation();
|
||||||
|
Shader.SetVector3("uViewPos", cameraPos);
|
||||||
|
|
||||||
Matrix4 model = Matrix4.CreateScale(Scale) * Matrix4.CreateFromQuaternion(Rotation) * Matrix4.CreateTranslation(Position);
|
Matrix4 model = Matrix4.CreateScale(Scale) * Matrix4.CreateFromQuaternion(Rotation) * Matrix4.CreateTranslation(Position);
|
||||||
int modelLoc = GL.GetUniformLocation(Shader.Handle, "model");
|
int modelLoc = GL.GetUniformLocation(Shader.Handle, "model");
|
||||||
@ -47,7 +57,9 @@ public class RenderObject
|
|||||||
int projLoc = GL.GetUniformLocation(Shader.Handle, "projection");
|
int projLoc = GL.GetUniformLocation(Shader.Handle, "projection");
|
||||||
GL.UniformMatrix4(projLoc, false, ref projection); // Try TRUE here
|
GL.UniformMatrix4(projLoc, false, ref projection); // Try TRUE here
|
||||||
|
|
||||||
|
|
||||||
// 5. Tell the Mesh to draw itself
|
// 5. Tell the Mesh to draw itself
|
||||||
Mesh.Draw();
|
Mesh.Draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -23,7 +23,7 @@ public class SceneNode
|
|||||||
Children.Add(child);
|
Children.Add(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(Matrix4 view, Matrix4 projection, Matrix4 parentTransform)
|
public void Draw(Matrix4 view, Matrix4 projection, Matrix4 parentTransform, Lighting light)
|
||||||
{
|
{
|
||||||
Matrix4 localTransform = Matrix4.CreateScale(Scale) * Matrix4.CreateFromQuaternion(Rotation) * Matrix4.CreateTranslation(Position);
|
Matrix4 localTransform = Matrix4.CreateScale(Scale) * Matrix4.CreateFromQuaternion(Rotation) * Matrix4.CreateTranslation(Position);
|
||||||
Matrix4 globalTransform = localTransform * parentTransform;
|
Matrix4 globalTransform = localTransform * parentTransform;
|
||||||
@ -34,12 +34,12 @@ public class SceneNode
|
|||||||
RenderObject.Rotation = Quaternion.Identity;
|
RenderObject.Rotation = Quaternion.Identity;
|
||||||
RenderObject.Scale = Vector3.One;
|
RenderObject.Scale = Vector3.One;
|
||||||
|
|
||||||
RenderObject.Draw(view, projection);
|
RenderObject.Draw(view, projection, light);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var child in Children)
|
foreach (var child in Children)
|
||||||
{
|
{
|
||||||
child.Draw(view, projection, globalTransform);
|
child.Draw(view, projection, globalTransform, light);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,37 +1,81 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
out vec4 outputColor;
|
// Fragment shader for basic lighting with texture mapping
|
||||||
|
|
||||||
|
out vec4 outputColor; // The final output color of the fragment
|
||||||
|
|
||||||
// --- INPUTS ---
|
// --- INPUTS ---
|
||||||
|
// These come from the Vertex Shader
|
||||||
in vec3 FragPos;
|
in vec3 FragPos;
|
||||||
in vec3 Normal;
|
in vec3 Normal;
|
||||||
in vec2 TexCoord;
|
in vec2 TexCoord;
|
||||||
|
|
||||||
|
struct MaterialProperty {
|
||||||
|
vec3 ambientColour;
|
||||||
|
vec3 diffuseColour;
|
||||||
|
vec3 specularColour;
|
||||||
|
float shininess;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LightProperty {
|
||||||
|
vec3 position;
|
||||||
|
vec3 ambientColour;
|
||||||
|
vec3 diffuseColour;
|
||||||
|
vec3 specularColour;
|
||||||
|
};
|
||||||
|
|
||||||
// --- UNIFORMS ---
|
// --- UNIFORMS ---
|
||||||
uniform sampler2D uTexture;
|
uniform sampler2D uTexture; // Image Texture
|
||||||
|
uniform vec3 uViewPos; // Camera Position
|
||||||
|
uniform MaterialProperty uMaterial; // Material Properties
|
||||||
|
uniform LightProperty uPointLight; // Light Properties
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Lighting Setup
|
// --- LIGHTING CALCULATIONS ---
|
||||||
|
// Lighting Setup (hardcoded for simplicity)
|
||||||
vec3 lightPos = vec3(1.2f, 1.0f, 2.0f);
|
vec3 lightPos = vec3(1.2f, 1.0f, 2.0f);
|
||||||
vec3 lightColor = vec3(1.0f, 1.0f, 1.0f);
|
vec3 lightColor = vec3(1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
// 1. Get Texture Color (Keep it as vec4!)
|
// 1. Get Texture Color
|
||||||
|
// Sample the texture at the given texture coordinates
|
||||||
vec4 objColor = texture(uTexture, TexCoord);
|
vec4 objColor = texture(uTexture, TexCoord);
|
||||||
|
|
||||||
// 2. Ambient
|
// 2. Ambient strength
|
||||||
|
// A constant, dim light that ensure s object are not completely dark
|
||||||
|
// It simply multiplies the light color by a small factor
|
||||||
float ambientStrength = 0.1f;
|
float ambientStrength = 0.1f;
|
||||||
vec3 ambient = ambientStrength * lightColor;
|
vec3 ambient = uMaterial.ambientColour * uPointLight.ambientColour;
|
||||||
|
|
||||||
// 3. Diffuse
|
// 3. Diffuse
|
||||||
vec3 norm = normalize(Normal);
|
// Creates the "matte" effect by calculating the angle between the light direction and the surface normal
|
||||||
vec3 lightDir = normalize(lightPos - FragPos);
|
|
||||||
float diff = max(dot(norm, lightDir), 0.0f);
|
|
||||||
vec3 diffuse = diff * lightColor;
|
|
||||||
|
|
||||||
// 4. Combine
|
// Normalize the normal vector and calculate the light direction
|
||||||
// Note: We use objColor.rgb (vec3) to match the lighting calculation
|
vec3 norm = normalize(Normal);
|
||||||
vec3 result = (ambient + diffuse) * objColor.rgb;
|
vec3 lightDir = normalize(uPointLight.position - FragPos);
|
||||||
|
|
||||||
|
// The dot product gives us the cosine of the angle between the two vectors
|
||||||
|
// The max function ensures we don't get negative values (light coming from behind the surface)
|
||||||
|
float diff = max(dot(norm, lightDir), 0.0f);
|
||||||
|
vec3 diffuse = (uPointLight.diffuseColour * diff) * uMaterial.diffuseColour;
|
||||||
|
|
||||||
|
// 4. Specular
|
||||||
|
// Creates the shiny highlights on the surface
|
||||||
|
float shininess = 32.0f;
|
||||||
|
// Calculate the view direction and the reflection direction
|
||||||
|
vec3 viewDirection = normalize(uViewPos - FragPos);
|
||||||
|
// If the light is coming from the light direction, we need to negate it for reflection
|
||||||
|
vec3 reflectDirection = reflect(-lightDir, normalize(Normal));
|
||||||
|
|
||||||
|
// Calculate the specular component using the dot product and shininess factor
|
||||||
|
float spec = pow(max(dot(viewDirection, reflectDirection), 0.0f), shininess);
|
||||||
|
vec3 specular = uMaterial.specularColour * spec * uPointLight.specularColour;
|
||||||
|
|
||||||
|
// 5. Combine
|
||||||
|
// We multiply (Ambient + Diffuse) by the Texture Color.
|
||||||
|
// We ADD Specular afterwards so the highlights look bright white (like plastic/metal).
|
||||||
|
vec3 result = (ambient + diffuse) * objColor.rgb + specular;
|
||||||
|
|
||||||
outputColor = vec4(result, objColor.a);
|
outputColor = vec4(result, objColor.a);
|
||||||
}
|
}
|
||||||
@ -1,16 +1,21 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
|
// Vertex shader decides where each vertex is in 3D space
|
||||||
|
|
||||||
// --- INPUTS ---
|
// --- INPUTS ---
|
||||||
layout(location = 0) in vec3 aPosition;
|
// Comes directly from the vertex buffer
|
||||||
layout(location = 1) in vec3 aNormal;
|
layout(location = 0) in vec3 aPosition; // Raw 3D position
|
||||||
layout(location = 2) in vec2 aTexCoord;
|
layout(location = 1) in vec3 aNormal; // The direction perpendicular to the surface
|
||||||
|
layout(location = 2) in vec2 aTexCoord; // The U,V texture coordinates
|
||||||
|
|
||||||
// --- OUTPUTS ---
|
// --- OUTPUTS ---
|
||||||
|
// We can pass data to the fragment shader through these
|
||||||
out vec3 FragPos;
|
out vec3 FragPos;
|
||||||
out vec3 Normal;
|
out vec3 Normal;
|
||||||
out vec2 TexCoord;
|
out vec2 TexCoord;
|
||||||
|
|
||||||
// --- UNIFORMS ---
|
// --- UNIFORMS ---
|
||||||
|
// These are matrices that help transform our vertices
|
||||||
uniform mat4 model;
|
uniform mat4 model;
|
||||||
uniform mat4 view;
|
uniform mat4 view;
|
||||||
uniform mat4 projection;
|
uniform mat4 projection;
|
||||||
|
|||||||
@ -253,6 +253,74 @@ public static class ShapeFactory
|
|||||||
// --- 4. Create the Mesh ---
|
// --- 4. Create the Mesh ---
|
||||||
return new Mesh(vertices.ToArray(), indices.ToArray(), Mesh.VertexLayout.PosTex);
|
return new Mesh(vertices.ToArray(), indices.ToArray(), Mesh.VertexLayout.PosTex);
|
||||||
}
|
}
|
||||||
|
public static Mesh CreateTexturedSphere(float radius = 0.5f, int stacks = 20, int slices = 20)
|
||||||
|
{
|
||||||
|
var vertices = new List<float>();
|
||||||
|
var indices = new List<uint>();
|
||||||
|
|
||||||
|
// 1. Generate Vertices
|
||||||
|
for (int i = 0; i <= stacks; i++)
|
||||||
|
{
|
||||||
|
// V ranges from 0.0 to 1.0 (bottom to top)
|
||||||
|
float v = (float)i / stacks;
|
||||||
|
|
||||||
|
// Phi ranges from -PI/2 (bottom) to +PI/2 (top)
|
||||||
|
float phi = v * MathF.PI - MathF.PI / 2;
|
||||||
|
|
||||||
|
for (int j = 0; j <= slices; j++)
|
||||||
|
{
|
||||||
|
// U ranges from 0.0 to 1.0 (around the sphere)
|
||||||
|
float u = (float)j / slices;
|
||||||
|
|
||||||
|
// Theta ranges from 0 to 2*PI
|
||||||
|
float theta = u * 2 * MathF.PI;
|
||||||
|
|
||||||
|
// Calculate Position (Spherical Coordinates)
|
||||||
|
float x = radius * MathF.Cos(phi) * MathF.Cos(theta);
|
||||||
|
float y = radius * MathF.Sin(phi);
|
||||||
|
float z = radius * MathF.Cos(phi) * MathF.Sin(theta);
|
||||||
|
|
||||||
|
// Calculate Normal (Normalized position)
|
||||||
|
// Since center is (0,0,0), normal is just (x,y,z) normalized.
|
||||||
|
// Or simpler: (x/r, y/r, z/r)
|
||||||
|
float nx = x / radius;
|
||||||
|
float ny = y / radius;
|
||||||
|
float nz = z / radius;
|
||||||
|
|
||||||
|
// Add Vertex Data: Pos (3) + Normal (3) + Tex (2)
|
||||||
|
vertices.Add(x); vertices.Add(y); vertices.Add(z); // Position
|
||||||
|
vertices.Add(nx); vertices.Add(ny); vertices.Add(nz); // Normal
|
||||||
|
vertices.Add(u); vertices.Add(v); // Texture
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Generate Indices
|
||||||
|
for (int i = 0; i < stacks; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < slices; j++)
|
||||||
|
{
|
||||||
|
// We are building a quad from 4 vertices:
|
||||||
|
// TopLeft (TL), TopRight (TR), BottomLeft (BL), BottomRight (BR)
|
||||||
|
|
||||||
|
uint bl = (uint)(i * (slices + 1) + j);
|
||||||
|
uint br = (uint)(i * (slices + 1) + (j + 1));
|
||||||
|
uint tl = (uint)((i + 1) * (slices + 1) + j);
|
||||||
|
uint tr = (uint)((i + 1) * (slices + 1) + (j + 1));
|
||||||
|
|
||||||
|
// Triangle 1
|
||||||
|
indices.Add(bl);
|
||||||
|
indices.Add(br);
|
||||||
|
indices.Add(tl);
|
||||||
|
|
||||||
|
// Triangle 2
|
||||||
|
indices.Add(br);
|
||||||
|
indices.Add(tr);
|
||||||
|
indices.Add(tl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Mesh(vertices.ToArray(), indices.ToArray(), Mesh.VertexLayout.PosTexNormal);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -52,7 +52,7 @@ public class Bus
|
|||||||
|
|
||||||
foreach (var pos in wheelPositions)
|
foreach (var pos in wheelPositions)
|
||||||
{
|
{
|
||||||
var wheelObj = new RenderObject(_wheelMesh, shader, wheelTexture);
|
//var wheelObj = new RenderObject(_wheelMesh, shader, wheelTexture);
|
||||||
var wheelNode = new SceneNode(wheelObj);
|
var wheelNode = new SceneNode(wheelObj);
|
||||||
|
|
||||||
wheelNode.Position = pos; // Relative to the MainNode!
|
wheelNode.Position = pos; // Relative to the MainNode!
|
||||||
@ -68,7 +68,7 @@ public class Bus
|
|||||||
|
|
||||||
public void Draw(Matrix4 view, Matrix4 projection)
|
public void Draw(Matrix4 view, Matrix4 projection)
|
||||||
{
|
{
|
||||||
MainNode.Draw(view, projection, Matrix4.Identity);
|
//MainNode.Draw(view, projection, Matrix4.Identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -30,4 +30,8 @@
|
|||||||
<None Include="..\..\README.md" Link="README.md" />
|
<None Include="..\..\README.md" Link="README.md" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Remove="Shapes\Bus.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user