private static Texture mixNormalTextures(int texWidth, int texHeight) { //Upload Textures //BIND TEXTURES Texture tex; int loc; Texture dMask = Common.RenderState.activeResMgr.texMgr.getTexture("default_mask.dds"); Texture dDiff = Common.RenderState.activeResMgr.texMgr.getTexture("default.dds"); //USE PROGRAM int pass_program = Common.RenderState.activeResMgr.GLShaders[GLSLHelper.SHADER_TYPE.TEXTURE_MIX_SHADER].program_id; GL.UseProgram(pass_program); //Upload base Layers Used int baseLayerIndex = 0; loc = GL.GetUniformLocation(pass_program, "lbaseLayersUsed"); if (loc >= 0) { for (int i = 0; i < 8; i++) { if (normaltextures[i] != null) { GL.Uniform1(loc + i, 1.0f); baseLayerIndex = i; } else { GL.Uniform1(loc + i, 0.0f); } } } loc = GL.GetUniformLocation(pass_program, "baseLayerIndex"); GL.Uniform1(loc, baseLayerIndex); //No need for extra alpha tetuxres loc = GL.GetUniformLocation(pass_program, "use_alpha_textures"); GL.Uniform1(loc, 1.0f); //Upload DiffuseTextures as alphaTextures loc = GL.GetUniformLocation(pass_program, "alphaTex"); if (loc >= 0) { for (int i = 0; i < 8; i++) { if (difftextures[i] != null) { tex = difftextures[i]; } else { tex = dMask; } //Upload diffuse Texture GL.Uniform1(loc + i, i); // I need to upload the texture unit number int tex0Id = (int)TextureUnit.Texture0; GL.ActiveTexture((TextureUnit)(tex0Id + i)); GL.BindTexture(tex.target, tex.texID); } } //Upload maskTextures loc = GL.GetUniformLocation(pass_program, "mainTex"); if (loc >= 0) { for (int i = 0; i < 8; i++) { if (normaltextures[i] != null) { tex = normaltextures[i]; } else { tex = dMask; } //Upload diffuse Texture GL.Uniform1(loc + i, 8 + i); // I need to upload the texture unit number int tex0Id = (int)TextureUnit.Texture8; GL.ActiveTexture((TextureUnit)(tex0Id + i)); GL.BindTexture(tex.target, tex.texID); } } //Activate Recoloring loc = GL.GetUniformLocation(pass_program, "recolor_flag"); GL.Uniform1(loc, 0.0f); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); GL.BindVertexArray(RenderState.activeResMgr.GLPrimitiveVaos["default_renderquad"].vao_id); GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); GL.DrawElements(PrimitiveType.Triangles, 6, DrawElementsType.UnsignedInt, IntPtr.Zero); //Console.WriteLine("MixTextures5, Last GL Error: " + GL.GetError()); int out_tex_2darray_mask = Sampler.generateTexture2DArray(PixelInternalFormat.Rgba8, texWidth, texHeight, 1, PixelFormat.Rgba, PixelType.UnsignedByte, 11); Sampler.setupTextureParameters(TextureTarget.Texture2DArray, out_tex_2darray_mask, (int)TextureWrapMode.Repeat, (int)TextureMagFilter.Linear, (int)TextureMinFilter.LinearMipmapLinear, 4.0f); //Copy the read buffers to the GL.BindTexture(TextureTarget.Texture2DArray, out_tex_2darray_mask); GL.ReadBuffer(ReadBufferMode.ColorAttachment0); GL.CopyTexSubImage3D(TextureTarget.Texture2DArray, 0, 0, 0, 0, 0, 0, texWidth, texHeight); //Generate Mipmaps to the new textures from the base level Sampler.generateTexture2DArrayMipmaps(out_tex_2darray_mask); //Find name for textures //Store Diffuse Texture to material Texture new_tex = new Texture(); new_tex.texID = out_tex_2darray_mask; new_tex.target = TextureTarget.Texture2DArray; #if (DUMP_TEXTURES) GL.ReadBuffer(ReadBufferMode.ColorAttachment0); Sampler.dump_texture("normal", texWidth, texHeight); #endif return(new_tex); }
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 }