SFML community forums

Bindings - other languages => DotNet => Topic started by: Raptor2277 on May 14, 2016, 11:17:50 pm

Title: OpenTK and SFML
Post by: Raptor2277 on May 14, 2016, 11:17:50 pm
Having a hard time getting sfml to work with opentk. I am creating an sfml window and trying to draw a 3d cube using opengl while using sfml's Text classes to draw text on top. However, on window.resize it bugs the program out. I am changing the model-view and setting the view-port, then it bugs the program where the cube is no longer being drawn. Also when I try to render Text, it is really buggy and flashy.

Am I doing something fundamentally wrong here?


using System;
using SFML.Window;
using SFML.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK;

namespace SFML.NET_2015
{
    class Program
    {
        static void Main(string[] args)
        {
            ContextSettings contextSettings = new ContextSettings(24, 0, 0);
            SFML.Graphics.RenderWindow win = new RenderWindow(new VideoMode(640, 400), "SFML.NET", Styles.Default, contextSettings);
            win.SetFramerateLimit(144);
            win.SetMouseCursorVisible(true);

            win.Closed += (o, e) => { win.Close(); };
            win.Resized += (o, e) =>
            {
                GL.Viewport(0, 0, (int)win.Size.X, (int)win.Size.Y);
                Matrix4 matr = OpenTK.Matrix4.CreatePerspectiveFieldOfView((float)Math.PI * 50f / 180f, win.Size.X / (float)win.Size.Y, .1f, 10f);
                GL.LoadMatrix(ref matr);
            };


            Toolkit.Init();
            OpenTK.Graphics.GraphicsMode graphicsMode = new OpenTK.Graphics.GraphicsMode(32, (int)contextSettings.DepthBits, (int)contextSettings.StencilBits, (int)contextSettings.AntialiasingLevel);
            OpenTK.Platform.IWindowInfo windowInfo = OpenTK.Platform.Utilities.CreateWindowsWindowInfo(win.SystemHandle);
            OpenTK.Graphics.GraphicsContext context = new OpenTK.Graphics.GraphicsContext(graphicsMode, windowInfo);
            context.MakeCurrent(windowInfo);
            context.LoadAll();

            GL.EnableClientState(ArrayCap.VertexArray);

            GL.MatrixMode(MatrixMode.Projection);
            Matrix4 mat = OpenTK.Matrix4.CreatePerspectiveFieldOfView((float)Math.PI * 50f / 180f, win.Size.X / (float)win.Size.Y, .1f, 10f);
            GL.LoadMatrix(ref mat);

            GL.MatrixMode(MatrixMode.Modelview);
            GL.Translate(0, 0, -4);

            #region Verts
            float[] verts =
            {
                -1.0f,-1.0f,-1.0f, // triangle 1 : begin
    -1.0f,-1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f, // triangle 1 : end
    1.0f, 1.0f,-1.0f, // triangle 2 : begin
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f,-1.0f, // triangle 2 : end
    1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,
    1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,
    1.0f,-1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f,-1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, 1.0f,-1.0f,
    -1.0f, 1.0f,-1.0f,
    1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f,
    1.0f,-1.0f, 1.0f
            };
            #endregion

            int buff = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.ArrayBuffer, buff);
            GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(verts.Length * sizeof(float)), verts, BufferUsageHint.StaticDraw);

            GL.VertexPointer(3, VertexPointerType.Float, 3 * sizeof(float), 0);

            Text t = new Text("Hello Cube", new Font("andyb.ttf"));
            t.Position = new System.Vector2f(200, 200);

            while (win.IsOpen)
            {
                win.DispatchEvents();

                GL.Rotate(.1f, 0, 1, 0);
                GL.DrawArrays(OpenTK.Graphics.OpenGL.PrimitiveType.Triangles, 0, verts.Length);
                GL.End();

                win.PushGLStates();
                win.Draw(t);
                win.PopGLStates();

                win.Display();
            }
        }
    }
}


 
Title: AW: OpenTK and SFML
Post by: eXpl0it3r on May 16, 2016, 12:14:41 pm
Are you sure you set the view correctly with OpenGL?
Title: Re: OpenTK and SFML
Post by: dabbertorres on May 16, 2016, 05:12:10 pm
You're forgetting to change MatrixMode to Projection in win.Resized. Right now, your Resized event is setting the View matrix.
Title: Re: OpenTK and SFML
Post by: Raptor2277 on May 16, 2016, 08:44:38 pm
 Thanks, the resizing works now. That's a dumb mistake by me. But trying to render the text now doesn't draw the  cube. I've tried resetting the model-view and projection on each draw, but that doesn't work either.
Title: Re: OpenTK and SFML
Post by: dabbertorres on May 16, 2016, 10:12:24 pm
I don't think you should be calling glEnd() at all. Especially since you don't even call glBegin() anywhere. glBegin() and glEnd() are for defining single vertices to draw together.

And I believe you need a call to glClear() before drawing anything (glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) usually suffices).
Title: Re: OpenTK and SFML
Post by: Raptor2277 on May 16, 2016, 11:43:58 pm
I've changed that, that was left over when I was doing immediate drawing. Calling GL.CLear() or window.clear() doesnt seem to make a difference.
Title: Re: OpenTK and SFML
Post by: Raptor2277 on May 16, 2016, 11:46:23 pm
Just do clarify, I draw the cube without trying to draw the text and it draws the cube fine, it rotates, all is good. But as soon as I do win.Draw(t); (drawing the text), the cube disappears.
Title: Re: OpenTK and SFML
Post by: dabbertorres on May 17, 2016, 06:17:24 am
Hmm. That sounds like states or matrices being changed... Oh. What happens if you add your
            GL.MatrixMode(MatrixMode.Modelview);
            GL.Translate(0, 0, -4);
before your GL.Rotate() in your while loop?

If that doesn't fix anything, can you post the current code?

(Sorry for the laggy responses, I only have time to check the forums between classes and work. :) )
Title: Re: OpenTK and SFML
Post by: Raptor2277 on May 18, 2016, 05:52:21 am
Here is the full code. Adding the -4 translation didn't do anything.


using System;
using SFML.Window;
using SFML.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK;

namespace SFML.NET_2015
{
    class Program
    {
        static void Main(string[] args)
        {
            ContextSettings contextSettings = new ContextSettings(24, 0, 0);
            SFML.Graphics.RenderWindow win = new RenderWindow(new VideoMode(640, 400), "SFML.NET", Styles.Default, contextSettings);
            win.SetFramerateLimit(144);
            win.SetMouseCursorVisible(true);

            win.Closed += (o, e) => { win.Close(); };
            win.Resized += (o, e) =>
            {
                GL.Viewport(0, 0, (int)win.Size.X, (int)win.Size.Y);
                GL.MatrixMode(MatrixMode.Projection);
                Matrix4 matr = OpenTK.Matrix4.CreatePerspectiveFieldOfView((float)Math.PI * 50f / 180f, win.Size.X / (float)win.Size.Y, .1f, 10f);
                GL.LoadMatrix(ref matr);
            };


            Toolkit.Init();
            OpenTK.Graphics.GraphicsMode graphicsMode = new OpenTK.Graphics.GraphicsMode(32, (int)contextSettings.DepthBits, (int)contextSettings.StencilBits, (int)contextSettings.AntialiasingLevel);
            OpenTK.Platform.IWindowInfo windowInfo = OpenTK.Platform.Utilities.CreateWindowsWindowInfo(win.SystemHandle);
            OpenTK.Graphics.GraphicsContext context = new OpenTK.Graphics.GraphicsContext(graphicsMode, windowInfo);
            context.MakeCurrent(windowInfo);
            context.LoadAll();

            GL.EnableClientState(ArrayCap.VertexArray);

            #region Verts
            float[] verts =
            {
                -1.0f,-1.0f,-1.0f, // triangle 1 : begin
    -1.0f,-1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f, // triangle 1 : end
    1.0f, 1.0f,-1.0f, // triangle 2 : begin
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f,-1.0f, // triangle 2 : end
    1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,
    1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,
    1.0f,-1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f,-1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, 1.0f,-1.0f,
    -1.0f, 1.0f,-1.0f,
    1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f,
    1.0f,-1.0f, 1.0f
            };
            #endregion

            int buff = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.ArrayBuffer, buff);
            GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(verts.Length * sizeof(float)), verts, BufferUsageHint.StaticDraw);
            GL.VertexPointer(3, VertexPointerType.Float, 3 * sizeof(float), 0);

            Text t = new Text("Hello Cube", new Font("andyb.ttf"));
            t.Position = new System.Vector2f(200, 000);

            while (win.IsOpen)
            {
                win.DispatchEvents();

                //win.Clear();
                GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

                //GL.Viewport(0, 0, (int)win.Size.X, (int)win.Size.Y);
                GL.MatrixMode(MatrixMode.Projection);
                Matrix4 matr = OpenTK.Matrix4.CreatePerspectiveFieldOfView((float)Math.PI * 50f / 180f, win.Size.X / (float)win.Size.Y, .1f, 10f);
                GL.LoadMatrix(ref matr);

                GL.MatrixMode(MatrixMode.Modelview);
                GL.LoadIdentity();
                GL.Translate(0, 0, -4);
                GL.Rotate(50f, 0, 1, 0);

                GL.DrawArrays(OpenTK.Graphics.OpenGL.PrimitiveType.Triangles, 0, verts.Length);

                win.PushGLStates();
                win.Draw(t);
                win.PopGLStates();

                win.Display();
            }
        }
    }
}


 
Title: Re: OpenTK and SFML
Post by: Raptor2277 on May 18, 2016, 05:53:34 am
Without the

                win.PushGLStates();
                win.Draw(t);
                win.PopGLStates();

 

It draws the cube, rotated so an edge faces the screen.
Title: Re: OpenTK and SFML
Post by: dabbertorres on May 18, 2016, 11:41:14 pm
Alright, I got it working over here.

(click to show/hide)

Two things:
You were having two contexts: one from SFML, and the one you created with OpenTK. Apparently, passing ContextHandle.Zero to the GraphicsContext constructor makes OpenTK find the already-existing context (from SFML in this case). A little nicer than manually doing so with a P/Invoke to wglGetCurrentContext (What I did in the first place!). I'm not certain if this was the issue (or part of it), but I could see it potentially causing complications in the future.

The part I am certain was at least part of the issue was coming from your cube's vertex buffer still being bound when SFML tries to draw. I haven't ever dug through enough of SFML's internals to know what it does that would make this an issue, but, in the future, make sure to unbind your buffers (pass 0 as the buffer id for glBindBuffer) before drawing with SFML (and can be a good thing to do anyways).

Beyond that, I think that was all I changed!

PS: You can also move your projection and view matrix code out of your while loop, and before it now, if you wish:
(click to show/hide)
Title: Re: OpenTK and SFML
Post by: Raptor2277 on May 19, 2016, 07:06:37 am
I get a an AccessViolcationException when I use


            Toolkit.Init();
            OpenTK.Graphics.GraphicsContext context = new OpenTK.Graphics.GraphicsContext(ContextHandle.Zero, OpenTK.Platform.Utilities.CreateWindowsWindowInfo(win.SystemHandle));
            context.LoadAll();

 


this is the exact error:
An unhandled exception of type 'System.AccessViolationException' occurred in OpenTK.dll

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

This issue is disused in http://en.sfml-dev.org/forums/index.php?topic=18276.0 (http://en.sfml-dev.org/forums/index.php?topic=18276.0) forum. This is the only way I found to solve that problem.
Title: Re: OpenTK and SFML
Post by: Raptor2277 on May 19, 2016, 07:11:21 am
I tried you code(pasted) and replaced you context creation with what I originally had. It shows the cube for a split second, then it goes away. I guess its the context creation that is messing me up. I just can't find much on why its giving me that error.
Title: Re: OpenTK and SFML
Post by: dabbertorres on May 19, 2016, 09:53:27 am
Well huh. Of course it wasn't that easy. Very odd that it seems to vary by computer too. Have you put a breakpoint on those lines? Can you determine which function call causes the issue? I'm wondering if it's a race condition. Or varies by graphics hardware/driver.

What graphics card and driver are you running this on?

Also, what OpenTK dlls are you using? I was testing with the dlls distributed with SFML.NET.
Title: Re: OpenTK and SFML
Post by: Raptor2277 on May 19, 2016, 06:47:40 pm
It crashes on the first(ish) GL.* call. Int his calse it was GL. Clear(), the other case I had was GL.TexImage2D. I have a GTX 970 with 365.19. I am also using the dlls handed by SFML.NET
Title: Re: OpenTK and SFML
Post by: dabbertorres on May 19, 2016, 10:31:46 pm
What about the last code I pasted above? (It doesn't call either of those functions.)

Hmm. I ran it on my work computer, which is just an intel graphics card.

I have a GTX 970 as well at home (can't remember driver version, prolly the latest), I'll see if I can repro it.
Title: Re: OpenTK and SFML
Post by: dabbertorres on May 20, 2016, 08:13:16 pm
I can reproduce it on my home machine (driver 365.10).

Investigating, it looks like I may be correct, seems it may be a race condition:
(click to show/hide)

NVIDIA's driver may potentially be doing some extra threading that interferes with both SFML and OpenTK using the context, that Intel's driver does not do.

Unfortunately, this is getting out of the realm of my knowledge, so I'm not really sure where to go from here.
Title: Re: OpenTK and SFML
Post by: Raptor2277 on May 21, 2016, 03:44:42 am
Welp, thanks for the help. Interesting issue we got here.