示例#1
0
        public void textureInit(byte[] imageData, string _name)
        {
            DDSImage ddsImage;

            name = _name;

            ddsImage = new DDSImage(imageData);
            RenderStats.texturesNum += 1; //Accumulate settings

            Console.WriteLine("Sampler Name Path " + name + " Width {0} Height {1}", ddsImage.header.dwWidth, ddsImage.header.dwHeight);
            width  = ddsImage.header.dwWidth;
            height = ddsImage.header.dwHeight;
            int blocksize = 16;

            switch (ddsImage.header.ddspf.dwFourCC)
            {
            //DXT1
            case (0x31545844):
                pif       = InternalFormat.CompressedSrgbAlphaS3tcDxt1Ext;
                blocksize = 8;
                break;

            case (0x35545844):
                pif = InternalFormat.CompressedSrgbAlphaS3tcDxt5Ext;
                break;

            case (0x32495441):                          //ATI2A2XY
                pif = InternalFormat.CompressedRgRgtc2; //Normal maps are probably never srgb
                break;

            //DXT10 HEADER
            case (0x30315844):
            {
                switch (ddsImage.header10.dxgiFormat)
                {
                case (DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM):
                    pif = InternalFormat.CompressedSrgbAlphaBptcUnorm;
                    break;

                default:
                    throw new ApplicationException("Unimplemented DX10 Texture Pixel format");
                }
                break;
            }

            default:
                throw new ApplicationException("Unimplemented Pixel format");
            }

            //Temp Variables
            int w           = width;
            int h           = height;
            int mm_count    = ddsImage.header.dwMipMapCount;
            int depth_count = Math.Max(1, ddsImage.header.dwDepth); //Fix the counter to 1 to fit the texture in a 3D container
            int temp_size   = ddsImage.header.dwPitchOrLinearSize;


            //Generate PBO
            pboID = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.PixelUnpackBuffer, pboID);
            GL.BufferData(BufferTarget.PixelUnpackBuffer, ddsImage.bdata.Length, ddsImage.bdata, BufferUsageHint.StaticDraw);
            //GL.BufferSubData(BufferTarget.PixelUnpackBuffer, IntPtr.Zero, ddsImage.bdata.Length, ddsImage.bdata);

            //Upload to GPU
            texID  = GL.GenTexture();
            target = TextureTarget.Texture2DArray;

            GL.BindTexture(target, texID);
            //When manually loading mipmaps, levels should be loaded first
            GL.TexParameter(target, TextureParameterName.TextureBaseLevel, 0);
            //GL.TexParameter(target, TextureParameterName.TextureMaxLevel, mm_count - 1);

            int offset = 0;

            for (int i = 0; i < mm_count; i++)
            {
                GL.CompressedTexImage3D(target, i, pif, w, h, depth_count, 0, temp_size * depth_count, IntPtr.Zero + offset);
                offset += temp_size * depth_count;

                w = Math.Max(w >> 1, 1);
                h = Math.Max(h >> 1, 1);

                temp_size = Math.Max(1, (w + 3) / 4) * Math.Max(1, (h + 3) / 4) * blocksize;
                //This works only for square textures
                //temp_size = Math.Max(temp_size/4, blocksize);
            }

            //GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureLodBias, -0.2f);
            GL.TexParameter(target, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
            GL.TexParameter(target, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
            GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
            GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
            //Console.WriteLine(GL.GetError());

            //Use anisotropic filtering
            float af_amount = GL.GetFloat((GetPName)All.MaxTextureMaxAnisotropy);

            af_amount = (float)Math.Max(af_amount, 4.0f);
            //GL.TexParameter(TextureTarget.Texture2D,  (TextureParameterName) 0x84FE, af_amount);
            int max_level = 0;

            GL.GetTexParameter(target, GetTextureParameter.TextureMaxLevel, out max_level);
            int base_level = 0;

            GL.GetTexParameter(target, GetTextureParameter.TextureBaseLevel, out base_level);

            int maxsize = Math.Max(height, width);
            int p       = (int)Math.Floor(Math.Log(maxsize, 2)) + base_level;
            int q       = Math.Min(p, max_level);

#if (DEBUGNONO)
            //Get all mipmaps
            temp_size = ddsImage.header.dwPitchOrLinearSize;
            for (int i = 0; i < q; i++)
            {
                //Get lowest calculated mipmap
                byte[] pixels = new byte[temp_size];

                //Save to disk
                GL.GetCompressedTexImage(TextureTarget.Texture2D, i, pixels);
                File.WriteAllBytes("Temp\\level" + i.ToString(), pixels);
                temp_size = Math.Max(temp_size / 4, 16);
            }
#endif

#if (DUMP_TEXTURESNONO)
            Sampler.dump_texture(name.Split('\\').Last().Split('/').Last(), width, height);
#endif
            //avgColor = getAvgColor(pixels);
            ddsImage = null;
            GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); //Unbind texture PBO
        }
示例#2
0
        public void init()
        {
            //Get MaterialFlags
            foreach (TkMaterialFlags f in Flags)
            {
                material_flags[(int)f.MaterialFlag] = 1.0f;
            }

            //Get Uniforms
            foreach (TkMaterialUniform un in Uniforms)
            {
                Uniform my_un = new Uniform("mpCustomPerMaterial.", un);
                CustomPerMaterialUniforms[my_un.Name] = my_un;
            }

            //Get Samplers
            foreach (TkMaterialSampler sm in Samplers)
            {
                Sampler s = new Sampler(sm);
                s.init(texMgr);
                PSamplers[s.PName] = s;
            }


            //Workaround for Procedurally Generated Samplers
            //I need to check if the diffuse sampler is procgen and then force the maps
            //on the other samplers with the appropriate names

            foreach (Sampler s in PSamplers.Values)
            {
                //Check if the first sampler is procgen
                if (s.isProcGen)
                {
                    string name = s.Map;

                    //Properly assemble the mask and the normal map names

                    string[] split        = name.Split('.');
                    string   pre_ext_name = "";
                    for (int i = 0; i < split.Length - 1; i++)
                    {
                        pre_ext_name += split[i] + '.';
                    }

                    if (PSamplers.ContainsKey("mpCustomPerMaterial.gMasksMap"))
                    {
                        string new_name = pre_ext_name + "MASKS.DDS";
                        PSamplers["mpCustomPerMaterial.gMasksMap"].PMap = new_name;
                        PSamplers["mpCustomPerMaterial.gMasksMap"].tex  = PSamplers["mpCustomPerMaterial.gMasksMap"].texMgr.getTexture(new_name);
                    }

                    if (PSamplers.ContainsKey("mpCustomPerMaterial.gNormalMap"))
                    {
                        string new_name = pre_ext_name + "NORMAL.DDS";
                        PSamplers["mpCustomPerMaterial.gNormalMap"].PMap = new_name;
                        PSamplers["mpCustomPerMaterial.gNormalMap"].tex  = PSamplers["mpCustomPerMaterial.gNormalMap"].texMgr.getTexture(new_name);
                    }
                    break;
                }
            }

            //Calculate material hash
            List <string> includes = new List <string>();

            for (int i = 0; i < MaterialFlags.Count; i++)
            {
                if (supported_flags.Contains(MaterialFlags[i]))
                {
                    includes.Add(MaterialFlags[i]);
                }
            }

            shaderHash = GLShaderHelper.calculateShaderHash(includes);

            if (!Common.RenderState.activeResMgr.shaderExistsForMaterial(this))
            {
                try
                {
                    compileMaterialShader();
                } catch (Exception e)
                {
                    Common.CallBacks.Log("Error during material shader compilation: " + e.Message);
                }
            }
        }