예제 #1
0
        public Texture2D ParseImageProgram(string source, ref DateTime timeStamp, ref TextureDepth depth)
        {
            _lexer = new idLexer(LexerOptions.NoFatalErrors | LexerOptions.NoStringConcatination | LexerOptions.NoStringEscapeCharacters | LexerOptions.AllowPathNames);
            _lexer.LoadMemory(source, source);

            return(ParseImageProgram(ref timeStamp, ref depth, false));
        }
예제 #2
0
		public Texture2D ParseImageProgram(string source, ref DateTime timeStamp, ref TextureDepth depth)
		{
			_lexer = new idLexer(LexerOptions.NoFatalErrors | LexerOptions.NoStringConcatination | LexerOptions.NoStringEscapeCharacters | LexerOptions.AllowPathNames);
			_lexer.LoadMemory(source, source);

			return ParseImageProgram(ref timeStamp, ref depth, false);
		}
예제 #3
0
        public FrameBufferColor(int w, int h)
        {
            IW  = w;
            IH  = h;
            FBO = GL.GenFramebuffer( );
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, FBO);
            BB  = new Texture2D(w, h, false);
            DB  = new TextureDepth(w, h);
            DRB = GL.GenRenderbuffer( );
            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, DRB);
            GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.DepthComponent, w, h);
            GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, DRB);
            GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, BB.ID, 0);
            DrawBuffersEnum db = DrawBuffersEnum.ColorAttachment0;

            GL.DrawBuffers(1, ref db);
            if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete)
            {
                Console.WriteLine("Framebuffer failure.");
                while (true)
                {
                }
            }
            Console.WriteLine("Framebuffer success.");
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, 0);
        }
예제 #4
0
        public Texture2D ParseImageProgram(idLexer lexer)
        {
            _lexer = lexer;

            DateTime     timeStamp = DateTime.Now;;
            TextureDepth depth     = TextureDepth.Default;

            return(ParseImageProgram(ref timeStamp, ref depth, true));
        }
예제 #5
0
        // background loading information.

        /*private idImage _partialImage;			// shrunken, space-saving version
         * private bool _isPartialImage;			// true if this is pointed to by another image*/
        #endregion

        #region Constructor
        public idImage(string name, ImageLoadCallback generator)
        {
            _name      = name;
            _generator = generator;
            _type      = TextureType.Disabled;

            _filter    = TextureFilter.Default;
            _repeat    = TextureRepeat.Repeat;
            _depth     = TextureDepth.Default;
            _cubeFiles = CubeFiles.TwoD;
        }
예제 #6
0
        public idImage(string name, TextureType type, TextureFilter filter, TextureRepeat repeat, TextureDepth depth, CubeFiles cubeMap, bool allowDownSize)
        {
            _name = name;
            _type = type;

            _filter        = filter;
            _repeat        = repeat;
            _depth         = depth;
            _cubeFiles     = cubeMap;
            _allowDownSize = allowDownSize;
        }
 public void Dispose()
 {
     fixed(uint *FrameBufferPtr = &FrameBufferId)
     {
         GL.glDeleteFramebuffers(1, FrameBufferPtr);
         if ((RenderTargetLayers & RenderTargetLayers.Color) != 0)
         {
             TextureColor.Dispose();
         }
         if ((RenderTargetLayers & RenderTargetLayers.Depth) != 0)
         {
             TextureDepth.Dispose();
         }
         if ((RenderTargetLayers & RenderTargetLayers.Stencil) != 0)
         {
             RenderBufferStencil.Dispose();
         }
     }
 }
예제 #8
0
        public FrameBufferColorMRT(int num, int w, int h, TextureFormat format = TextureFormat.Normal)
        {
            IW  = w;
            IH  = h;
            FBO = GL.GenFramebuffer();
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, FBO);
            for (int i = 0; i < num; i++)
            {
                Targets.Add(new Texture2D(w, h, false, format));
            }
            //BB = new Texture2D(w, h, false, format);
            DB = new TextureDepth(w, h);

            DRB = GL.GenRenderbuffer();
            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, DRB);
            GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.DepthComponent, w, h);
            GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, DRB);
            DrawBuffersEnum[] drawb = new DrawBuffersEnum[num];
            for (int i = 0; i < num; i++)
            {
                FramebufferAttachment fa = FramebufferAttachment.ColorAttachment0;
                switch (i)
                {
                case 0:
                    fa       = FramebufferAttachment.ColorAttachment0;
                    drawb[0] = DrawBuffersEnum.ColorAttachment0;
                    break;

                case 1:
                    fa       = FramebufferAttachment.ColorAttachment1;
                    drawb[1] = DrawBuffersEnum.ColorAttachment1;
                    break;

                case 2:
                    fa       = FramebufferAttachment.ColorAttachment2;
                    drawb[2] = DrawBuffersEnum.ColorAttachment2;
                    break;

                case 3:
                    fa       = FramebufferAttachment.ColorAttachment3;
                    drawb[3] = DrawBuffersEnum.ColorAttachment3;
                    break;

                case 4:
                    fa       = FramebufferAttachment.ColorAttachment4;
                    drawb[4] = DrawBuffersEnum.ColorAttachment4;
                    break;

                case 5:
                    fa       = FramebufferAttachment.ColorAttachment5;
                    drawb[5] = DrawBuffersEnum.ColorAttachment5;
                    break;

                case 6:
                    fa       = FramebufferAttachment.ColorAttachment6;
                    drawb[6] = DrawBuffersEnum.ColorAttachment6;
                    break;

                case 7:
                    fa       = FramebufferAttachment.ColorAttachment7;
                    drawb[7] = DrawBuffersEnum.ColorAttachment7;
                    break;
                }

                GL.FramebufferTexture(FramebufferTarget.Framebuffer, fa, Targets[i].ID, 0);
            }

            //  DrawBuffersEnum db = DrawBuffersEnum.ColorAttachment0;

            GL.DrawBuffers(drawb.Length, drawb);

            if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete)
            {
                Console.WriteLine("Framebuffer failure.");
            }
            Console.WriteLine("Framebuffer success.");
            GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
            GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, 0);
        }
예제 #9
0
		public Texture2D LoadImageProgram(string name, ref DateTime timeStamp, ref TextureDepth depth)
		{
			return ParseImageProgram(name, ref timeStamp, ref depth);
		}
예제 #10
0
		/// <summary>
		/// Finds or loads the given image, always returning a valid image pointer.
		/// Loading of the image may be deferred for dynamic loading.
		/// </summary>
		/// <param name="name"></param>
		/// <param name="filter"></param>
		/// <param name="allowDownSize"></param>
		/// <param name="repeat"></param>
		/// <param name="depth"></param>
		/// <param name="cubeMap"></param>
		/// <returns></returns>
		public idImage ImageFromFile(string name, TextureFilter filter, bool allowDownSize, TextureRepeat repeat, TextureDepth depth, CubeFiles cubeMap)
		{
			if((name == null) || (name == string.Empty)
				|| (name.Equals("default", StringComparison.OrdinalIgnoreCase) == true)
				|| (name.Equals("_default", StringComparison.OrdinalIgnoreCase) == true))
			{
				idE.DeclManager.MediaPrint("DEFAULTED");

				return this.DefaultImage;
			}

			idImage image;

			// strip any .tga file extensions from anywhere in the _name, including image program parameters
			name = name.Replace(".tga", "");

			//
			// see if the image is already loaded, unless we
			// are in a reloadImages call
			//
			if(_imageDictionary.TryGetValue(name, out image) == true)
			{
				// the built in's, like _white and _flat always match the other options
				if(name.StartsWith("_") == true)
				{
					return image;
				}

				if(image.CubeFiles != cubeMap)
				{
					idConsole.Error("Image '{0}' has been referenced with conflicting cube map states", name);
				}

				if((image.Filter != filter) || (image.Repeat != repeat))
				{
					// we might want to have the system reset these parameters on every bind and
					// share the image data	

					// FIXME: this might be the wrong behaviour.  original d3 would return a new image but our dictionary
					// requires unique keys.
					return image;
				}
				else
				{
					if((image.AllowDownSize == allowDownSize) && (image.Depth == depth))
					{
						// note that it is used this level load
						image.LevelLoadReferenced = true;

						return image;
					}

					// the same image is being requested, but with a different allowDownSize or depth
					// so pick the highest of the two and reload the old image with those parameters
					if(image.AllowDownSize == false)
					{
						allowDownSize = false;
					}

					if(image.Depth > depth)
					{
						depth = image.Depth;
					}

					if((image.AllowDownSize == allowDownSize) && (image.Depth == depth))
					{
						// the already created one is already the highest quality
						image.LevelLoadReferenced = true;

						return image;
					}

					/*image.AllowDownSize = allowDownSize;
					image.Depth = depth;*/
					image.LevelLoadReferenced = true;


					if((idE.CvarSystem.GetBool("image_preload") == true) && (_insideLevelLoad == false))
					{
						image.ReferencedOutsideLevelLoad = true;
						image.ActuallyLoadImage(true, false); // check for precompressed, load is from front end

						idE.DeclManager.MediaPrint("{0}x{1} {1} (reload for mixed referneces)", image.Width, image.Height, image.Name);
					}

					return image;
				}
			}

			// HACK: to allow keep fonts from being mip'd, as new ones will be introduced with localization
			// this keeps us from having to make a material for each font tga
			if(name.Contains("fontImage_") == true)
			{
				allowDownSize = false;
			}

			//
			// create a new image
			//
			image = CreateImage(name, TextureType.TwoD, filter, repeat, depth, cubeMap, allowDownSize);
			image.LevelLoadReferenced = true;

			// load it if we aren't in a level preload
			if((idE.CvarSystem.GetBool("image_preload") == true) && (_insideLevelLoad == false))
			{
				image.ReferencedOutsideLevelLoad = true;
				image.ActuallyLoadImage(true, false); // check for precompressed, load is from front end

				idE.DeclManager.MediaPrint("{0}x{1} {2}", image.Width, image.Height, image.Name);
			}
			else
			{
				idE.DeclManager.MediaPrint(image.Name);
			}

			return image;
		}
예제 #11
0
		/// <summary>
		/// Finds or loads the given image, always returning a valid image pointer.
		/// Loading of the image may be deferred for dynamic loading.
		/// </summary>
		/// <param name="name"></param>
		/// <param name="filter"></param>
		/// <param name="allowDownSize"></param>
		/// <param name="repeat"></param>
		/// <param name="depth"></param>
		/// <returns></returns>
		public idImage ImageFromFile(string name, TextureFilter filter, bool allowDownSize, TextureRepeat repeat, TextureDepth depth)
		{
			return ImageFromFile(name, filter, allowDownSize, repeat, depth, CubeFiles.TwoD);
		}
예제 #12
0
		private idImage CreateImage(string name, TextureType type, TextureFilter filter, TextureRepeat repeat, TextureDepth depth, CubeFiles cubeMap, bool allowDownSize)
		{
			idImage image = new idImage(name, type, filter, repeat, depth, cubeMap, allowDownSize);

			_images.Add(image);
			_imageDictionary.Add(name, image);

			return image;
		}
예제 #13
0
		/// <summary>
		/// If data is NULL, the timestamps will be filled in, but no image will be generated
		/// If both data and timeStamp are NULL, it will just advance past it, which can be
		/// used to parse an image program from a text stream.
		/// </summary>
		/// <param name="source"></param>
		/// <param name="timeStamp"></param>
		/// <param name="depth"></param>
		/// <returns></returns>
		public Texture2D ParseImageProgram(string source, ref DateTime timeStamp, ref TextureDepth depth)
		{
			return new idImageProgramParser().ParseImageProgram(source, ref timeStamp, ref depth);
		}
예제 #14
0
        /// <summary>
        /// Used by callback functions to specify the actual data
        /// data goes from the bottom to the top line of the image, as OpenGL expects it
        /// These perform an implicit Bind() on the current texture unit.
        /// </summary>
        /// <remarks>
        /// The alpha channel bytes should be 255 if you don't want the channel.
        /// We need a material characteristic to ask for specific texture modes.
        /// Designed limitations of flexibility:
        /// No support for texture borders.
        /// No support for texture border color.
        /// No support for texture environment colors or GL_BLEND or GL_DECAL
        /// texture environments, because the automatic optimization to single
        /// or dual component textures makes those modes potentially undefined.
        /// No non-power-of-two images.
        /// No palettized textures.
        /// There is no way to specify separate wrap/clamp values for S and T.
        /// There is no way to specify explicit mip map levels.
        /// </remarks>
        /// <param name="data"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="filter"></param>
        /// <param name="allowDownSize"></param>
        /// <param name="repeat"></param>
        /// <param name="depth"></param>
        public void Generate(byte[] data, int width, int height, TextureFilter filter, bool allowDownSize, TextureRepeat repeat, TextureDepth depth)
        {
            if (this.Disposed == true)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            // FIXME: should we implement cinematics this way, instead of with explicit calls?

            /*Purge();
             *
             * _filter = filter;
             * _allowDownSize = allowDownSize;
             * _repeat = repeat;
             * _depth = depth;*/

            idConsole.Warning("TODO: generate");

            // if we don't have a rendering context, just return after we
            // have filled in the parms.  We must have the values set, or
            // an image match from a shader before OpenGL starts would miss
            // the generated texture
            if (idE.RenderSystem.IsRunning == false)
            {
                return;
            }

            // don't let mip mapping smear the texture into the clamped border

            /*bool preserveBorder = (_repeat == TextureRepeat.ClampToZero);
             *
             * // make sure it is a power of 2
             * int scaledWidth = idHelper.MakePowerOfTwo(width);
             * int scaledHeight = idHelper.MakePowerOfTwo(height);
             *
             * if((scaledWidth != width) || (scaledHeight != height))
             * {
             *      idConsole.Error("Image.Generate: not a power of 2 image.");
             * }
             *
             * // Optionally modify our width/height based on options/hardware
             * GetDownSize(ref scaledWidth, ref scaledHeight);
             *
             * byte[] scaledBuffer = null;
             * /*idE.RenderSystem.CheckOpenGLErrors();
             * uint[] tex = new uint[1];
             * //Gl.glGenTextures(1, tex);
             * _texNumber = (int) tex[0];
             * idE.RenderSystem.CheckOpenGLErrors();*/
            /*_loaded = true;
             *
             * // select proper internal format before we resample
             * _internalFormat = Gl.GL_RGB8;  // SelectInternalFormat(data, 1, width, height, depth, out _isMonochrome);
             *
             * // copy or resample data as appropriate for first MIP level.
             * if((scaledWidth == width) && (scaledHeight == height))
             * {
             *      // we must copy even if unchanged, because the border zeroing
             *      // would otherwise modify const data
             *      scaledBuffer = data;
             * }
             * else
             * {
             *      idConsole.Warning("TODO: DONT SUPPORT MIMAP RIGHT NOW");
             *
             *      // resample down as needed (FIXME: this doesn't seem like it resamples anymore!)
             *      // scaledBuffer = R_ResampleTexture( pic, width, height, width >>= 1, height >>= 1 );
             *      /*scaledBuffer = R_MipMap( pic, width, height, preserveBorder );
             *      width >>= 1;
             *      height >>= 1;
             *      if ( width < 1 ) {
             *              width = 1;
             *      }
             *      if ( height < 1 ) {
             *              height = 1;
             *      }
             *
             *      while ( width > scaled_width || height > scaled_height ) {
             *              shrunk = R_MipMap( scaledBuffer, width, height, preserveBorder );
             *              R_StaticFree( scaledBuffer );
             *              scaledBuffer = shrunk;
             *
             *              width >>= 1;
             *              height >>= 1;
             *              if ( width < 1 ) {
             *                      width = 1;
             *              }
             *              if ( height < 1 ) {
             *                      height = 1;
             *              }
             *      }
             *
             *      // one might have shrunk down below the target size
             *      scaled_width = width;
             *      scaled_height = height;*/
            /*}*/

            /*_uploadWidth = scaledWidth;
             * _uploadHeight = scaledHeight;
             * _type = TextureType.TwoD;
             *
             * // zero the border if desired, allowing clamped projection textures
             * // even after picmip resampling or careless artists.
             * if(repeat == TextureRepeat.ClampToZero)
             * {
             *      byte[] rgba = new byte[4] { 0, 0, 0, 255 };
             *      SetBorderTexels(scaledBuffer, width, height, rgba);
             * }
             * else if(repeat == TextureRepeat.ClampToZeroAlpha)
             * {
             *      byte[] rgba = new byte[4] { 255, 255, 255, 0 };
             *      SetBorderTexels(scaledBuffer, width, height, rgba);
             * }*/

            /*if((_generator == null) && ((_depth == TextureDepth.Bump) && (idE.CvarSystem.GetBool("image_writeNormalTGA") == true) || (_depth != TextureDepth.Bump) && (idE.CvarSystem.GetBool("image_writeTGA") == true)))
             * {
             *      idConsole.Warning("TODO: gen = null && bump && write");
             *      // Optionally write out the texture to a .tga
             *      /*char filename[MAX_IMAGE_NAME];
             *      ImageProgramStringToCompressedFileName( imgName, filename );
             *      char *ext = strrchr(filename, '.');
             *      if ( ext ) {
             *              strcpy( ext, ".tga" );
             *              // swap the red/alpha for the write
             *              /*
             *              if ( depth == TD_BUMP ) {
             *                      for ( int i = 0; i < scaled_width * scaled_height * 4; i += 4 ) {
             *                              scaledBuffer[ i ] = scaledBuffer[ i + 3 ];
             *                              scaledBuffer[ i + 3 ] = 0;
             *                      }
             *              }
             */
            // TODO: R_WriteTGA( filename, scaledBuffer, scaled_width, scaled_height, false );

            // put it back

            /*
             * if ( depth == TD_BUMP ) {
             *      for ( int i = 0; i < scaled_width * scaled_height * 4; i += 4 ) {
             *              scaledBuffer[ i + 3 ] = scaledBuffer[ i ];
             *              scaledBuffer[ i ] = 0;
             *      }
             * }
             */
            /*}*/
            /*	}*/

            // swap the red and alpha for rxgb support
            // do this even on tga normal maps so we only have to use
            // one fragment program.
            // if the image is precompressed (either in palletized mode or true rxgb mode)
            // then it is loaded above and the swap never happens here.

            /*if((depth == TextureDepth.Bump) && (idE.CvarSystem.GetInteger("image_useNormalCompression") != 1))
             * {
             *      for(int i = 0; i < scaledWidth * scaledHeight * 4; i += 4)
             *      {
             *              scaledBuffer[i + 3] = scaledBuffer[i];
             *              scaledBuffer[i] = 0;
             *      }
             * }
             *
             * // upload the main image level
             * Bind();
             *
             * if(_internalFormat == Gl.GL_COLOR_INDEX8_EXT)
             * {
             *      idConsole.Warning("TODO: UploadCompressedNormalMap( scaled_width, scaled_height, scaledBuffer, 0 );");
             * }
             * else
             * {
             *      //Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, _internalFormat, scaledWidth, scaledHeight, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, scaledBuffer);
             * }
             *
             * // create and upload the mip map levels, which we do in all cases, even if we don't think they are needed
             * /*int miplevel = 0;
             * // TODO: remove this if not needed
             * while((scaledWidth > 1) || (scaledHeight > 1))
             * {
             *      // preserve the border after mip map unless repeating
             *      scaledBuffer = MipMap(scaledBuffer, scaledWidth, scaledHeight, preserveBorder);
             *      scaledWidth >>= 1;
             *      scaledHeight >>= 1;
             *
             *      if(scaledWidth < 1)
             *      {
             *              scaledWidth = 1;
             *      }
             *
             *      if(scaledHeight < 1)
             *      {
             *              scaledHeight = 1;
             *      }
             *
             *      miplevel++;
             *
             *      // this is a visualization tool that shades each mip map
             *      // level with a different color so you can see the
             *      // rasterizer's texture level selection algorithm
             *      // Changing the color doesn't help with lumminance/alpha/intensity formats...
             *      // TODO
             *      /*if ( depth == TD_DIFFUSE && globalImages->image_colorMipLevels.GetBool() ) {
             *              R_BlendOverTexture( (byte *)scaledBuffer, scaled_width * scaled_height, mipBlendColors[miplevel] );
             *      }*/

            // upload the mip map

            /*if(_internalFormat == Gl.GL_COLOR_INDEX8_EXT)
             * {
             *      idConsole.Warning("TODO: UploadCompressedNormalMap( scaled_width, scaled_height, scaledBuffer, miplevel );");
             * }
             * else
             * {
             *      //Gl.glTexImage2D(Gl.GL_TEXTURE_2D, miplevel, _internalFormat, scaledWidth, scaledHeight, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, scaledBuffer);
             * }
             * }*/

            //SetImageFilterAndRepeat();
        }
예제 #15
0
        private Texture2D ParseImageProgram(ref DateTime timeStamp, ref TextureDepth depth, bool parseOnly)
        {
            idToken token = _lexer.ReadToken();

            AppendToken(token);

            string tokenLower = token.ToString().ToLower();

            if (tokenLower == "heightmap")
            {
                MatchAndAppendToken(_lexer, "(");

                Texture2D tex = ParseImageProgram(_lexer, ref timeStamp, ref depth);

                if (tex == null)
                {
                    return(null);
                }

                MatchAndAppendToken(_lexer, ",");
                token = _lexer.ReadToken();
                AppendToken(token);

                float scale = token.ToFloat();

                // process it
                if (tex != null)
                {
                    idConsole.Warning("TODO: R_HeightmapToNormalMap( *pic, *width, *height, scale );");
                    depth = TextureDepth.Bump;
                }

                MatchAndAppendToken(_lexer, ")");

                return(tex);
            }
            else if (tokenLower == "addnormals")
            {
                MatchAndAppendToken(_lexer, "(");

                /*byte	*pic2;
                 * int		width2, height2;*/

                Texture2D tex, tex2;

                if ((tex = ParseImageProgram(_lexer, ref timeStamp, ref depth)) == null)
                {
                    return(null);
                }

                MatchAndAppendToken(_lexer, ",");

                if ((tex2 = ParseImageProgram(_lexer, ref timeStamp, ref depth)) == null)
                {
                    tex.Dispose();

                    idConsole.Warning("TODO: content doesn't get unloaded, this texture will remain disposed for ever!");

                    return(null);
                }

                // process it
                if (tex != null)
                {
                    // TODO: tex2.Dispose();
                    idConsole.Warning("TODO: content doesn't get unloaded, this texture will remain disposed for ever!");

                    depth = TextureDepth.Bump;
                    idConsole.Warning("TODO: R_AddNormalMaps( *pic, *width, *height, pic2, width2, height2 );");
                }

                MatchAndAppendToken(_lexer, ")");

                return(tex);
            }
            else if (tokenLower == "smoothnormals")
            {
                idConsole.WriteLine("image program smoothnormals");

                /*MatchAndAppendToken( src, "(" );
                 *
                 * if ( !R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ) ) {
                 *      return false;
                 * }
                 *
                 * if ( pic ) {
                 *      R_SmoothNormalMap( *pic, *width, *height );
                 *      if ( depth ) {
                 * depth = TD_BUMP;
                 *      }
                 * }
                 *
                 * MatchAndAppendToken( src, ")" );
                 * return true;*/
                return(null);
            }
            else if (tokenLower == "add")
            {
                idConsole.WriteLine("image program add");

                /*byte	*pic2;
                 * int		width2, height2;
                 *
                 * MatchAndAppendToken( src, "(" );
                 *
                 * if ( !R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ) ) {
                 *      return false;
                 * }
                 *
                 * MatchAndAppendToken( src, "," );
                 *
                 * if ( !R_ParseImageProgram_r( src, pic ? &pic2 : NULL, &width2, &height2, timestamps, depth ) ) {
                 *      if ( pic ) {
                 *              R_StaticFree( *pic );
                 * pic = NULL;
                 *      }
                 *      return false;
                 * }
                 *
                 * // process it
                 * if ( pic ) {
                 *      R_ImageAdd( *pic, *width, *height, pic2, width2, height2 );
                 *      R_StaticFree( pic2 );
                 * }
                 *
                 * MatchAndAppendToken( src, ")" );
                 * return true;*/

                return(null);
            }
            else if (tokenLower == "scale")
            {
                idConsole.WriteLine("image program scale");

                /*float	scale[4];
                 * int		i;
                 *
                 * MatchAndAppendToken( src, "(" );
                 *
                 * R_ParseImageProgram_r( src, pic, width, height, timestamps, depth );
                 *
                 * for ( i = 0 ; i < 4 ; i++ ) {
                 *      MatchAndAppendToken( src, "," );
                 *      src.ReadToken( &token );
                 *      AppendToken( token );
                 *      scale[i] = token.GetFloatValue();
                 * }
                 *
                 * // process it
                 * if ( pic ) {
                 *      R_ImageScale( *pic, *width, *height, scale );
                 * }
                 *
                 * MatchAndAppendToken( src, ")" );
                 * return true;*/

                return(null);
            }
            else if (tokenLower == "invertalpha")
            {
                idConsole.WriteLine("image program invertalpha");

                /*MatchAndAppendToken( src, "(" );
                 *
                 * R_ParseImageProgram_r( src, pic, width, height, timestamps, depth );
                 *
                 * // process it
                 * if ( pic ) {
                 *      R_InvertAlpha( *pic, *width, *height );
                 * }
                 *
                 * MatchAndAppendToken( src, ")" );
                 * return true;*/

                return(null);
            }
            else if (tokenLower == "invertcolor")
            {
                idConsole.WriteLine("image program invertcolor");

                /*MatchAndAppendToken( src, "(" );
                 *
                 * R_ParseImageProgram_r( src, pic, width, height, timestamps, depth );
                 *
                 * // process it
                 * if ( pic ) {
                 *      R_InvertColor( *pic, *width, *height );
                 * }
                 *
                 * MatchAndAppendToken( src, ")" );
                 * return true;*/

                return(null);
            }
            else if (tokenLower == "makeintensity")
            {
                MatchAndAppendToken(_lexer, "(");
                Texture2D t = ParseImageProgram(ref timeStamp, ref depth, parseOnly);

                idConsole.Warning("TODO: makeintensity");

                /*if(parseOnly == false)
                 * {
                 *      // copy red to green, blue, and alpha
                 *      int c = width * height * 4;
                 *
                 *      for(int i = 0; i < c; i += 4)
                 *      {
                 *              data[i + 1] = data[i + 2] = data[i + 3] = data[i];
                 *      }
                 * }*/

                MatchAndAppendToken(_lexer, ")");

                return(t);
            }
            else if (tokenLower == "makealpha")
            {
                MatchAndAppendToken(_lexer, "(");

                Texture2D tex = ParseImageProgram(_lexer, ref timeStamp, ref depth);

                // average RGB into alpha, then set RGB to white
                if (tex != null)
                {
                    idConsole.Warning("TODO: average alpha image");

                    /*int		c;
                     * c = *width * *height * 4;
                     * for ( i = 0 ; i < c ; i+=4 ) {
                     *      (*pic)[i+3] = ( (*pic)[i+0] + (*pic)[i+1] + (*pic)[i+2] ) / 3;
                     *      (*pic)[i+0] =
                     *      (*pic)[i+1] =
                     *      (*pic)[i+2] = 255;
                     * }*/
                }

                MatchAndAppendToken(_lexer, ")");

                return(tex);
            }

            // if we are just parsing instead of loading or checking, don't do the R_LoadImage
            if (parseOnly == true)
            {
                return(null);
            }

            // load it as an image
            return(idE.ImageManager.LoadImage(token.ToString(), ref timeStamp, true));
        }
예제 #16
0
        public Texture2D ParseImageProgram(idLexer lexer, ref DateTime timeStamp, ref TextureDepth depth)
        {
            _lexer = lexer;

            return(ParseImageProgram(ref timeStamp, ref depth, false));
        }
예제 #17
0
		private Texture2D ParseImageProgram(ref DateTime timeStamp, ref TextureDepth depth, bool parseOnly)
		{
			idToken token = _lexer.ReadToken();			
			AppendToken(token);
			
			string tokenLower = token.ToString().ToLower();
		
			if(tokenLower == "heightmap")
			{
				MatchAndAppendToken(_lexer, "(");

				Texture2D tex = ParseImageProgram(_lexer, ref timeStamp, ref depth);

				if(tex == null)
				{
					return null;
				}

				MatchAndAppendToken(_lexer, ",");
				token = _lexer.ReadToken();
				AppendToken(token);

				float scale = token.ToFloat();
		
				// process it
				if(tex != null)
				{
					idConsole.Warning("TODO: R_HeightmapToNormalMap( *pic, *width, *height, scale );");
					depth = TextureDepth.Bump;
				}
		
				MatchAndAppendToken(_lexer, ")");

				return tex;
			}
			else if(tokenLower == "addnormals")
			{
				MatchAndAppendToken(_lexer, "(");

				/*byte	*pic2;
				int		width2, height2;*/

				Texture2D tex, tex2;
				
				if((tex = ParseImageProgram(_lexer, ref timeStamp, ref depth)) == null)
				{
					return null;
				}

				MatchAndAppendToken(_lexer, ",");

				if((tex2 = ParseImageProgram(_lexer, ref timeStamp, ref depth)) == null)
				{
					tex.Dispose();

					idConsole.Warning("TODO: content doesn't get unloaded, this texture will remain disposed for ever!");

					return null;
				}
		
				// process it
				if(tex != null)
				{

					// TODO: tex2.Dispose();
					idConsole.Warning("TODO: content doesn't get unloaded, this texture will remain disposed for ever!");

					depth = TextureDepth.Bump;
					idConsole.Warning("TODO: R_AddNormalMaps( *pic, *width, *height, pic2, width2, height2 );");
				}

				MatchAndAppendToken(_lexer, ")");

				return tex;
			}
			else if(tokenLower == "smoothnormals")
			{
				idConsole.WriteLine("image program smoothnormals");
				/*MatchAndAppendToken( src, "(" );

				if ( !R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ) ) {
					return false;
				}

				if ( pic ) {
					R_SmoothNormalMap( *pic, *width, *height );
					if ( depth ) {
						*depth = TD_BUMP;
					}
				}

				MatchAndAppendToken( src, ")" );
				return true;*/
				return null;
			}
			else if(tokenLower == "add")
			{
				idConsole.WriteLine("image program add");

				/*byte	*pic2;
				int		width2, height2;

				MatchAndAppendToken( src, "(" );

				if ( !R_ParseImageProgram_r( src, pic, width, height, timestamps, depth ) ) {
					return false;
				}

				MatchAndAppendToken( src, "," );

				if ( !R_ParseImageProgram_r( src, pic ? &pic2 : NULL, &width2, &height2, timestamps, depth ) ) {
					if ( pic ) {
						R_StaticFree( *pic );
						*pic = NULL;
					}
					return false;
				}
		
				// process it
				if ( pic ) {
					R_ImageAdd( *pic, *width, *height, pic2, width2, height2 );
					R_StaticFree( pic2 );
				}

				MatchAndAppendToken( src, ")" );
				return true;*/

				return null;
			}
			else if(tokenLower == "scale")
			{
				idConsole.WriteLine("image program scale");
				/*float	scale[4];
				int		i;

				MatchAndAppendToken( src, "(" );

				R_ParseImageProgram_r( src, pic, width, height, timestamps, depth );

				for ( i = 0 ; i < 4 ; i++ ) {
					MatchAndAppendToken( src, "," );
					src.ReadToken( &token );
					AppendToken( token );
					scale[i] = token.GetFloatValue();
				}

				// process it
				if ( pic ) {
					R_ImageScale( *pic, *width, *height, scale );
				}

				MatchAndAppendToken( src, ")" );
				return true;*/

				return null;
			}
			else if(tokenLower == "invertalpha")
			{
				idConsole.WriteLine("image program invertalpha");
				/*MatchAndAppendToken( src, "(" );

				R_ParseImageProgram_r( src, pic, width, height, timestamps, depth );

				// process it
				if ( pic ) {
					R_InvertAlpha( *pic, *width, *height );
				}

				MatchAndAppendToken( src, ")" );
				return true;*/

				return null;
			}
			else if(tokenLower == "invertcolor")
			{
				idConsole.WriteLine("image program invertcolor");

				/*MatchAndAppendToken( src, "(" );

				R_ParseImageProgram_r( src, pic, width, height, timestamps, depth );

				// process it
				if ( pic ) {
					R_InvertColor( *pic, *width, *height );
				}

				MatchAndAppendToken( src, ")" );
				return true;*/

				return null;
			}
			else if(tokenLower == "makeintensity")
			{
				MatchAndAppendToken(_lexer, "(");
				Texture2D t = ParseImageProgram(ref timeStamp, ref depth, parseOnly);

				idConsole.Warning("TODO: makeintensity");
				/*if(parseOnly == false)
				{
					// copy red to green, blue, and alpha			
					int c = width * height * 4;

					for(int i = 0; i < c; i += 4)
					{
						data[i + 1] = data[i + 2] = data[i + 3] = data[i];
					}
				}*/

				MatchAndAppendToken(_lexer, ")");

				return t;
			}
			else if(tokenLower == "makealpha")
			{
				MatchAndAppendToken(_lexer, "(");

				Texture2D tex = ParseImageProgram(_lexer, ref timeStamp, ref depth);

				// average RGB into alpha, then set RGB to white
				if(tex != null)
				{
					idConsole.Warning("TODO: average alpha image");

					/*int		c;
					c = *width * *height * 4;
					for ( i = 0 ; i < c ; i+=4 ) {
						(*pic)[i+3] = ( (*pic)[i+0] + (*pic)[i+1] + (*pic)[i+2] ) / 3;
						(*pic)[i+0] = 
						(*pic)[i+1] = 
						(*pic)[i+2] = 255;
					}*/
				}

				MatchAndAppendToken(_lexer, ")");

				return tex;
			}

			// if we are just parsing instead of loading or checking, don't do the R_LoadImage
			if(parseOnly == true)
			{
				return null;
			}

			// load it as an image
			return idE.ImageManager.LoadImage(token.ToString(), ref timeStamp, true);
		}
예제 #18
0
		// background loading information.
		/*private idImage _partialImage;			// shrunken, space-saving version
		private bool _isPartialImage;			// true if this is pointed to by another image*/
		#endregion

		#region Constructor
		public idImage(string name, ImageLoadCallback generator)
		{
			_name = name;
			_generator = generator;
			_type = TextureType.Disabled;

			_filter = TextureFilter.Default;
			_repeat = TextureRepeat.Repeat;
			_depth = TextureDepth.Default;
			_cubeFiles = CubeFiles.TwoD;
		}
예제 #19
0
		public Texture2D ParseImageProgram(idLexer lexer, ref DateTime timeStamp, ref TextureDepth depth)
		{
			_lexer = lexer;

			return ParseImageProgram(ref timeStamp, ref depth, false);
		}
예제 #20
0
		/// <summary>
		/// Used by callback functions to specify the actual data
		/// data goes from the bottom to the top line of the image, as OpenGL expects it
		/// These perform an implicit Bind() on the current texture unit.
		/// </summary>
		/// <remarks>
		/// The alpha channel bytes should be 255 if you don't want the channel.
		/// We need a material characteristic to ask for specific texture modes.
		/// Designed limitations of flexibility:
		/// No support for texture borders.
		/// No support for texture border color.
		/// No support for texture environment colors or GL_BLEND or GL_DECAL
		/// texture environments, because the automatic optimization to single
		/// or dual component textures makes those modes potentially undefined.
		/// No non-power-of-two images.
		/// No palettized textures.
		/// There is no way to specify separate wrap/clamp values for S and T.
		/// There is no way to specify explicit mip map levels.
		/// </remarks>
		/// <param name="data"></param>
		/// <param name="width"></param>
		/// <param name="height"></param>
		/// <param name="filter"></param>
		/// <param name="allowDownSize"></param>
		/// <param name="repeat"></param>
		/// <param name="depth"></param>
		public void Generate(byte[] data, int width, int height, TextureFilter filter, bool allowDownSize, TextureRepeat repeat, TextureDepth depth)
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException(this.GetType().Name);
			}

			// FIXME: should we implement cinematics this way, instead of with explicit calls?
			/*Purge();

			_filter = filter;
			_allowDownSize = allowDownSize;
			_repeat = repeat;
			_depth = depth;*/

			idConsole.Warning("TODO: generate");

			// if we don't have a rendering context, just return after we
			// have filled in the parms.  We must have the values set, or
			// an image match from a shader before OpenGL starts would miss
			// the generated texture
			if(idE.RenderSystem.IsRunning == false)
			{
				return;
			}

			// don't let mip mapping smear the texture into the clamped border
			/*bool preserveBorder = (_repeat == TextureRepeat.ClampToZero);

			// make sure it is a power of 2
			int scaledWidth = idHelper.MakePowerOfTwo(width);
			int scaledHeight = idHelper.MakePowerOfTwo(height);

			if((scaledWidth != width) || (scaledHeight != height))
			{
				idConsole.Error("Image.Generate: not a power of 2 image.");
			}

			// Optionally modify our width/height based on options/hardware			
			GetDownSize(ref scaledWidth, ref scaledHeight);

			byte[] scaledBuffer = null;
			/*idE.RenderSystem.CheckOpenGLErrors();
			uint[] tex = new uint[1];
			//Gl.glGenTextures(1, tex);
			_texNumber = (int) tex[0];
			idE.RenderSystem.CheckOpenGLErrors();*/
			/*_loaded = true;

			// select proper internal format before we resample
			_internalFormat = Gl.GL_RGB8;  // SelectInternalFormat(data, 1, width, height, depth, out _isMonochrome);

			// copy or resample data as appropriate for first MIP level.
			if((scaledWidth == width) && (scaledHeight == height))
			{
				// we must copy even if unchanged, because the border zeroing
				// would otherwise modify const data
				scaledBuffer = data;
			}
			else
			{
				idConsole.Warning("TODO: DONT SUPPORT MIMAP RIGHT NOW");

				// resample down as needed (FIXME: this doesn't seem like it resamples anymore!)
				// scaledBuffer = R_ResampleTexture( pic, width, height, width >>= 1, height >>= 1 );
				/*scaledBuffer = R_MipMap( pic, width, height, preserveBorder );
				width >>= 1;
				height >>= 1;
				if ( width < 1 ) {
					width = 1;
				}
				if ( height < 1 ) {
					height = 1;
				}

				while ( width > scaled_width || height > scaled_height ) {
					shrunk = R_MipMap( scaledBuffer, width, height, preserveBorder );
					R_StaticFree( scaledBuffer );
					scaledBuffer = shrunk;

					width >>= 1;
					height >>= 1;
					if ( width < 1 ) {
						width = 1;
					}
					if ( height < 1 ) {
						height = 1;
					}
				}

				// one might have shrunk down below the target size
				scaled_width = width;
				scaled_height = height;*/
			/*}*/

			/*_uploadWidth = scaledWidth;
			_uploadHeight = scaledHeight;
			_type = TextureType.TwoD;

			// zero the border if desired, allowing clamped projection textures
			// even after picmip resampling or careless artists.
			if(repeat == TextureRepeat.ClampToZero)
			{
				byte[] rgba = new byte[4] { 0, 0, 0, 255 };
				SetBorderTexels(scaledBuffer, width, height, rgba);
			}
			else if(repeat == TextureRepeat.ClampToZeroAlpha)
			{
				byte[] rgba = new byte[4] { 255, 255, 255, 0 };
				SetBorderTexels(scaledBuffer, width, height, rgba);
			}*/

			/*if((_generator == null) && ((_depth == TextureDepth.Bump) && (idE.CvarSystem.GetBool("image_writeNormalTGA") == true) || (_depth != TextureDepth.Bump) && (idE.CvarSystem.GetBool("image_writeTGA") == true)))
			{
				idConsole.Warning("TODO: gen = null && bump && write");
				// Optionally write out the texture to a .tga
				/*char filename[MAX_IMAGE_NAME];
				ImageProgramStringToCompressedFileName( imgName, filename );
				char *ext = strrchr(filename, '.');
				if ( ext ) {
					strcpy( ext, ".tga" );
					// swap the red/alpha for the write
					/*
					if ( depth == TD_BUMP ) {
						for ( int i = 0; i < scaled_width * scaled_height * 4; i += 4 ) {
							scaledBuffer[ i ] = scaledBuffer[ i + 3 ];
							scaledBuffer[ i + 3 ] = 0;
						}
					}
					*/
				// TODO: R_WriteTGA( filename, scaledBuffer, scaled_width, scaled_height, false );

				// put it back
				/*
				if ( depth == TD_BUMP ) {
					for ( int i = 0; i < scaled_width * scaled_height * 4; i += 4 ) {
						scaledBuffer[ i + 3 ] = scaledBuffer[ i ];
						scaledBuffer[ i ] = 0;
					}
				}
				*/
				/*}*/
		/*	}*/

			// swap the red and alpha for rxgb support
			// do this even on tga normal maps so we only have to use
			// one fragment program.
			// if the image is precompressed (either in palletized mode or true rxgb mode)
			// then it is loaded above and the swap never happens here.
			/*if((depth == TextureDepth.Bump) && (idE.CvarSystem.GetInteger("image_useNormalCompression") != 1))
			{
				for(int i = 0; i < scaledWidth * scaledHeight * 4; i += 4)
				{
					scaledBuffer[i + 3] = scaledBuffer[i];
					scaledBuffer[i] = 0;
				}
			}

			// upload the main image level
			Bind();

			if(_internalFormat == Gl.GL_COLOR_INDEX8_EXT)
			{
				idConsole.Warning("TODO: UploadCompressedNormalMap( scaled_width, scaled_height, scaledBuffer, 0 );");
			}
			else
			{
				//Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, _internalFormat, scaledWidth, scaledHeight, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, scaledBuffer);
			}

			// create and upload the mip map levels, which we do in all cases, even if we don't think they are needed
			/*int miplevel = 0;
			// TODO: remove this if not needed
			while((scaledWidth > 1) || (scaledHeight > 1))
			{
				// preserve the border after mip map unless repeating
				scaledBuffer = MipMap(scaledBuffer, scaledWidth, scaledHeight, preserveBorder);
				scaledWidth >>= 1;
				scaledHeight >>= 1;

				if(scaledWidth < 1)
				{
					scaledWidth = 1;
				}

				if(scaledHeight < 1)
				{
					scaledHeight = 1;
				}

				miplevel++;

				// this is a visualization tool that shades each mip map
				// level with a different color so you can see the
				// rasterizer's texture level selection algorithm
				// Changing the color doesn't help with lumminance/alpha/intensity formats...
				// TODO
				/*if ( depth == TD_DIFFUSE && globalImages->image_colorMipLevels.GetBool() ) {
					R_BlendOverTexture( (byte *)scaledBuffer, scaled_width * scaled_height, mipBlendColors[miplevel] );
				}*/

			// upload the mip map
			/*if(_internalFormat == Gl.GL_COLOR_INDEX8_EXT)
			{
				idConsole.Warning("TODO: UploadCompressedNormalMap( scaled_width, scaled_height, scaledBuffer, miplevel );");
			}
			else
			{
				//Gl.glTexImage2D(Gl.GL_TEXTURE_2D, miplevel, _internalFormat, scaledWidth, scaledHeight, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, scaledBuffer);
			}
		}*/

			//SetImageFilterAndRepeat();
		}
예제 #21
0
		public idImage(string name, TextureType type, TextureFilter filter, TextureRepeat repeat, TextureDepth depth, CubeFiles cubeMap, bool allowDownSize)
		{
			_name = name;
			_type = type;

			_filter = filter;
			_repeat = repeat;
			_depth = depth;
			_cubeFiles = cubeMap;
			_allowDownSize = allowDownSize;
		}