protected override void OnLoad() { VSync = VSyncMode.Off; // Check for necessary capabilities: var extensions = GL.GetString(StringName.Extensions); if (!GL.GetString(StringName.Extensions).Contains("GL_ARB_shading_language")) { throw new NotSupportedException(String.Format("This example requires OpenGL 2.0. Found {0}. Aborting.", GL.GetString(StringName.Version).Substring(0, 3))); } if (!extensions.Contains("GL_ARB_texture_compression") || !extensions.Contains("GL_EXT_texture_compression_s3tc")) { throw new NotSupportedException("This example requires support for texture compression. Aborting."); } var temp = new int[1]; GL.GetInteger(GetPName.MaxTextureImageUnits, out temp[0]); Trace.WriteLine(temp[0] + " TMU's for Fragment Shaders found. (2 required)"); GL.GetInteger(GetPName.MaxVaryingFloats, out temp[0]); Trace.WriteLine(temp[0] + " varying floats between VS and FS allowed. (6 required)"); GL.GetInteger(GetPName.MaxVertexUniformComponents, out temp[0]); Trace.WriteLine(temp[0] + " uniform components allowed in Vertex Shader. (6 required)"); GL.GetInteger(GetPName.MaxFragmentUniformComponents, out temp[0]); Trace.WriteLine(temp[0] + " uniform components allowed in Fragment Shader. (11 required)"); Trace.WriteLine(""); // load textures TextureLoaderParameters.MagnificationFilter = TextureMagFilter.Linear; TextureLoaderParameters.MinificationFilter = TextureMinFilter.LinearMipmapLinear; TextureLoaderParameters.WrapModeS = TextureWrapMode.ClampToBorder; TextureLoaderParameters.WrapModeT = TextureWrapMode.ClampToBorder; TextureLoaderParameters.EnvMode = TextureEnvMode.Modulate; uint handle; TextureTarget target; ImageDDS.LoadFromDisk(TextureDiffuseHeightFilename, out handle, out target); _textureDiffuseHeight = TextureFactory.AquireTexture2D((int)handle); Trace.WriteLine("Loaded " + TextureDiffuseHeightFilename + " with handle " + handle + " as " + target); ImageDDS.LoadFromDisk(TextureNormalGlossFilename, out handle, out target); _textureNormalGloss = TextureFactory.AquireTexture2D((int)handle); Trace.WriteLine("Loaded " + TextureNormalGlossFilename + " with handle " + handle + " as " + target); Trace.WriteLine("End of Texture Loading. GL Error: " + GL.GetError()); Trace.WriteLine(""); // initialize buffer var normal = Vector3.UnitZ; var tangent = Vector3.UnitX; var vertices = new[] { new Vertex { Position = new Vector3(-1, -1, 0), TexCoord = new Vector2(0, 0), Normal = normal, Tangent = tangent }, new Vertex { Position = new Vector3(1, -1, 0), TexCoord = new Vector2(1, 0), Normal = normal, Tangent = tangent }, new Vertex { Position = new Vector3(-1, 1, 0), TexCoord = new Vector2(0, 1), Normal = normal, Tangent = tangent }, new Vertex { Position = new Vector3(1, 1, 0), TexCoord = new Vector2(1, 1), Normal = normal, Tangent = tangent } }; _buffer = new Buffer <Vertex>(); _buffer.Init(BufferTarget.ArrayBuffer, vertices); // load shader _program = ProgramFactory.Create <ParallaxProgram>(); _program.Use(); // set up vertex array _vao = new VertexArray(); _vao.Bind(); // bind vertex attributes // the buffer layout is defined by the Vertex struct: // data X Y Z NX NY NZ TX TY TZ U V *next vertex* // offset 0 4 8 12 16 20 24 28 32 36 40 44 // having to work with offsets could be prevented by using seperate buffer objects for each attribute, // but that might reduce performance and can get annoying as well. // performance increase could also be achieved by improving coherent read access // by padding the struct so that each attribute begins at a multiple of 16 bytes, i.e. 4-floats // because the GPU can then read all 4 floats at once. I did not do that here to keep it simple. _vao.BindAttribute(_program.InPosition, _buffer); _vao.BindAttribute(_program.InNormal, _buffer, 12); _vao.BindAttribute(_program.InTangent, _buffer, 24); _vao.BindAttribute(_program.InTexCoord, _buffer, 36); // set camera position Camera.DefaultState.Position = new Vector3(0, 0, 3); Camera.ResetToDefault(); // set state GL.ClearColor(0.2f, 0f, 0.4f, 0f); GL.PointSize(10f); GL.Disable(EnableCap.Dither); GL.FrontFace(FrontFaceDirection.Ccw); GL.PolygonMode(MaterialFace.Front, PolygonMode.Fill); GL.PolygonMode(MaterialFace.Back, PolygonMode.Line); }