LoginSignup
0
0

cscの作法 その375

Posted at

概要

cscの作法、調べてみた。
opentkのgamewindow使ってみた。
Shader使ってみた。
GL.Uniform使ってみた。

写真

image.png

サンプルコード



using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL4;

namespace App
{
	public class OpenGLUniform: System.IDisposable {
		public int Location;
		public string Name;
		public OpenGLProgram Program;
		public OpenGLUniform(OpenGLProgram program, string name) {
			Program = program;
			Name = name;
			Program.Use();
			Location = GL.GetUniformLocation(Program.Id, Name);
		}
		public void Uniform1(double value) {
			Program.Use();
			GL.Uniform1(Location, value);
		}
		public void Uniform1(float value) {
			Program.Use();
			GL.Uniform1(Location, value);
		}
		public void Uniform1(int value) {
			Program.Use();
			GL.Uniform1(Location, value);
		}
		public void Uniform2(Vector2 value) {
			Program.Use();
			GL.Uniform2(Location, value);
		}
		public void Uniform3(Vector3 value) {
			Program.Use();
			GL.Uniform3(Location, value);
		}
		public void Uniform4(Vector4 value) {
			Program.Use();
			GL.Uniform4(Location, value);
		}
		public void Matrix4(bool transpose, ref Matrix4 value) {
			Program.Use();
			GL.UniformMatrix4(Location, transpose, ref value);
		}
		public void Dispose() {
		}
	}
	public class OpenGLShader: System.IDisposable {
		public int Id;
		public ShaderType Type;
		public string SourceCode;
		public OpenGLShader(ShaderType shaderType, string sourceCode) {
			Type = shaderType;
			SourceCode = sourceCode;
			Id = GL.CreateShader(Type);
			GL.ShaderSource(Id, SourceCode);
			GL.CompileShader(Id);
		}
		public void Dispose() {
			GL.DeleteShader(Id);
		}
	}
	public class OpenGLProgram: System.IDisposable {
		public int Id;
		public OpenGLShader VertexShader;
		public OpenGLShader FragmentShader;
		public OpenGLProgram(OpenGLShader vertexShader, OpenGLShader fragmentShader) {
			VertexShader = vertexShader;
			FragmentShader = fragmentShader;
			Id = GL.CreateProgram();
			GL.AttachShader(Id, VertexShader.Id);
			GL.AttachShader(Id, FragmentShader.Id);
			GL.LinkProgram(Id);
		}
		public void Use() {
			GL.UseProgram(Id);
		}
		public void Unuse() {
			//GL.UseProgram(OpenGLConstant.NoneProgramId);
		}
		public void Dispose() {
			GL.DeleteProgram(Id);
		}
	}
	public class OpenGLBuffer: System.IDisposable {
		public int Count;
		public BufferTarget Target;
		public int[] Ids;
		public OpenGLBuffer(int count, BufferTarget bufferTarget) {
			Count = count;
			Target = bufferTarget;
			Ids = new int[Count];
			GL.GenBuffers(Count, Ids);
		}
		public void Bind(int index) {
			GL.BindBuffer(Target, Ids[index]);
		}
		public void Unbind() {
			//GL.BindBuffer(Target, OpenGLConstant.NoneBufferId);
		}
		public void SetData<T>(int index, int sizeInByte, T[] data, BufferUsageHint hint) where T : struct {
			Bind(index);
			GL.BufferData(Target, sizeInByte, data, hint);
		}
		public void Dispose() {
			GL.DeleteBuffers(Count, Ids);
		}
	}
	public class OpenGLVertexArray: System.IDisposable {
		public int Count;
		public int[] Ids;
		public OpenGLVertexArray(int count) {
			Count = count;
			Ids = new int[Count];
			GL.GenVertexArrays(Count, Ids);
		}
		public void Bind(int index) {
			GL.BindVertexArray(Ids[index]);
		}
		public void Unbind() {
			//GL.BindVertexArray(OpenGLConstant.NoneVertexArrayId);
		}
		public void EnableAttribute(int index, int location, int elementCount, VertexAttribPointerType elementType, bool normalized, int strideInByte, int offsetInByte) {
			Bind(index);
			GL.EnableVertexAttribArray(location);
			GL.VertexAttribPointer(location, elementCount, elementType, normalized, strideInByte, offsetInByte);
			//GL.EnableVertexAttribArray(OpenGLConstant.NoneLocation);
		}
		public void Dispose() {
			GL.DeleteBuffers(Count, Ids);
		}
	}
	class Gwin: GameWindow {
		private readonly float[] Vertices = {
			-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
			 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
			 0.0f,  0.5f, 0.0f, 0.0f, 0.0f, 1.0f,
		};
		private int[] VertexBufferObjects = new int[1];
		private int[] VertexArrayObjects = new int[1];
		private readonly string VertexShaderSourceCode = "#version 330 core\r\n" +
			"layout(location = 0) in vec3 InPosition;\r\n" +
			"layout(location = 1) in vec3 InColor;\r\n" +
			"out vec3 OutColor;\r\n" +
			"void main() {\r\n" +
			"	gl_Position = vec4(InPosition, 1.0);\r\n" +
			"	OutColor = InColor;\r\n" +
			"}";
		private readonly string FragmentShaderSourceCode = "#version 330 core\r\n" +
			"uniform float elapsedTime;\r\n" +
			"in vec3 OutColor;\r\n" +
			"out vec4 FragColor;\r\n" +
			"void main() {\r\n" +
			"	FragColor = sin(elapsedTime) * vec4(OutColor, 1.0);\r\n" +
			"}";
		private OpenGLBuffer VertexBuffer;
		private OpenGLVertexArray VertexArray;
		private OpenGLShader VertexShader;
		private OpenGLShader FragmentShader;
		private OpenGLProgram Program;
		private OpenGLUniform ElapsedTimeUniform;
		private double ElapsedTime;
		public Gwin(int width, int height, GraphicsMode mode, string title): base(width, height, mode, title) {
			this.VSync = VSyncMode.On;
			InitializeBuffer();
			InitializeShader();
			InitializeProgram();
			InitializeUniform();
			InitializeVertexArrayObject();
			ElapsedTime = .0;
		}
		protected override void OnUpdateFrame(FrameEventArgs args) {
			base.OnUpdateFrame(args);
		}
		protected override void OnRenderFrame(FrameEventArgs e) {
			base.OnRenderFrame(e);
			GL.Clear(ClearBufferMask.ColorBufferBit);
			VertexBuffer.Bind(0);
			VertexArray.Bind(0);
			Program.Use();
			ElapsedTimeUniform.Uniform1((float) ElapsedTime);
			GL.DrawArrays(PrimitiveType.Triangles, 0, 3);
			Program.Unuse();
			VertexArray.Unbind();
			VertexBuffer.Unbind();
			this.SwapBuffers();
			ElapsedTime += e.Time;
		}
		private void InitializeBuffer() {
			VertexBuffer = new OpenGLBuffer(1, BufferTarget.ArrayBuffer);
			VertexBuffer.SetData(0, 4 * 18, Vertices, BufferUsageHint.StaticDraw);
		}
		private void InitializeShader() {
			VertexShader = new OpenGLShader(ShaderType.VertexShader, VertexShaderSourceCode);
			FragmentShader = new OpenGLShader(ShaderType.FragmentShader, FragmentShaderSourceCode);
		}
		private void InitializeProgram() {
			Program = new OpenGLProgram(VertexShader, FragmentShader);
		}
		private void InitializeUniform() {
			ElapsedTimeUniform = new OpenGLUniform(Program, "elapsedTime");
		}
		private void InitializeVertexArrayObject() {
			VertexArray = new OpenGLVertexArray(1);
			Program.Use();
			VertexBuffer.Bind(0);
			VertexArray.Bind(0);
			VertexArray.EnableAttribute(0, 0, 3, VertexAttribPointerType.Float, false, 24, 0);
			VertexArray.EnableAttribute(0, 1, 3, VertexAttribPointerType.Float, false, 24, 12);
			VertexArray.Unbind();
			VertexBuffer.Unbind();
			Program.Unuse();
		}
		protected override void OnResize(EventArgs e) {
			GL.Viewport(0, 0, Width, Height);
		}
		protected override void OnUnload(EventArgs e) {
			base.OnUnload(e);
		}
	}
	class Program1 {
		static void Main(string[] args) {
			Gwin window = new Gwin(500, 500, OpenTK.Graphics.GraphicsMode.Default, "Test");
			window.Run();
		}
	}
}





以上。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0