我找到了这个C ++代码here。它绘制简单的矩形。效果很好。
#define GLEW_STATIC
#include <iostream>
#include <glew.h>
#include <freeglut.h>
const GLchar* vertexSource =
"#version 150 core\n"
"in vec2 position;"
"in vec3 color;"
"out vec3 Color;"
"void main() {"
" Color = color;"
" gl_Position = vec4(position, 0.0, 1.0);"
"}";
const GLchar* fragmentSource =
"#version 150 core\n"
"in vec3 Color;"
"out vec4 outColor;"
"void main() {"
" outColor = vec4(Color, 1.0);"
"}";
void Display()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glFlush();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_MULTISAMPLE);
glutInitWindowSize(800, 600);
glutInitContextVersion(4, 4);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutCreateWindow("OpenGL");
glewExperimental = GL_TRUE;
if (GLEW_OK != glewInit())
exit(1);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vbo;
glGenBuffers(1, &vbo);
GLfloat vertices[] = {
-0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, 1.0f, 1.0f, 1.0f // Bottom-left
};
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
GLuint ebo;
glGenBuffers(1, &ebo);
GLuint elements[] = {
0, 1, 2,
2, 3, 0
};
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0);
GLint colAttrib = glGetAttribLocation(shaderProgram, "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
glutDisplayFunc(Display);
glutMainLoop();
glDeleteProgram(shaderProgram);
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
glDeleteBuffers(1, &ebo);
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
}
所以我决定用OpenTK框架在C#上重写它:
using OpenTK;
using OpenTK.Graphics.OpenGL;
using System;
using System.IO;
namespace OpenTKTest
{
public class Game : GameWindow
{
private Int32 vao;
private Int32 vbo;
private Int32 ebo;
private Int32 vertexShader;
private Int32 fragmentShader;
private Int32 shaderProgram;
public Game() : base()
{
}
[STAThread]
public static void Main()
{
var window = new Game();
window.Run(120, 120);
window.Dispose();
}
protected override void OnLoad(EventArgs e)
{
GL.GenVertexArrays(1, out vao);
GL.BindVertexArray(vao);
GL.GenBuffers(1, out vbo);
var vertices = new Single[]
{
-0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, 1.0f, 1.0f, 1.0f // Bottom-left
};
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(sizeof(Single) * vertices.Length), vertices, BufferUsageHint.StaticDraw);
GL.GenBuffers(1, out ebo);
var elements = new Single[]
{
0, 1, 2,
2, 3, 0
};
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ebo);
GL.BufferData(BufferTarget.ElementArrayBuffer, new IntPtr(sizeof(UInt32) * elements.Length), elements, BufferUsageHint.StaticDraw);
vertexShader = GL.CreateShader(ShaderType.VertexShader);
GL.ShaderSource(vertexShader, File.ReadAllText("vs.glsl"));
GL.CompileShader(vertexShader);
Console.WriteLine(GL.GetShaderInfoLog(vertexShader));
fragmentShader = GL.CreateShader(ShaderType.FragmentShader);
GL.ShaderSource(fragmentShader, File.ReadAllText("fs.glsl"));
GL.CompileShader(fragmentShader);
Console.WriteLine(GL.GetShaderInfoLog(fragmentShader));
shaderProgram = GL.CreateProgram();
GL.AttachShader(shaderProgram, vertexShader);
GL.AttachShader(shaderProgram, fragmentShader);
GL.BindFragDataLocation(shaderProgram, 0, "outColor");
GL.LinkProgram(shaderProgram);
GL.UseProgram(shaderProgram);
var posAttrib = GL.GetAttribLocation(shaderProgram, "position");
GL.EnableVertexAttribArray(posAttrib);
GL.VertexAttribPointer(posAttrib, 2, VertexAttribPointerType.Float, false, 5 * sizeof(Single), IntPtr.Zero);
var colAttrib = GL.GetAttribLocation(shaderProgram, "color");
GL.EnableVertexAttribArray(colAttrib);
GL.VertexAttribPointer(colAttrib, 3, VertexAttribPointerType.Float, false, 5 * sizeof(Single), new IntPtr(2 * sizeof(Single)));
GL.Viewport(0, 0, Width, Height);
}
protected override void OnRenderFrame(FrameEventArgs e)
{
GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
GL.Clear(ClearBufferMask.ColorBufferBit);
GL.DrawElements(PrimitiveType.Triangles, 6, DrawElementsType.UnsignedInt, IntPtr.Zero);
GL.Flush();
SwapBuffers();
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
GL.DeleteProgram(shaderProgram);
GL.DeleteShader(fragmentShader);
GL.DeleteShader(vertexShader);
GL.DeleteBuffers(1, ref ebo);
GL.DeleteBuffers(1, ref vbo);
GL.DeleteVertexArrays(1, ref vao);
}
}
}
顶点着色器:
#version 150 core
in vec2 position;
in vec3 color;
out vec3 Color;
void main()
{
Color = color;
gl_Position = vec4(position, 0.0, 1.0);
}
片段着色器:
#version 150 core
in vec3 Color;
out vec4 outColor;
void main()
{
outColor = vec4(Color, 1.0);
}
两个来源几乎相同。但是在C#版本GL.DrawElements
中,函数永远不会被调用(我在使用gremedy中的gDEBugger进行调试时发现了它。
为什么这段代码在OpenTK中不起作用?