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
Compare commits
No commits in common. "cf8eb3f5fd4f8902e555786b6ab17c93662da1be" and "87804fc932f1fe87fa1f9bd6de2573c2806c043a" have entirely different histories.
cf8eb3f5fd
...
87804fc932
@ -1,24 +0,0 @@
|
|||||||
using OpenTK.Mathematics;
|
|
||||||
|
|
||||||
namespace TheLabs;
|
|
||||||
|
|
||||||
public class Camera
|
|
||||||
{
|
|
||||||
public Vector3 _position = new Vector3(0.0f, 0.0f, -3.0f);
|
|
||||||
public Vector3 _target = new Vector3(0.0f, 0.0f, -1.0f);
|
|
||||||
public Vector3 _up;
|
|
||||||
|
|
||||||
public Camera(Vector3 position, Vector3 target, Vector3 up)
|
|
||||||
{
|
|
||||||
_position = position;
|
|
||||||
_target = target;
|
|
||||||
_up = up;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Matrix4 LookAt()
|
|
||||||
{
|
|
||||||
return Matrix4.LookAt(_position, _position + _target, _up);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -17,11 +17,9 @@ namespace TheLabs
|
|||||||
// OpenGL only supports rendering in 3D, so to create a flat triangle, the Z coordinate will be kept as 0.
|
// OpenGL only supports rendering in 3D, so to create a flat triangle, the Z coordinate will be kept as 0.
|
||||||
|
|
||||||
private Shader _shader;
|
private Shader _shader;
|
||||||
private Camera _camera;
|
|
||||||
// - Resources that only need to be created once
|
// - Resources that only need to be created once
|
||||||
private Mesh _cubeMesh;
|
private Mesh _cubeMesh;
|
||||||
private Mesh _circleMesh;
|
|
||||||
private Mesh _cylinderMesh;
|
|
||||||
private Texture _cubeTexture;
|
private Texture _cubeTexture;
|
||||||
private Texture _cubeTexture2;
|
private Texture _cubeTexture2;
|
||||||
private float _rotation;
|
private float _rotation;
|
||||||
@ -29,9 +27,6 @@ namespace TheLabs
|
|||||||
// -- Scene Objects
|
// -- Scene Objects
|
||||||
private RenderObject _cubeObject;
|
private RenderObject _cubeObject;
|
||||||
private RenderObject _cubeObject2;
|
private RenderObject _cubeObject2;
|
||||||
private RenderObject _circleObject;
|
|
||||||
private RenderObject _cylinderObject;
|
|
||||||
private Bus _bus;
|
|
||||||
|
|
||||||
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);
|
||||||
@ -65,17 +60,17 @@ namespace TheLabs
|
|||||||
// Set The background color to a nice blue.
|
// Set The background color to a nice blue.
|
||||||
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);
|
||||||
_camera = new Camera(_cameraPosition, _cameraFront, _cameraUp);
|
|
||||||
|
|
||||||
CursorState = CursorState.Grabbed;
|
CursorState = CursorState.Grabbed;
|
||||||
|
|
||||||
_shader = new Shader("Shaders/shader.vert", "Shaders/shader.frag");
|
_shader = new Shader("Shaders/shader.vert", "Shaders/shader.frag");
|
||||||
_cubeTexture = new Texture("Textures/placeholder.png");
|
_cubeMesh = ShapeFactory.CreateTexturedCube();
|
||||||
|
_cubeTexture = new Texture("Textures/stone.jpg");
|
||||||
_cubeTexture2 = new Texture("Textures/placeholder.png");
|
_cubeTexture2 = new Texture("Textures/placeholder.png");
|
||||||
|
_cubeObject = new RenderObject(_cubeMesh, _shader, _cubeTexture);
|
||||||
_bus = new Bus(_cubeTexture, _shader);
|
_cubeObject2 = new RenderObject(_cubeMesh, _shader, _cubeTexture2);
|
||||||
|
_cubeObject.Position = new Vector3(-1.5f, 0.0f, 0.0f);
|
||||||
|
_cubeObject2.Position = new Vector3(1.5f, 0.0f, 0.0f);
|
||||||
|
_cubeObject.Scale = new Vector3(0.5f, 0.5f, 0.5f);
|
||||||
|
_cubeObject2.Scale = new Vector3(0.5f, 0.5f, 0.5f);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -87,11 +82,11 @@ 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); //
|
_cubeObject.Rotation = Quaternion.FromEulerAngles(_rotation * 0.5f, _rotation, 0); //
|
||||||
//_cubeObject2.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 = Matrix4.LookAt(_cameraPosition, _cameraPosition + _cameraFront, _cameraUp);
|
||||||
float aspectRatio = (float)Size.X / Size.Y;
|
float aspectRatio = (float)Size.X / Size.Y;
|
||||||
|
|
||||||
// 2. Add a safety check for divide-by-zero
|
// 2. Add a safety check for divide-by-zero
|
||||||
@ -106,8 +101,8 @@ namespace TheLabs
|
|||||||
100.0f
|
100.0f
|
||||||
);
|
);
|
||||||
|
|
||||||
// --- Draw Scene Objects ---
|
_cubeObject.Draw(view, projection);
|
||||||
_bus.DrawBus(view, projection);
|
_cubeObject2.Draw(view, projection);
|
||||||
|
|
||||||
SwapBuffers();
|
SwapBuffers();
|
||||||
}
|
}
|
||||||
@ -167,16 +162,15 @@ namespace TheLabs
|
|||||||
}
|
}
|
||||||
_pitch = MathHelper.Clamp(_pitch, -89.0f, 89.0f);
|
_pitch = MathHelper.Clamp(_pitch, -89.0f, 89.0f);
|
||||||
Vector3 front;
|
Vector3 front;
|
||||||
_camera._target.X = MathF.Cos(MathHelper.DegreesToRadians(_yaw)) * MathF.Cos(MathHelper.DegreesToRadians(_pitch));
|
front.X = MathF.Cos(MathHelper.DegreesToRadians(_yaw)) * MathF.Cos(MathHelper.DegreesToRadians(_pitch));
|
||||||
_camera._target.Y = MathF.Sin(MathHelper.DegreesToRadians(_pitch));
|
front.Y = MathF.Sin(MathHelper.DegreesToRadians(_pitch));
|
||||||
_camera._target.Z = MathF.Sin(MathHelper.DegreesToRadians(_yaw)) * MathF.Cos(MathHelper.DegreesToRadians(_pitch));
|
front.Z = MathF.Sin(MathHelper.DegreesToRadians(_yaw)) * MathF.Cos(MathHelper.DegreesToRadians(_pitch));
|
||||||
|
_cameraFront = Vector3.Normalize(front);
|
||||||
_cameraFront = Vector3.Normalize(_camera._target);
|
var _cameraRight = Vector3.Normalize(Vector3.Cross(_cameraFront, _cameraUp));
|
||||||
var _cameraRight = Vector3.Normalize(Vector3.Cross(_cameraFront, _camera._up));
|
if (input.IsKeyDown(Keys.W)) _cameraPosition += _cameraFront * _cameraSpeed * (float)e.Time;
|
||||||
if (input.IsKeyDown(Keys.W)) _camera._position += _cameraFront * _cameraSpeed * (float)e.Time;
|
if (input.IsKeyDown(Keys.S)) _cameraPosition -= _cameraFront * _cameraSpeed * (float)e.Time;
|
||||||
if (input.IsKeyDown(Keys.S)) _camera._position -= _cameraFront * _cameraSpeed * (float)e.Time;
|
if (input.IsKeyDown(Keys.A)) _cameraPosition -= _cameraRight * _cameraSpeed * (float)e.Time;
|
||||||
if (input.IsKeyDown(Keys.A)) _camera._position -= _cameraRight * _cameraSpeed * (float)e.Time;
|
if (input.IsKeyDown(Keys.D)) _cameraPosition += _cameraRight * _cameraSpeed * (float)e.Time;
|
||||||
if (input.IsKeyDown(Keys.D)) _camera._position += _cameraRight * _cameraSpeed * (float)e.Time;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ namespace TheLabs
|
|||||||
{
|
{
|
||||||
var nativeWindowSettings = new NativeWindowSettings
|
var nativeWindowSettings = new NativeWindowSettings
|
||||||
{
|
{
|
||||||
Size = new Vector2i(1920, 1080),
|
Size = new Vector2i(800, 600),
|
||||||
Title = "My OpenTK Example Program"
|
Title = "My OpenTK Example Program"
|
||||||
};
|
};
|
||||||
MyVector myVector = new MyVector(30, 40, 0);
|
MyVector myVector = new MyVector(30, 40, 0);
|
||||||
|
|||||||
@ -11,7 +11,6 @@ public class RenderObject
|
|||||||
public Texture Texture;
|
public Texture Texture;
|
||||||
|
|
||||||
public Vector3 Position = Vector3.Zero;
|
public Vector3 Position = Vector3.Zero;
|
||||||
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;
|
||||||
|
|
||||||
|
|||||||
@ -66,60 +66,6 @@ public static class ShapeFactory
|
|||||||
return new Mesh(vertices, indices, Mesh.VertexLayout.PosTex);
|
return new Mesh(vertices, indices, Mesh.VertexLayout.PosTex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Mesh CreateColouredCircle()
|
|
||||||
{
|
|
||||||
float[] vertices = {
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
int segments = 100;
|
|
||||||
for (int i = 0; i <= segments; i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
float angle = i * 2.0f * MathF.PI / segments;
|
|
||||||
float x = 0.5f * MathF.Cos(angle);
|
|
||||||
float y = 0.5f * MathF.Sin(angle);
|
|
||||||
|
|
||||||
Array.Resize(ref vertices, vertices.Length + 7);
|
|
||||||
vertices[^7] = x;
|
|
||||||
vertices[^6] = y;
|
|
||||||
vertices[^5] = 0f;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Mesh(vertices, Mesh.VertexLayout.PosColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Mesh CreateTexturedCircle()
|
|
||||||
{
|
|
||||||
var vertices = new List<float>();
|
|
||||||
|
|
||||||
int segments = 100;
|
|
||||||
|
|
||||||
vertices.Add(0f); // Center X
|
|
||||||
vertices.Add(0f); // Center Y
|
|
||||||
vertices.Add(0f); // Center Z
|
|
||||||
vertices.Add(0.5f); // Center U
|
|
||||||
vertices.Add(0.5f); // Center V
|
|
||||||
for (int i = 0; i <= segments; i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
float angle = i * 2.0f * MathF.PI / segments;
|
|
||||||
float x = 0.5f * MathF.Cos(angle);
|
|
||||||
float y = 0.5f * MathF.Sin(angle);
|
|
||||||
|
|
||||||
vertices.Add(x); // X
|
|
||||||
vertices.Add(y); // Y
|
|
||||||
vertices.Add(0f); // Z
|
|
||||||
vertices.Add((x + 0.5f)); // U
|
|
||||||
vertices.Add((y + 0.5f)); // V
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Mesh(vertices.ToArray(), Mesh.VertexLayout.PosTex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Mesh CreateColorCube()
|
public static Mesh CreateColorCube()
|
||||||
{
|
{
|
||||||
float[] vertices = {
|
float[] vertices = {
|
||||||
@ -165,92 +111,8 @@ public static class ShapeFactory
|
|||||||
return new Mesh(vertices, indices, Mesh.VertexLayout.PosColor);
|
return new Mesh(vertices, indices, Mesh.VertexLayout.PosColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Mesh CreateTexturedCylinder(int segments = 32, float height = 1.0f, float radius = 0.5f)
|
// You'd also add CreateCircle, CreateCylinder, etc.
|
||||||
{
|
// Your Cylinder should be ONE mesh, not 3 draw calls.
|
||||||
var vertices = new List<float>();
|
// Generate the top, bottom, and side vertices into one
|
||||||
var indices = new List<uint>();
|
// big array and use one EBO for all of it.
|
||||||
uint vertexIndex = 0;
|
|
||||||
|
|
||||||
float halfHeight = height / 2.0f;
|
|
||||||
uint topCenterIndex = vertexIndex;
|
|
||||||
vertices.AddRange(new[]
|
|
||||||
{
|
|
||||||
0.0f, halfHeight, 0.0f, // Position
|
|
||||||
0.5f, 0.5f
|
|
||||||
}); // Top center vertex
|
|
||||||
|
|
||||||
vertexIndex++;
|
|
||||||
|
|
||||||
uint topStartIndex = vertexIndex;
|
|
||||||
|
|
||||||
for (int i = 0; i <= segments; i++)
|
|
||||||
{
|
|
||||||
float angle = i * 2.0f * MathF.PI / segments;
|
|
||||||
float x = radius * MathF.Cos(angle);
|
|
||||||
float z = radius * MathF.Sin(angle);
|
|
||||||
|
|
||||||
// UV coordinates are mapped from model space (-0.5 to +0.5)
|
|
||||||
// to texture space (0.0 to 1.0)
|
|
||||||
float u = x / (radius * 2) + 0.5f;
|
|
||||||
float v = z / (radius * 2) + 0.5f;
|
|
||||||
|
|
||||||
vertices.AddRange(new[] { x, halfHeight, z, u, v });
|
|
||||||
vertexIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add Top Cap Indices (Triangle Fan)
|
|
||||||
for (int i = 0; i < segments; i++)
|
|
||||||
{
|
|
||||||
indices.Add(topCenterIndex);
|
|
||||||
indices.Add(topStartIndex + (uint)i);
|
|
||||||
indices.Add(topStartIndex + (uint)((i + 1) % segments)); // Wrap around
|
|
||||||
}
|
|
||||||
|
|
||||||
uint sideStartIndex = vertexIndex;
|
|
||||||
|
|
||||||
// Loop from 0 to segments (inclusive) to get (segments + 1)
|
|
||||||
// vertices for wrapping the texture seamlessly.
|
|
||||||
for (int i = 0; i <= segments; i++)
|
|
||||||
{
|
|
||||||
float angle = i * 2.0f * MathF.PI / segments;
|
|
||||||
float x = radius * MathF.Cos(angle);
|
|
||||||
float z = radius * MathF.Sin(angle);
|
|
||||||
|
|
||||||
// The U coordinate goes from 0.0 to 1.0 around the cylinder
|
|
||||||
float u = (float)i / segments;
|
|
||||||
|
|
||||||
// Add Top Side Vertex
|
|
||||||
vertices.AddRange(new[] { x, halfHeight, z, u, 1.0f }); // V = 1.0 (top)
|
|
||||||
vertexIndex++;
|
|
||||||
|
|
||||||
// Add Bottom Side Vertex
|
|
||||||
vertices.AddRange(new[] { x, -halfHeight, z, u, 0.0f }); // V = 0.0 (bottom)
|
|
||||||
vertexIndex++;
|
|
||||||
}
|
|
||||||
// Add Side Wall Indices (Quad Strip)
|
|
||||||
for (int i = 0; i < segments; i++)
|
|
||||||
{
|
|
||||||
// Each segment has 2 vertices (top, bottom)
|
|
||||||
// We reference the vertices we just created.
|
|
||||||
uint topCurrent = sideStartIndex + (uint)(i * 2);
|
|
||||||
uint bottomCurrent = topCurrent + 1;
|
|
||||||
uint topNext = sideStartIndex + (uint)((i + 1) * 2);
|
|
||||||
uint bottomNext = topNext + 1;
|
|
||||||
|
|
||||||
// Triangle 1 (CCW)
|
|
||||||
indices.Add(topCurrent);
|
|
||||||
indices.Add(bottomCurrent);
|
|
||||||
indices.Add(topNext);
|
|
||||||
|
|
||||||
// Triangle 2 (CCW)
|
|
||||||
indices.Add(bottomCurrent);
|
|
||||||
indices.Add(bottomNext);
|
|
||||||
indices.Add(topNext);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- 4. Create the Mesh ---
|
|
||||||
return new Mesh(vertices.ToArray(), indices.ToArray(), Mesh.VertexLayout.PosTex);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,90 +0,0 @@
|
|||||||
using LearnOpenTK.Common;
|
|
||||||
using OpenTK.Mathematics;
|
|
||||||
|
|
||||||
namespace TheLabs.Shapes;
|
|
||||||
|
|
||||||
public class Bus
|
|
||||||
{
|
|
||||||
private Mesh _wheelMesh;
|
|
||||||
private RenderObject _wheelObject;
|
|
||||||
|
|
||||||
private Texture _wheelTexture;
|
|
||||||
private Shader _wheelShader;
|
|
||||||
private Texture _bodyTexture;
|
|
||||||
|
|
||||||
public Bus(Texture texture, Shader shader)
|
|
||||||
{
|
|
||||||
_wheelTexture = new Texture("Textures/rubber.jpg");
|
|
||||||
_wheelShader = shader;
|
|
||||||
|
|
||||||
_bodyTexture = new Texture("Textures/rust.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DrawWheel(Matrix4 view, Matrix4 projection, Vector3 position)
|
|
||||||
{
|
|
||||||
Matrix4 localTransform = Matrix4.Identity;
|
|
||||||
//Matrix4 comboTransform = localTransform * _wheelObject.Transform;
|
|
||||||
|
|
||||||
_wheelMesh = ShapeFactory.CreateTexturedCylinder();
|
|
||||||
_wheelObject = new RenderObject(_wheelMesh, _wheelShader, _wheelTexture);
|
|
||||||
|
|
||||||
// Front Left Wheel
|
|
||||||
_wheelObject.Position = new Vector3(position);
|
|
||||||
_wheelObject.Scale = new Vector3(0.3f, 0.1f, 0.2f);
|
|
||||||
_wheelObject.Rotation = Quaternion.FromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(90.0f));
|
|
||||||
|
|
||||||
_wheelObject.Draw(view, projection);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void drawBody(Matrix4 view, Matrix4 projection)
|
|
||||||
{
|
|
||||||
Mesh bodyMesh = ShapeFactory.CreateTexturedCube();
|
|
||||||
RenderObject bodyObject = new RenderObject(bodyMesh, _wheelShader, _bodyTexture);
|
|
||||||
|
|
||||||
bodyObject.Position = new Vector3(0.0f, 0.0f, 0.0f);
|
|
||||||
bodyObject.Scale = new Vector3(1.5f, 0.5f, 0.5f);
|
|
||||||
|
|
||||||
bodyObject.Draw(view, projection);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawRoof(Matrix4 view, Matrix4 projection)
|
|
||||||
{
|
|
||||||
Mesh roofMesh = ShapeFactory.CreateTexturedCylinder();
|
|
||||||
RenderObject roofObject = new RenderObject(roofMesh, _wheelShader, _bodyTexture);
|
|
||||||
|
|
||||||
roofObject.Position = new Vector3(0.0f, 0.25f, 0.0f);
|
|
||||||
roofObject.Scale = new Vector3(0.5f, 1.5f, .25f);
|
|
||||||
|
|
||||||
roofObject.Rotation = Quaternion.FromAxisAngle(Vector3.UnitY, MathHelper.DegreesToRadians(90.0f));
|
|
||||||
roofObject.Rotation *= Quaternion.FromAxisAngle(Vector3.UnitX, MathHelper.DegreesToRadians(90.0f));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
roofObject.Draw(view, projection);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DrawBus(Matrix4 view, Matrix4 projection)
|
|
||||||
{
|
|
||||||
// Drawing 4 wheels
|
|
||||||
float xOffset = 0.4f; // Reduced to bring wheels closer to the body
|
|
||||||
float zOffset = 0.28f; // Reduced to bring front and back wheels closer
|
|
||||||
float yOffset = -0.3f; // Adjusted to ensure wheels touch the body
|
|
||||||
|
|
||||||
// Drawing 4 wheels
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
float xPosition = (i % 2 == 0) ? -xOffset : xOffset; // Left or Right
|
|
||||||
float zPosition = (i < 2) ? zOffset : -zOffset; // Front or Back
|
|
||||||
|
|
||||||
DrawWheel(view, projection, new Vector3(xPosition, yOffset, zPosition));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drawing the body
|
|
||||||
drawBody(view, projection);
|
|
||||||
// Drawing the roof
|
|
||||||
drawRoof(view, projection);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user