/* A helper function that gets a GLubyte *pdata * array out of the pMemDC so you can scale it and pass it to _maketexture. * Used in the constructors.*/ protected void _maketexture(byte [] pdata) { /* usemipmap uses more memory, makes a nicer looking * images across a range of size scales. It may be slower. */ GL.Enable(EnableCap.Texture2D); GL.GenTextures(1, out _textureID); /* Get an unused name for a texture * object, which is something a bit like a display list. That is, * it's a kind of handle which will enable us to rapidly reaccess a * texture once we've first loaded it. */ GL.BindTexture(TextureTarget.Texture2D, _textureID); /* Makes this texture current * so that all the following calls in _maketexture() affect it. */ GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); GL.PixelStore(PixelStoreParameter.PackAlignment, 1); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Clamp); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Clamp); if (_usemipmap) { GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); Glu.Build2DMipmap(TextureTarget.Texture2D, _pixeldataformat, _cx, _cy, (_pixeldataformat == 3)? PixelFormat.Rgb : PixelFormat.Rgba, PixelType.UnsignedByte, pdata); } else //No usemipmap means use only use one texture { //Use faster size filters. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); // GL_NEAREST GL.TexImage2D(TextureTarget.Texture2D, 0, (_pixeldataformat == 3) ? PixelInternalFormat.Rgb : PixelInternalFormat.Rgba, _cx, _cy, 0, (_pixeldataformat == 3) ? PixelFormat.Rgb : PixelFormat.Rgba, PixelType.UnsignedByte, pdata); } GL.BindTexture(TextureTarget.Texture2D, 0); //Close off the call to glBindTexture started above. GL.Disable(EnableCap.Texture2D); }
/// <summary> /// The main entry point for the application. /// </summary> static void Main() { // Request a 32-bits depth buffer when creating the window ContextSettings contextSettings = new ContextSettings(); contextSettings.DepthBits = 32; // Create the main window RenderWindow window = new RenderWindow(new VideoMode(800, 600), "SFML graphics with OpenGL", Styles.Default, contextSettings); window.SetVerticalSyncEnabled(true); // Make it the active window for OpenGL calls window.SetActive(); // Initialize OpenTK Toolkit.Init(); GraphicsContext context = new GraphicsContext(new ContextHandle(IntPtr.Zero), null); // Setup event handlers window.Closed += new EventHandler(OnClosed); window.KeyPressed += new EventHandler <KeyEventArgs>(OnKeyPressed); window.Resized += new EventHandler <SizeEventArgs>(OnResized); // Create a sprite for the background Sprite background = new Sprite(new Texture("resources/background.jpg")); // Create a text to display on top of the OpenGL object Text text = new Text("SFML / OpenGL demo", new Font("resources/sansation.ttf")); text.Position = new Vector2f(250, 450); text.Color = new Color(255, 255, 255, 170); // Load an OpenGL texture. // We could directly use a SFML.Graphics.Texture as an OpenGL texture (with its Bind() member function), // but here we want more control on it (generate mipmaps, ...) so we create a new one int texture = 0; using (Image image = new Image("resources/texture.jpg")) { GL.GenTextures(1, out texture); GL.BindTexture(TextureTarget.Texture2D, texture); Glu.Build2DMipmap(TextureTarget.Texture2D, (int)PixelInternalFormat.Rgba, (int)image.Size.X, (int)image.Size.Y, PixelFormat.Rgba, PixelType.UnsignedByte, image.Pixels); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); } // Enable Z-buffer read and write GL.Enable(EnableCap.DepthTest); GL.DepthMask(true); GL.ClearDepth(1); // Disable lighting GL.Disable(EnableCap.Lighting); // Configure the viewport (the same size as the window) GL.Viewport(0, 0, (int)window.Size.X, (int)window.Size.Y); // Setup a perspective projection GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity(); float ratio = (float)(window.Size.X) / window.Size.Y; GL.Frustum(-ratio, ratio, -1, 1, 1, 500); // Enable 2D Textures GL.Enable(EnableCap.Texture2D); // Define a 3D cube (6 faces made of 2 triangles composed by 3 vertices) float[] cube = new float[] { // positions // texture coordinates -20, -20, -20, 0, 0, -20, 20, -20, 1, 0, -20, -20, 20, 0, 1, -20, -20, 20, 0, 1, -20, 20, -20, 1, 0, -20, 20, 20, 1, 1, 20, -20, -20, 0, 0, 20, 20, -20, 1, 0, 20, -20, 20, 0, 1, 20, -20, 20, 0, 1, 20, 20, -20, 1, 0, 20, 20, 20, 1, 1, -20, -20, -20, 0, 0, 20, -20, -20, 1, 0, -20, -20, 20, 0, 1, -20, -20, 20, 0, 1, 20, -20, -20, 1, 0, 20, -20, 20, 1, 1, -20, 20, -20, 0, 0, 20, 20, -20, 1, 0, -20, 20, 20, 0, 1, -20, 20, 20, 0, 1, 20, 20, -20, 1, 0, 20, 20, 20, 1, 1, -20, -20, -20, 0, 0, 20, -20, -20, 1, 0, -20, 20, -20, 0, 1, -20, 20, -20, 0, 1, 20, -20, -20, 1, 0, 20, 20, -20, 1, 1, -20, -20, 20, 0, 0, 20, -20, 20, 1, 0, -20, 20, 20, 0, 1, -20, 20, 20, 0, 1, 20, -20, 20, 1, 0, 20, 20, 20, 1, 1 }; // Enable position and texture coordinates vertex components GL.EnableClientState(EnableCap.VertexArray); GL.EnableClientState(EnableCap.TextureCoordArray); GL.VertexPointer(3, VertexPointerType.Float, 5 * sizeof(float), Marshal.UnsafeAddrOfPinnedArrayElement(cube, 0)); GL.TexCoordPointer(2, TexCoordPointerType.Float, 5 * sizeof(float), Marshal.UnsafeAddrOfPinnedArrayElement(cube, 3)); // Disable normal and color vertex components GL.DisableClientState(EnableCap.NormalArray); GL.DisableClientState(EnableCap.ColorArray); Clock clock = new Clock(); // Start game loop while (window.IsOpen) { // Process events window.DispatchEvents(); // Clear the window window.Clear(); // Draw background window.PushGLStates(); window.Draw(background); window.PopGLStates(); // Clear the depth buffer GL.Clear(ClearBufferMask.DepthBufferBit); // We get the position of the mouse cursor, so that we can move the box accordingly float x = Mouse.GetPosition(window).X * 200.0F / window.Size.X - 100.0F; float y = -Mouse.GetPosition(window).Y * 200.0F / window.Size.Y + 100.0F; // Apply some transformations GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity(); GL.Translate(x, y, -100.0F); GL.Rotate(clock.ElapsedTime.AsSeconds() * 50, 1.0F, 0.0F, 0.0F); GL.Rotate(clock.ElapsedTime.AsSeconds() * 30, 0.0F, 1.0F, 0.0F); GL.Rotate(clock.ElapsedTime.AsSeconds() * 90, 0.0F, 0.0F, 1.0F); // Bind the texture GL.BindTexture(TextureTarget.Texture2D, texture); // Draw the cube GL.DrawArrays(BeginMode.Triangles, 0, 36); // Draw some text on top of our OpenGL object window.PushGLStates(); window.Draw(text); window.PopGLStates(); // Finally, display the rendered frame on screen window.Display(); } // Don't forget to destroy our texture GL.DeleteTextures(1, ref texture); }