概要
cscの作法、調べてみた。
opentkでshadertoy、やってみた。
iResolution、iGlobalTime、iFrameを導入。
写真
サンプルコード
using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL4;
namespace App
{
class Gwin: GameWindow {
double counter = 0;
private readonly float[] Vertices = {
-1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
};
private int[] VertexBufferObjects = new int[1];
private int[] VertexArrayObjects = new int[1];
private int VertexShader;
private int FragmentShader;
private int Program;
private int PositionLocation;
private readonly string VertexShaderSourceCode = @"#version 330 core
layout(location = 0) in vec3 InPosition;
void main() {
gl_Position = vec4(InPosition, 1.0);
}
";
private readonly string FragmentShaderSourceCode = @"#version 330 core
out vec4 FragColor;
uniform vec2 iResolution;
uniform float iGlobalTime;
uniform int iFrame;
#define PI 3.14159265359
#define TWOPI 6.28318530718
float linearstep(float edge0, float edge1, float x) {
float t = (x - edge0) / (edge1 - edge0);
return clamp(t, 0.0, 1.0);
}
float smootherstep(float edge0, float edge1, float x) {
float t = (x - edge0) / (edge1 - edge0);
float t1 = t * t * t * (t * (t * 6. - 15.) + 10.);
return clamp(t1, 0.0, 1.0);
}
void plot(vec2 r, float y, float lineThickness, vec3 color, inout vec3 pixel) {
if (abs(y - r.y) < lineThickness)
pixel = color;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 r = 2.0 * vec2(fragCoord.xy - 0.5 * iResolution.xy) / iResolution.y;
vec3 bgCol = vec3(1.0);
vec3 axesCol = vec3(0.0, 0.0, 1.0);
vec3 gridCol = vec3(0.5);
vec3 col1 = vec3(0.841, 0.582, 0.594);
vec3 col2 = vec3(0.884, 0.850, 0.648);
vec3 col3 = vec3(0.348, 0.555, 0.641);
vec3 pixel = bgCol;
const float tickWidth = 0.1;
for (float i = -2.0; i < 2.0; i += tickWidth)
{
if (abs(r.x - i) < 0.004)
pixel = gridCol;
if (abs(r.y - i) < 0.004)
pixel = gridCol;
}
if (abs(r.x) < 0.006)
pixel = axesCol;
if (abs(r.y) < 0.007)
pixel = axesCol;
float x = r.x;
float y = r.y;
if (abs(2. * x + .5 - y) < 0.02)
pixel = col1;
if (abs(r.x * r.x - 0.2 - y) < 0.01)
pixel = col1;
if (abs(sin(PI * r.x) - y) < 0.02)
pixel = col1;
if (abs(0.25 * step(0.0, x) + 0.6 - y) < 0.01)
pixel = col3;
if (abs(0.25 * linearstep(-0.5, 0.5, x) + 0.1 - y) < 0.01)
pixel = col3;
if (abs(0.25 * smoothstep(-0.5, 0.5, x) - 0.4 - y) < 0.01)
pixel = col3;
if (abs(0.25 * smootherstep(-0.5, 0.5, x) - 0.9 - y) < 0.01)
pixel = col3;
plot(r, 0.5 * clamp(sin(TWOPI * x), 0.0, 1.0) - 0.7, 0.015, col2, pixel);
plot(r, 0.6 * exp(-10.0 * (x + 0.8) * (x + 0.8)) - 0.1, 0.015, col2, pixel);
fragColor = vec4(pixel, 1.0);
}
void main(void) {
vec4 color = vec4(1.0, 0.0, 0.0, 1.0);
mainImage(color, gl_FragCoord.xy);
color.w = 1.0;
FragColor = color;
}
";
public Gwin(int width, int height, GraphicsMode mode, string title): base(width, height, mode, title) {
this.VSync = VSyncMode.On;
InitializeBuffer();
InitializeShader();
InitializeProgram();
InitializeVertexArrayObject();
}
private void InitializeBuffer() {
GL.GenBuffers(1, VertexBufferObjects);
GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBufferObjects[0]);
GL.BufferData(BufferTarget.ArrayBuffer, 4 * 18, Vertices, BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
}
private void InitializeShader() {
VertexShader = CreateShader(ShaderType.VertexShader, VertexShaderSourceCode);
FragmentShader = CreateShader(ShaderType.FragmentShader, FragmentShaderSourceCode);
}
private int CreateShader(ShaderType shaderType, string sourceCode) {
int shader = GL.CreateShader(shaderType);
GL.ShaderSource(shader, sourceCode);
GL.CompileShader(shader);
string log = GL.GetShaderInfoLog(shader);
return shader;
}
private void InitializeProgram() {
Program = GL.CreateProgram();
GL.AttachShader(Program, VertexShader);
GL.AttachShader(Program, FragmentShader);
GL.LinkProgram(Program);
GL.UseProgram(Program);
PositionLocation = GL.GetAttribLocation(Program, "InPosition");
GL.UseProgram(0);
}
private void InitializeVertexArrayObject() {
GL.GenVertexArrays(1, VertexArrayObjects);
GL.BindVertexArray(VertexArrayObjects[0]);
GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBufferObjects[0]);
GL.EnableVertexAttribArray(PositionLocation);
GL.VertexAttribPointer(PositionLocation, 3, VertexAttribPointerType.Float, false, 12, 0);
GL.EnableVertexAttribArray(0);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.BindVertexArray(0);
}
protected override void OnUpdateFrame(FrameEventArgs args) {
base.OnUpdateFrame(args);
}
protected override void OnResize(EventArgs e) {
GL.Viewport(0, 0, Width, Height);
}
protected override void OnUnload(EventArgs e) {
base.OnUnload(e);
GL.DeleteVertexArrays(1, VertexArrayObjects);
GL.DeleteBuffers(1, VertexBufferObjects);
GL.DeleteProgram(Program);
}
protected override void OnRenderFrame(FrameEventArgs e) {
base.OnRenderFrame(e);
counter += e.Time;
GL.Clear(ClearBufferMask.ColorBufferBit);
GL.BindBuffer(BufferTarget.ArrayBuffer, VertexBufferObjects[0]);
GL.BindVertexArray(VertexArrayObjects[0]);
GL.UseProgram(Program);
int resLoc = GL.GetUniformLocation(Program, "iResolution");
GL.Uniform2(resLoc, new Vector2(Width, Height));
int timeLoc = GL.GetUniformLocation(Program, "iGlobalTime");
GL.Uniform1(timeLoc, (float) counter);
int frameLoc = GL.GetUniformLocation(Program, "iFrame");
GL.Uniform1(frameLoc, (int) (counter * 60));
GL.DrawArrays(PrimitiveType.Triangles, 0, 3);
GL.DrawArrays(PrimitiveType.Triangles, 3, 3);
this.SwapBuffers();
}
}
class Program {
static void Main(string[] args) {
Gwin window = new Gwin(500, 500, OpenTK.Graphics.GraphicsMode.Default, "Test");
window.Run();
}
}
}
以上。
