2025-11-11 15:35:10 +00:00

134 lines
5.2 KiB
C#

using OpenTK.Graphics.OpenGL4;
using OpenTK.Windowing.Common;
using OpenTK.Windowing.GraphicsLibraryFramework;
using OpenTK.Windowing.Desktop;
using LearnOpenTK.Common;
using OpenTK.Mathematics;
using TheLabs.Shapes;
namespace TheLabs
{
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.
private Shader _shader;
// - Resources that only need to be created once
private Mesh _cubeMesh;
private Texture _cubeTexture;
private float _rotation;
// -- Scene Objects
private RenderObject _cubeObject;
public MyExampleWindow(GameWindowSettings gameWindowSettings, NativeWindowSettings nativeWindowSettings)
: base(gameWindowSettings, nativeWindowSettings)
{
}
// Now, we start initializing OpenGL.
protected override void OnLoad()
{
// This is called when the window is created and is where we can set up OpenGL resources.
base.OnLoad();
string shaderVertPath = "Shaders/shader.vert";
string texturePath = "Textures/placeholder.png";
if (!File.Exists(shaderVertPath))
{
throw new FileNotFoundException($"The shader file was not found at: {Path.GetFullPath(shaderVertPath)}");
}
if (!File.Exists(texturePath))
{
throw new FileNotFoundException($"The texture file was not found at: {Path.GetFullPath(texturePath)}");
}
//GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
// Set The background color to a nice blue.
GL.ClearColor(0.2f, 0.3f, 0.3f, 1.0f);
GL.Enable(EnableCap.DepthTest);
_shader = new Shader("Shaders/shader.vert", "Shaders/shader.frag");
_cubeMesh = ShapeFactory.CreateTexturedCube();
_cubeTexture = new Texture("Textures/placeholder.png");
_cubeObject = new RenderObject(_cubeMesh, _shader, _cubeTexture);
_cubeObject.Position = new Vector3(-0.75f, 0.0f, 0.0f);
}
// Now that initialization is done, let's create our render loop.
protected override void OnRenderFrame(FrameEventArgs e)
{
// This is called once per frame and is where all the rendering code goes.
base.OnRenderFrame(e);
// Clear the color buffer and the depth buffer
GL.Clear(ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit);
_cubeObject.Rotation = Quaternion.FromEulerAngles(_rotation * 0.5f, _rotation, 0); //
// --- Set up Camera ---
Matrix4 view = Matrix4.CreateTranslation(0.0f, 0.0f, -3.0f);
Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView(
MathHelper.DegreesToRadians(45f),
Size.X / (float)Size.Y,
0.1f,
100.0f
);
_cubeObject.Draw(view, projection);
SwapBuffers();
}
protected override void OnUpdateFrame(FrameEventArgs e)
{
base.OnUpdateFrame(e);
_rotation += (float)e.Time;
var input = KeyboardState;
if (input.IsKeyDown(Keys.Escape))
{
Close();
}
}
protected override void OnResize(ResizeEventArgs e)
{
base.OnResize(e);
// When the window gets resized, we have to call GL.Viewport to resize OpenGL's viewport to match the new size.
// If we don't, the NDC will no longer be correct.
GL.Viewport(0, 0, Size.X, Size.Y);
}
// Now, for cleanup.
// You should generally not do cleanup of opengl resources when exiting an application,
// as that is handled by the driver and operating system when the application exits.
//
// There are reasons to delete opengl resources, but exiting the application is not one of them.
// This is provided here as a reference on how resource cleanup is done in opengl, but
// should not be done when exiting the application.
//
// Places where cleanup is appropriate would be: to delete textures that are no
// longer used for whatever reason (e.g. a new scene is loaded that doesn't use a texture).
// This would free up video ram (VRAM) that can be used for new textures.
//
// The coming chapters will not have this code.
protected override void OnUnload()
{
// Unbind all the resources by binding the targets to 0/null.
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.BindVertexArray(0);
GL.UseProgram(0);
GL.DeleteProgram(_shader.Handle);
base.OnUnload();
}
}
}