mandragora's picture

GLControl refresh ...

Hi All,

I'm having a strange behaviour refreshing using glControl.

I've one button that fires some calculations and create a texture witch is used within the paint method linked to the paint event of the control.

here is the code:

 
void glControl2_Paint(object sender, PaintEventArgs e)
        {
            if (!glControl2.Context.IsCurrent)
            {
                glControl2.MakeCurrent();
            }
            GL.Clear(ClearBufferMask.ColorBufferBit);
 
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();
 
            GL.BindTexture(TextureTarget.Texture2D, processedImage);
 
            GL.Begin(BeginMode.Quads);
 
            GL.TexCoord2(0.0f, 1.0f); GL.Vertex2(-1.0f, -1.0f); //LowerLeft Corner
            GL.TexCoord2(1.0f, 1.0f); GL.Vertex2(1.0f, -1.0f);  //LowerRight Corner
            GL.TexCoord2(1.0f, 0.0f); GL.Vertex2(1.0f, 1.0f);   //UpperRight Corner
            GL.TexCoord2(0.0f, 0.0f); GL.Vertex2(-1.0f, 1.0f);  //UpperLeft Corner
 
            GL.End();
            glControl2.SwapBuffers();
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            processedImage = ProcessData(bmp);
            glControl2.Refresh();
        }

It's working, is refreshing the control but ... only after the second click on the button.
Any idea on what could be?

Thanks in advance to everybody!

Have a nice day and weekend

Ben


Comments

Comment viewing options

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

Nobody had my same issue?

what I'm doing wrong?

Please help me.

Thanks a lot

Ben

Hortus Longus's picture

An idea, perhaps. What happens if you use glControl2.Invalidate instead glControl2.Refresh?

mandragora's picture

Hi Hortus,

thanks a lot for your reply, however it doesn't work, the behavior is the same.
Just after two clicks on the button I'll see the image in the glControl

Any Ideas? What I'm doing wrong?

Thanks again to everybody

Ben

Hortus Longus's picture

Are you sure, your processedImage is "ready to paint" when you call it?
Make a test: two textures, finished in memory, bind them alternating, are they shown ready?

mr_ST's picture

Try to insert following code after GL.End()

GL.Finish();

mandragora's picture

Hi,

and thanks to everybody for the replies.
Unfortunately I've tried with ready textures and with the GL.Finish() command but it doesn't work.

I've managed make it work by modifying button1_click method in this way :

 
private void button1_Click(object sender, EventArgs e)
        {
            if (!glControl2.Context.IsCurrent)
            {
                glControl2.MakeCurrent();
            }
            processedImage = ProcessData(bmp);
            glControl2.Refresh();
 
        }

but I'm not entirely sure that this is correct, I was sure that the Context check was necessary only in the control paint method.

Any clue on what I'm missing?

Thanks in advance

Ben

mr_ST's picture

Hmm, looks like you call Open GL functions(s) in ProcessData method.

>>but I'm not entirely sure that this is correct, I was sure that the Context check was necessary only in the control paint method.
AFAIR you must check the context whenever the OpenGL function called.

mandragora's picture

Hi mr_ST,

you're right I'm using OpenGL call within the process data method

here is the code:

int ProcessData(Bitmap bmp)
        {
            int id = GL.GenTexture();
 
            GL.Enable(EnableCap.Texture2D);
 
            GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Nicest);
            GL.BindTexture(TextureTarget.Texture2D, id);
            Bitmap image = new Bitmap(bmp);
            floatImage = BitmapToGrayFloat(bmp);
 
            // =====================================  Place here the OpenCL calls !!! ===================================
 
            //float[] filter = GaussKernel(0.5f, 1.5f);
            float[] filter = {-1,0,1,
                              -1,0,1,
                              -1,0,1};
            int filtSize = (int)System.Math.Round(filter.Length / 2.0) - 1;
            floatImage = gpuCalc.ImageConvolve(floatImage, filter, image.Width, image.Height, filtSize);
 
            // ==========================================================================================================
 
 
            image = FlatImageToBitmap(floatImage, bmp.Width, bmp.Height);
            BitmapData bmp_data = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp_data.Width, bmp_data.Height, 0,
                         OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bmp_data.Scan0);
 
            image.UnlockBits(bmp_data);
            image.Dispose();
 
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
 
            return id;
        }

what I'm doing wrong?

Thanks a lot for all the answers, but I'm pretty new to OpenGl

Thanks again

Ben

mr_ST's picture

In short words... If your method contains OpenGL function call and called not from OnPaint, just add to its method

if (!glControl2.Context.IsCurrent)
{
         glControl2.MakeCurrent();
}

you must check context is current before using OpenGL functions.

mandragora's picture

Hi mr_ST,

thanks a lot for the answer!

Ben