概要
cscの作法、調べてみた。
opentkのgamewindow使ってみた。
Shader使ってみた。
GL.Uniform使ってみた。
写真
サンプルコード
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();
}
}
}
以上。