示例#1
0
文件: Panel3D.cs 项目: zparr/ATF
 /// <summary>
 /// Makes this panel's OpenGL context current</summary>
 protected void SetCurrentContext()
 {
     if (!Wgl.wglMakeCurrent(m_hdc, m_hglrc))
     {
         Util3D.ReportErrors();
         throw new InvalidOperationException("Can't make this panel's GL context to be current");
     }
 }
示例#2
0
        /// <summary>
        /// Ends drawing the canvas contents</summary>
        protected override void EndPaint()
        {
            if (m_isPicking)
            {
                Util3D.DrawHatchedFrame(Size, FirstMousePoint, CurrentMousePoint, Color.Black);
            }

            base.EndPaint();
        }
示例#3
0
文件: Panel3D.cs 项目: zparr/ATF
 /// <summary>
 /// Begins painting</summary>
 /// <exception cref="InvalidOperationException">Can't make this panel's GL context to be current</exception>
 protected virtual void BeginPaint()
 {
     StartGlIfNecessary();
     if (!Wgl.wglMakeCurrent(m_hdc, m_hglrc))
     {
         Util3D.ReportErrors();
         throw new InvalidOperationException("Can't make this panel's GL context to be current");
     }
 }
示例#4
0
        /// <summary>
        /// Draws a 3D arrow from point 1 to point 2 using an OpenGL display list for greatly improved
        /// performance. This method must not be called in between Gl.glNewList and Gl.glEndList.</summary>
        /// <param name="p1">Point 1</param>
        /// <param name="p2">Point 2</param>
        /// <param name="coneSize">Arrow head base diameter</param>
        public static void DrawArrowDisplayList(Vec3F p1, Vec3F p2, float coneSize)
        {
            Gl.glBegin(Gl.GL_LINES);
            Gl.glVertex3f(p1.X, p1.Y, p1.Z);
            Gl.glVertex3f(p2.X, p2.Y, p2.Z);
            Gl.glEnd();

            Gl.glPushMatrix();
            Gl.glTranslatef(p2.X, p2.Y, p2.Z);
            Gl.glPushMatrix();
            Util3D.glMultMatrixf(LookAtMatrix(p2 - p1));
            DrawConeDisplayList(coneSize, coneSize * 2, RenderStyle.Solid);
            Gl.glPopMatrix();
            Gl.glPopMatrix();
            Util3D.RenderStats.VertexCount += 2;
        }
        /// <summary>
        /// Destroys all texture bindings for the given context</summary>
        /// <param name="contextId">Context ID of textures to destroy</param>
        public void DestroyTextures(object contextId)
        {
            TextureContext texCollection = FindContext(contextId);

            if (texCollection != null)
            {
                if (texCollection.Names.Count > 0)
                {
                    int[] texs = new int[texCollection.Names.Count];
                    texCollection.Names.CopyTo(texs, 0);
                    Gl.glDeleteTextures(texs.Length, texs);
                    Util3D.ReportErrors();
                }

                m_texCollections.Remove(texCollection);
            }
        }
示例#6
0
        /// <summary>
        /// Initializes an OpenGL context with the associated Win32 device context</summary>
        /// <param name="hdc">HDC from the window to which the new OpenGL context is bound</param>
        /// <param name="hglrc">Handle to the new OpenGL context</param>
        public static void InitOpenGl(IntPtr hdc, out IntPtr hglrc)
        {
            Gdi.PIXELFORMATDESCRIPTOR pfd = new Gdi.PIXELFORMATDESCRIPTOR();
            PopulatePixelFormatDescriptor(ref pfd);

            // Attempt To Find An Appropriate Pixel Format
            int pixelFormat = Gdi.ChoosePixelFormat(hdc, ref pfd);

            if (pixelFormat == 0)
            {
                throw new InvalidOperationException("Can't find a suitable PixelFormat");
            }

            // Attempt To Set The Pixel Format?
            if (!Gdi.SetPixelFormat(hdc, pixelFormat, ref pfd))
            {
                throw new InvalidOperationException("Can't set the PixelFormat");
            }

            // Attempt To Get The Rendering Context
            hglrc = Wgl.wglCreateContext(hdc);
            if (hglrc == IntPtr.Zero)
            {
                throw new InvalidOperationException("Can't create GL rendering context");
            }

            if (s_sharedHglrc == IntPtr.Zero)
            {
                s_sharedHglrc = hglrc;
            }
            else
            {
                // We don't throw an exception on failure because the caller may be on another thread or is
                //  using a different pixel format.
                Wgl.wglShareLists(s_sharedHglrc, hglrc);
            }

            if (!Wgl.wglMakeCurrent(hdc, hglrc))
            {
                throw new InvalidOperationException("Can't make the OpenGL rendering context to be the current context.");
            }

            // Load all extensions for mainline rendering
            if (!s_initialized)
            {
                LoadAllExtensions();
                s_initialized = true;
            }

            // Init fonts
            Gdi.SelectObject(hdc, SystemFonts.DefaultFont.ToHfont());
            foreach (IntSet.Range range in s_fontMap.Ranges)
            {
                int baseDisplayListId = range.PreviousItemsCount + TEXT_DISPLAY_LIST_BASE;

                if (!wglUseFontBitmaps(hdc, range.Min, range.Count, (uint)baseDisplayListId))
                {
                    throw new InvalidOperationException("Font bitmaps were unable to be created.");
                }
            }
            s_fontMap.Lock();

            Util3D.ReportErrors();
        }
        /// <summary>
        /// Loads a compressed texture using a call to glCompressedTexImage2DARB() as CUBE_MAP</summary>
        /// <param name="image">The Image</param>
        /// <param name="levels">Mipmap levels</param>
        private unsafe void CompressedTextureLoadPixelDataCUBEMAP(Image image, int levels)
        {
            IntPtr glCompressedTexImage2DARB =
                Gl.GetFunctionPointerForExtensionMethod("glCompressedTexImage2DARB");

            if (glCompressedTexImage2DARB == IntPtr.Zero)
            {
                return;
            }

            int nBlockSize;

            if (image.OpenGlPixelFormat == Gl.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
            {
                nBlockSize = 8;
            }
            else
            {
                nBlockSize = 16;
            }

            int offset = 0;

            // Load the mip-map levels
            for (int face = 0; face < 6; face++)
            {
                int nWidth  = image.Width;
                int nHeight = image.Height;
                for (int i = 0; i < levels; ++i)
                {
                    if (nWidth == 0)
                    {
                        nWidth = 1;
                    }
                    if (nHeight == 0)
                    {
                        nHeight = 1;
                    }

                    //                    nSize = ((nWidth + 3) / 4) * ((nHeight + 3) / 4) * nBlockSize;
                    int nSize = ((nWidth + 3) >> 2) * ((nHeight + 3) >> 2) * nBlockSize;

                    byte[] pixel = new byte[nSize];
                    for (int o = offset, j = 0; o < offset + nSize; o++, j++)
                    {
                        pixel[j] = image.Pixels[o];
                    }
                    Gl.glCompressedTexImage2DARB(
                        Gl.GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
                        i,
                        image.OpenGlPixelFormat,
                        nWidth,
                        nHeight,
                        0,
                        nSize,
                        pixel);

                    offset += nSize;

                    // Half the image size for the next mip-map level...
                    nWidth  = (nWidth >> 1);
                    nHeight = (nHeight >> 1);
                }
            }
            Util3D.ReportErrors();
        }
        private unsafe void CompressedTextureLoadPixelData(Image image, int levels)
        {
            IntPtr glCompressedTexImage2DARB =
                Gl.GetFunctionPointerForExtensionMethod("glCompressedTexImage2DARB");

            if (glCompressedTexImage2DARB == IntPtr.Zero)
            {
                return;
            }

            int nBlockSize;

            if (image.OpenGlPixelFormat == Gl.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
            {
                nBlockSize = 8;
            }
            else
            {
                nBlockSize = 16;
            }

            int nWidth  = image.Width;
            int nHeight = image.Height;
            int nSize;
            int nOffset = 0;

            // Load the mip-map levels
            fixed(byte *pixels = image.Pixels)
            {
                for (int i = 0; i < levels; ++i)
                {
                    if (nWidth == 0)
                    {
                        nWidth = 1;
                    }
                    if (nHeight == 0)
                    {
                        nHeight = 1;
                    }

                    nSize = ((nWidth + 3) / 4) * ((nHeight + 3) / 4) * nBlockSize;

                    Gl.glCompressedTexImage2DARB(
                        Gl.GL_TEXTURE_2D,
                        i,
                        image.OpenGlPixelFormat,
                        nWidth,
                        nHeight,
                        0,
                        nSize,
                        new IntPtr(pixels + nOffset));

                    nOffset += nSize;

                    // Half the image size for the next mip-map level...
                    nWidth  = (nWidth / 2);
                    nHeight = (nHeight / 2);
                }
            }

            Util3D.ReportErrors();
        }
        private int TryCreateOpenGlTextureFromImage(Image image, TextureInfo textureInfo)
        {
            textureInfo.Format     = image.OpenGlPixelFormat;
            textureInfo.Width      = image.Width;
            textureInfo.Height     = image.Height;
            textureInfo.Components = image.ElementsPerPixel;

            // Relax pixel data alignment restrictions down from 4 to 1
            Gl.glPixelStorei(Gl.GL_UNPACK_ALIGNMENT, 1);

            int textureName;

            Gl.glGenTextures(1, out textureName);

            if (image.IsCubeMap)
            {
                Gl.glEnable(Gl.GL_TEXTURE_CUBE_MAP);
                Gl.glBindTexture(Gl.GL_TEXTURE_CUBE_MAP, textureName);
                // Initialize bound texture state
                Gl.glTexParameteri(Gl.GL_TEXTURE_CUBE_MAP, Gl.GL_TEXTURE_WRAP_R, Gl.GL_CLAMP_TO_EDGE);
                Gl.glTexParameteri(Gl.GL_TEXTURE_CUBE_MAP, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP_TO_EDGE);
                Gl.glTexParameteri(Gl.GL_TEXTURE_CUBE_MAP, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP_TO_EDGE);
                Gl.glTexParameteri(Gl.GL_TEXTURE_CUBE_MAP, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR_MIPMAP_LINEAR);
                Gl.glTexParameteri(Gl.GL_TEXTURE_CUBE_MAP, Gl.GL_TEXTURE_MAX_LEVEL, image.Levels - 1);
                textureInfo.EnableFlipImage = false;
            }
            else
            {
                Gl.glBindTexture(Gl.GL_TEXTURE_2D, textureName);
                // Initialize bound texture state
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_REPEAT);
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_REPEAT);
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
            }

            // If EnableFlipImage, we want to flip the image up side down
            if (textureInfo.EnableFlipImage)
            {
                int    pixel_size = image.Pixels.Length;
                byte[] new_pixels = new byte[pixel_size];
                for (int i = 0; i < image.Height; i++)
                {
                    int source_i_offset = (image.Height - i - 1) * image.Width * image.ElementsPerPixel;
                    int destin_i_offset = (i) * image.Width * image.ElementsPerPixel;
                    for (int j = 0; j < image.Width; j++)
                    {
                        int j_offset = j * image.ElementsPerPixel;
                        for (int k = 0; k < image.ElementsPerPixel; k++)
                        {
                            new_pixels[destin_i_offset + j_offset + k] = image.Pixels[source_i_offset + j_offset + k];
                        }
                    }
                }
                image.Pixels = new_pixels;
            }

            if ((image.PixelFormat == PixelFormat.DXT1) ||
                (image.PixelFormat == PixelFormat.DXT3) ||
                (image.PixelFormat == PixelFormat.DXT5))
            {
                int levels = image.Levels;
                if ((levels > 1) && CompressedTextureContainsAllMipmaps(image))
                {
                    Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST_MIPMAP_LINEAR);
                }
                else
                {
                    levels = 1;
                    Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
                }

                if (image.IsCubeMap)
                {
                    CompressedTextureLoadPixelDataCUBEMAP(image, image.Levels);
                }
                else
                {
                    CompressedTextureLoadPixelData(image, levels);
                }
            }
            else
            {
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST_MIPMAP_LINEAR);
                Glu.gluBuild2DMipmaps(
                    Gl.GL_TEXTURE_2D,
                    image.ElementsPerPixel,
                    image.Width,
                    image.Height,
                    image.OpenGlPixelFormat,
                    Gl.GL_UNSIGNED_BYTE,
                    image.Pixels);
            }
            Util3D.ReportErrors();
            return(textureName);
        }