dwmkerr / sharpgl

Use OpenGL in .NET applications. SharpGL wraps all modern OpenGL features and offers a powerful scene graph to aid development.
MIT License
753 stars 300 forks source link

Hemisphere #150

Closed istvankovacs-priv closed 5 years ago

istvankovacs-priv commented 5 years ago

Hey Guys,

This isn't an issue, this is more like a question. I use your library in my project where I need to make a half sphere. I managed to find a method to successfully create the geometry but I have problems with the appearance of it. If I put it next to an original quadric, like a sphere or a cylinder, you can clearly see the difference. So I would like to ask you where should I start to look for the solution? What could cause the color difference between the shapes when they have the same material? At the beginning I thought it is caused by material, but I experimented with a lot lately and now I think it is related to the shaders, which unfortunatelly an unfamiliar place for me. Thank your for your reply!

EDIT: it's about the normal generation, but still don't know where to start

Regards, Steve

P.S.: thank you for your amazing library, it's really easy and handy to use

snip

Here you can see the half sphere on top and bottom, and there is an original cylinder between them.

This is how I make the geometry. I added a new func to SharpGL's OpenGL class. Other things are the same as the original sphere, but I call this in my half sphere's render function.

`public void HalfSphere(IntPtr qobj, double radius, int slices, int stacks, bool istop) { PreGLCall();

        int scalex = 50;
        int scaley = 50;

        float[,] v = new float[2 * scalex * scaley, 3];

        if (istop)
        {
            for (int i = 0; i < scalex; i++)
            {
                for (int j = 0; j < scaley; j++)
                {
                    v[i * scaley + j, 0] = (float)(radius * Math.Cos(j * 2 * Math.PI / scaley) * Math.Cos(i * Math.PI / (2 * scalex)));
                    v[i * scaley + j, 2] = (float)(radius * Math.Sin(i * Math.PI / (2 * scalex)));
                    v[i * scaley + j, 1] = (float)(radius * Math.Sin(j * 2 * Math.PI / scaley) * Math.Cos(i * Math.PI / (2 * scalex)));
                }
            }
        }
        else
        {
            for (int i = 0; i < scalex; i++)
            {
                for (int j = 0; j < scaley; j++)
                {
                    v[i * scaley + j, 0] = (float)(radius * Math.Cos(j * 2 * Math.PI / scaley) * Math.Cos(i * Math.PI / (2 * scalex)));
                    v[i * scaley + j, 2] = (-1) * ((float)(radius * Math.Sin(i * Math.PI / (2 * scalex))));
                    v[i * scaley + j, 1] = (float)(radius * Math.Sin(j * 2 * Math.PI / scaley) * Math.Cos(i * Math.PI / (2 * scalex)));
                }
            }
        }

        glBegin(GL_QUADS);
            for (int i = 0; i < scalex; i++)
            {
                for (int j = 0; j < scaley; j++)
                {
                    glVertex3f(v[i * scaley + j, 0], v[i * scaley + j, 1], v[i * scaley + j, 2]);
                    glVertex3f(v[i * scaley + (j + 1) % scaley, 0], v[i * scaley + (j + 1) % scaley, 1], v[i * scaley + (j + 1) % scaley, 2]);
                    glVertex3f(v[(i + 1) * scaley + (j + 1) % scaley, 0], v[(i + 1) * scaley + (j + 1) % scaley, 1], v[(i + 1) * scaley + (j + 1) % scaley, 2]);
                    glVertex3f(v[(i + 1) * scaley + j, 0], v[(i + 1) * scaley + j, 1], v[(i + 1) * scaley + j, 2]);
                }
            }
        glEnd();

        PostGLCall();
    }`
istvankovacs-priv commented 5 years ago

The solution is to miss the custom calculations and utilize the regular sphere fuction of the opengl and use clipping the get desired half (or smaller piece, because you can apply multiple clips) of the sphere. Actually the correct name of this quadric is hemisphere not halfsphere as I called it before.