Fidchells_eye's picture

ABS newbie trying to get it to work

Fidchells_eye here again

I am converting an old C++ to C#
But before i can continue to do that I need the test render function DrawX() to draw an X on screen
But my setup function is failing, due to GL being NULL.

The structure of the project is;
BaseScope is inherited into any ToolScope Class.
The BaseScope class is used in the ModularScopeDisplay class so I can switch the tools as needed

The main does have a GLControl called GLDisplay1.

public class ModularScopeDisplay
{
#region Data
ScopeBase sBase;
#endregion
public ModularScopeDisplay(OpenTK.GLControl GL_Display, ScopeBase.ScopeMode mode)
{
if (mode == ScopeBase.ScopeMode.WFM)
{
sBase = new Scope_WFM(ref GL_Display);
}
//gl = GL_Display;
}
}

public abstract class ScopeBase
{
...
protected OpenTK.Graphics.OpenGL.GL gl;
...
}
public class Scope_WFM:ScopeBase
{
.....
}


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

OpenTK.Graphics.OpenGL.GL is a static class. You do not create references to it, you just call GL.SomeFunction() directly.

Fidchells_eye's picture

I get an error where GL static class is NULL

the Fiddler's picture

This is wrong:

GL gl;
gl.BindTexture(0); // NullReferenceException

This is correct:

GL.BindTexture(0);
Fidchells_eye's picture

the error is
"NULLreference exception was unhandled"

code

public virtual bool SetupProjection(int width, int height) //configures OpenGL camera properties
{
if (height == 0) // don't want a divide by zero
{
height = 1;
}
m_Zdelta = (float)((height/2)/(Math.Tan(FovY/2)));
// \/ zoom factor
//m_Zdelta = m_Zdelta * 2.45;
GL.Viewport(0, 0, width, height); // reset the viewport to new dimensions <------------------------Getting exception here
GL.MatrixMode(MatrixMode.Projection); // set projection matrix current matrix
GL.LoadIdentity(); // reset projection matrix
// calculate aspect ratio of window

Matrix4.CreatePerspectiveFieldOfView(FovY,(float)width/(float)height,200.0f,2000.0f);
GL.MatrixMode(MatrixMode.Modelview); // set modelview matrix
GL.LoadIdentity(); // reset modelview matrix
//load window dimensions into class memory
m_windowWidth = (float)width;
m_windowHeight = (float)height;
return true;
}

haplokuon's picture

The code you are showing seems ok. Probably the error is somewhere else.

If you try to call a GL function before you have initialized the opengl context you get that kind of exception. Check if you are calling that function inside a window resize event since, if I correctly remember, the resize event is called even before the window loaded event, the place where I usually initialize the opengl context.

What I usually do is create a bool variable to check if the context is initialized to avoid calling GL functions in this kind of situations.

Fidchells_eye's picture

Then how do you initialize the opengl context?
this code is not being executed in a resize event it is executed in the main form's constructor.
GLDisplay1 is a GLControl on the main form.

code

Scope_WFM scope;
public frmMain()
{
InitializeComponent();
scope = new Scope_WFM(ref this.GLDisplay1);

scope.SetupProjection(GLDisplay1.Size.Width, GLDisplay1.Size.Height);

scope.DrawX();

}

haplokuon's picture

The GLControl initializes the opengl context for you.

Make sure that your GLControl is properly initialized before calling any GL function. Move the code:

scope.SetupProjection(GLDisplay1.Size.Width, GLDisplay1.Size.Height);
scope.DrawX();

to your GLControl paint event. It does not look good to call draw calls inside the constructor everything that is needed might not be ready.

I am not sure and I might be wrong but the problem might be that there is no gl context active at that moment.

Fidchells_eye's picture

GLDisplay1.Size.Width, GLDisplay1.Size.Height give data (320 and 240)

I moved the
scope.SetupProjection(GLDisplay1.Size.Width, GLDisplay1.Size.Height);
scope.DrawX();
to a button and it got past the viewport thanks.
but it now stops at
Matrix4.CreatePerspectiveFieldOfView(FovY,(float)width/(float)height,200.0f,2000.0f); <-------------FovY = 52.0

error: argument out of range exception

haplokuon's picture
Matrix4.CreatePerspectiveFieldOfView(FovY,(float)width/(float)height,200.0f,2000.0f)

that function requires that the field of view in radians not in degrees (52 is a big number in radians) and is limited between 0 and PI.

Part of the internal code for Matrix4.CreatePerspectiveFieldOfView says:

if (fovy <= 0 || fovy > Math.PI)
     throw new ArgumentOutOfRangeException("fovy");
Fidchells_eye's picture

Thanks, that got it.

but it is not rendering, I get a white GL control.

Does the GL or GL control need an init to be called?

public override void DrawX() // a display test function
{
//setup GL_RENDERING
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); // clear screen and depth buffer
GL.LoadIdentity(); //load matrix identity // \/ zoom factor

Matrix4.LookAt((m_windowWidth / 2), (m_windowHeight / 2), (m_Zdelta * (2.70f + 0.00f)), //camera
(m_windowWidth / 2), (m_windowHeight / 2), (float)0.0, //view center
(float)0.0, (float)1.0, (float)0.0); //camera orientation
/*gluLookAt((m_windowWidth/2), (m_windowHeight/2), (m_Zdelta* (2.70f + 0.00f)), //camera
(m_windowWidth/2), (m_windowHeight/2), 0.0, //view center
0.0, 1.0, 0.0); //camera orientation*/

GL.Begin(BeginMode.Lines);
GL.Vertex3(0.0f, 0.0f, 0.0f);
GL.Vertex3((float)m_windowWidth, (float)m_windowHeight, 0.0f);
GL.Vertex3(0.0f, (float)m_windowHeight, 0.0f);
GL.Vertex3((float)m_windowWidth, 0.0f, 0.0f);
GL.End();
}