pooya's picture

Updating a big matrix

Hi
I am new in graphic programming. I am developing a 3D viewer. I have a matrix (640 X 480) and i want to show them as a point cloud. The problems is my application is too slow.

            base.OnRenderFrame(e);
            System.Drawing.Bitmap flag = new System.Drawing.Bitmap(640, 480);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
 
            Matrix4 modelview = Matrix4.LookAt(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY);
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadMatrix(ref cameraMatrix);
            GL.Rotate(rtri, 0.0f, 1.0f, 0.0f);
 
            short* point = (short*)depthMD.DepthMapPtr.ToPointer();
            GL.Begin(BeginMode.Points);
            float x = 0;
            float y = 0;
            float z = 0;
            int minDistance = -10;
            double scaleFactor = .0021;
            for (int i = 0; i < depthMD.YRes * depthMD.XRes; i += 1, point += 1)
            {
                short* value = point;
                GL.Color3(((float)(depthMD.YRes * depthMD.XRes - i) % depthMD.XRes) / 320, ((float)(depthMD.YRes * depthMD.XRes - i) / depthMD.YRes) / 240, ((float)*value) / 800);
                x = (float)((((depthMD.YRes * depthMD.XRes - i) % depthMD.XRes) - depthMD.XRes / 2) * (*value - 10) * 0.0021 * (depthMD.XRes / depthMD.YRes));
                y = (float)((((depthMD.YRes * depthMD.XRes - i) / depthMD.YRes) - depthMD.YRes / 2) * ((float)*value - 10) * 0.0021);
                z = (int)*value;
                GL.Vertex3(y / -200, x / -200, z / 500);
            }
            GL.End();
 
            SwapBuffers();

Using "For" is very time consuming. I was wondering if you let me know your ideas/clues ... :D
Thanks


Comments

Comment viewing options

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

You can get around two orders-of-magnitude speedup by switching from immediate mode to VertexBufferObject use.

pooya's picture

Actually my knowledge is very basic in 3D modeling, Would you let me know how can i do? which part of my code has been changed?

avc81's picture

declare a private member

private int _displaylistid = -1;

and use a display list

            base.OnRenderFrame(e);
            System.Drawing.Bitmap flag = new System.Drawing.Bitmap(640, 480);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
 
            Matrix4 modelview = Matrix4.LookAt(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY);
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadMatrix(ref cameraMatrix);
            GL.Rotate(rtri, 0.0f, 1.0f, 0.0f);
 
        if(_displaylistid !=  -1)
                GL.CallList(_displaylistid );
        else
        {
            _displaylistid = GL.GenLists(1);
            GL.NewList(_displaylistid, ListMode.CompileAndExecute);
 
            short* point = (short*)depthMD.DepthMapPtr.ToPointer();
            GL.Begin(BeginMode.Points);
            float x = 0;
            float y = 0;
            float z = 0;
            int minDistance = -10;
            double scaleFactor = .0021;
            for (int i = 0; i < depthMD.YRes * depthMD.XRes; i += 1, point += 1)
            {
                short* value = point;
                GL.Color3(((float)(depthMD.YRes * depthMD.XRes - i) % depthMD.XRes) / 320, ((float)(depthMD.YRes * depthMD.XRes - i) / depthMD.YRes) / 240, ((float)*value) / 800);
                x = (float)((((depthMD.YRes * depthMD.XRes - i) % depthMD.XRes) - depthMD.XRes / 2) * (*value - 10) * 0.0021 * (depthMD.XRes / depthMD.YRes));
                y = (float)((((depthMD.YRes * depthMD.XRes - i) / depthMD.YRes) - depthMD.YRes / 2) * ((float)*value - 10) * 0.0021);
                z = (int)*value;
                GL.Vertex3(y / -200, x / -200, z / 500);
            }
            GL.End();
            GL.EndList();
        }
 
avc81's picture

p.s. use this technique only if you're not updating your points frequently

pooya's picture

I get this point cloud from Kinect sensor and I want to show on screen, It should be render 30 fps. I know that this process is too time consuming.
I tried to convert this point cloud into a mesh (if I did, I could reduce number of vertex significantly) but i couldn't because i did not find an algorithm to convert it into a mesh model (this is the main problem on Windows platform that most of programmers prefer to work with MAC systems). I know in some cases which is using mesh model, they can reduce the number of points twenty times less than actual numbers. when I change BeginMode.Point to BeginMode.Triangle it makes a mesh model but it connects wrong points to reconstruct triangles (it connects each of point to other points in the same plane)

avc81's picture

so go with vbos. drawing 640*480 points is nothing to worry about with a decent hardware

pooya's picture

Thanks
Do you know any example for understanding, how does it work?

avc81's picture

check "VBO Dynamic" in opentk 's examples

ebnf's picture

""BeginMode.Triangle it makes a mesh model but it connects wrong points to reconstruct triangles (it connects each of point to other points in the same plane)""

Triangle mode doesn't automatically convert a point-cloud surface into a triangle mesh, but treats each set of 3 points in the data as a triangle.

Since your data is coming from the Kinect you don't need a complex algorithm to convert to a mesh. You just need to connect all neighboring points into a triangle mesh the same as you would with the terrain heightmap demos using Kinect depth as the heightfield data.

pooya's picture

thanks sooo much, you are right!!! , because my matrix was not too big (640X480). if I create a mesh, i can reduce the number of points and cover the surface by my triangles.
I did it and result was awesome. Actually I could not use camera images to set as my model texture but I read pixels form image () and load on my triangles colors one by one.
Your approach was very easy to implement. how can i load frames as my model texture now? :D