public override void DoTextureLoad(EntityName textureEntityName, AssetType typ, DownloadFinishedCallback finishCall)
        {
            EntityNameLL textureEnt = new EntityNameLL(textureEntityName);
            string       worldID    = textureEnt.EntityPart;

            OMV.UUID binID = new OMV.UUID(worldID);

            if (m_basePath == null)
            {
                return;
            }

            // do we already have the file?
            string textureFilename = Path.Combine(CacheDirBase, textureEnt.CacheFilename);

            lock (FileSystemAccessLock) {
                if (File.Exists(textureFilename))
                {
                    m_log.Log(LogLevel.DTEXTUREDETAIL, "DoTextureLoad: Texture file already exists for " + worldID);
                    bool hasTransparancy = CheckTextureFileForTransparancy(textureFilename);
                    // make the callback happen on a new thread so things don't get tangled (caller getting the callback)
                    Object[] finishCallParams = { finishCall, textureEntityName.Name, hasTransparancy };
                    m_completionWork.DoLater(FinishCallDoLater, finishCallParams);
                    // m_completionWork.DoLater(new FinishCallDoLater(finishCall, textureEntityName.Name, hasTransparancy));
                }
                else
                {
                    bool sendRequest = false;
                    lock (m_waiting) {
                        // if this is already being requested, don't waste our time
                        if (m_waiting.ContainsKey(binID))
                        {
                            m_log.Log(LogLevel.DTEXTUREDETAIL, "DoTextureLoad: Already waiting for " + worldID);
                        }
                        else
                        {
                            WaitingInfo wi = new WaitingInfo(binID, finishCall);
                            wi.filename = textureFilename;
                            wi.type     = typ;
                            m_waiting.Add(binID, wi);
                            sendRequest = true;
                        }
                    }
                    if (sendRequest)
                    {
                        // this is here because RequestTexture might immediately call the callback
                        //   and we should be outside the lock
                        m_log.Log(LogLevel.DTEXTUREDETAIL, "DoTextureLoad: Requesting: " + textureEntityName);
                        // m_texturePipe.RequestTexture(binID, OMV.ImageType.Normal, 50f, 0, 0, OnACDownloadFinished, false);
                        // m_comm.GridClient.Assets.RequestImage(binID, OMV.ImageType.Normal, 101300f, 0, 0, OnACDownloadFinished, false);
                        // m_comm.GridClient.Assets.RequestImage(binID, OMV.ImageType.Normal, 50f, 0, 0, OnACDownloadFinished, false);
                        ThrottleTextureRequests(binID);
                    }
                }
            }
            return;
        }
        private void GenerateMipMaps(AssetContextBase acontext, OMV.UUID textureUUID, out int textureID)
        {
            EntityNameLL textureEntityName = EntityNameLL.ConvertTextureWorldIDToEntityName(acontext, textureUUID);

            // see if the cache file exists -- if not, we don't get a texture this frame
            if (!acontext.CheckIfCached(textureEntityName))
            {
                textureID = 0;
                return;
            }

            int id = GL.GenTexture();

            GL.BindTexture(TextureTarget.Texture2D, id);

            try {
                using (Bitmap bmp = acontext.GetTexture(textureEntityName)) {
                    BitmapData bmp_data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
                                                       ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

                    GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp_data.Width, bmp_data.Height, 0,
                                  OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bmp_data.Scan0);

                    bmp.UnlockBits(bmp_data);
                }
                // GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
                // GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);

                // We haven't uploaded mipmaps, so disable mipmapping (otherwise the texture will not appear).
                // On newer video cards, we can use GL.GenerateMipmaps() or GL.Ext.GenerateMipmaps() to create
                // mipmaps automatically. In that case, use TextureMinFilter.LinearMipmapLinear to enable them.
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
            }
            catch (Exception e) {
                m_log.Log(LogLevel.DBADERROR, "Failed binding texture id={0}, uuid={1}: {2}", id, textureUUID, e);
                textureID = 0;
            }

            textureID = id;
            return;
        }
Example #3
0
        private void CreateNewPrim(LLEntityBase ent)
        {
            m_log.Log(LogLevel.DRENDERDETAIL, "Create new prim {0}", ent.Name.Name);
            // entity render info is kept per region. Get the region prim structure
            RegionRenderInfo rri = GetRegionRenderInfo(ent.RegionContext);
            IEntityAvatar    av;

            if (ent.TryGet <IEntityAvatar>(out av))
            {
                // if this entity is an avatar, just put it on the display list
                lock (rri.renderAvatarList) {
                    if (!rri.renderAvatarList.ContainsKey(av.LGID))
                    {
                        RenderableAvatar ravv = new RenderableAvatar();
                        ravv.avatar = av;
                        rri.renderAvatarList.Add(av.LGID, ravv);
                    }
                }
                return;
            }
            OMV.Primitive prim = ent.Prim;

            /* don't do foliage yet
             * if (prim.PrimData.PCode == OMV.PCode.Grass
             || prim.PrimData.PCode == OMV.PCode.Tree
             || prim.PrimData.PCode == OMV.PCode.NewTree) {
             || lock (renderFoliageList)
             ||     renderFoliageList[prim.LocalID] = prim;
             || return;
             ||}
             */

            RenderablePrim render = new RenderablePrim();

            render.Prim      = prim;
            render.acontext  = ent.AssetContext;
            render.rcontext  = ent.RegionContext;
            render.Position  = prim.Position;
            render.Rotation  = prim.Rotation;
            render.isVisible = true; // initially assume visible

            if (m_meshMaker == null)
            {
                m_meshMaker = new Renderer.Mesher.MeshmerizerR();
                m_meshMaker.ShouldScaleMesh = false;
            }

            if (prim.Sculpt != null)
            {
                EntityNameLL          textureEnt    = EntityNameLL.ConvertTextureWorldIDToEntityName(ent.AssetContext, prim.Sculpt.SculptTexture);
                System.Drawing.Bitmap textureBitmap = ent.AssetContext.GetTexture(textureEnt);
                if (textureBitmap == null)
                {
                    // the texture is not available. Request it.
                    // Note that we just call this routine again when it is available. Hope it's not recursive
                    ent.AssetContext.DoTextureLoad(textureEnt, AssetContextBase.AssetType.SculptieTexture,
                                                   delegate(string name, bool trans) {
                        CreateNewPrim(ent);
                        return;
                    }
                                                   );
                    return;
                }
                render.Mesh = m_meshMaker.GenerateSculptMesh(textureBitmap, prim, OMVR.DetailLevel.Medium);
                textureBitmap.Dispose();
            }
            else
            {
                render.Mesh = m_meshMaker.GenerateFacetedMesh(prim, OMVR.DetailLevel.High);
            }

            if (render.Mesh == null)
            {
                // mesh generation failed
                m_log.Log(LogLevel.DBADERROR, "FAILED MESH GENERATION: not generating new prim {0}", ent.Name.Name);
                return;
            }

            // Create a FaceData struct for each face that stores the 3D data
            // in an OpenGL friendly format
            for (int j = 0; j < render.Mesh.Faces.Count; j++)
            {
                OMVR.Face face = render.Mesh.Faces[j];
                FaceData  data = new FaceData();

                // Vertices for this face
                data.Vertices = new float[face.Vertices.Count * 3];
                for (int k = 0; k < face.Vertices.Count; k++)
                {
                    data.Vertices[k * 3 + 0] = face.Vertices[k].Position.X;
                    data.Vertices[k * 3 + 1] = face.Vertices[k].Position.Y;
                    data.Vertices[k * 3 + 2] = face.Vertices[k].Position.Z;
                }

                // Indices for this face
                data.Indices = face.Indices.ToArray();

                // Texture transform for this face
                OMV.Primitive.TextureEntryFace teFace = prim.Textures.GetFace((uint)j);
                m_meshMaker.TransformTexCoords(face.Vertices, face.Center, teFace);

                // Texcoords for this face
                data.TexCoords = new float[face.Vertices.Count * 2];
                for (int k = 0; k < face.Vertices.Count; k++)
                {
                    data.TexCoords[k * 2 + 0] = face.Vertices[k].TexCoord.X;
                    data.TexCoords[k * 2 + 1] = face.Vertices[k].TexCoord.Y;
                }

                data.Normals = new float[face.Vertices.Count * 3];
                for (int k = 0; k < face.Vertices.Count; k++)
                {
                    data.Normals[k * 3 + 0] = face.Vertices[k].Normal.X;
                    data.Normals[k * 3 + 1] = face.Vertices[k].Normal.Y;
                    data.Normals[k * 3 + 2] = face.Vertices[k].Normal.Z;
                }


                // m_log.Log(LogLevel.DRENDERDETAIL, "CreateNewPrim: v={0}, i={1}, t={2}",
                //     data.Vertices.GetLength(0), data.Indices.GetLength(0), data.TexCoords.GetLength(0));

                // Texture for this face
                if (teFace.TextureID != OMV.UUID.Zero &&
                    teFace.TextureID != OMV.Primitive.TextureEntry.WHITE_TEXTURE)
                {
                    lock (Textures) {
                        if (!Textures.ContainsKey(teFace.TextureID))
                        {
                            // temporarily add the entry to the table so we don't request it multiple times
                            Textures.Add(teFace.TextureID, new TextureInfo(0, true));
                            // We haven't constructed this image in OpenGL yet, get ahold of it
                            AssetContextBase.RequestTextureLoad(
                                EntityNameLL.ConvertTextureWorldIDToEntityName(ent.AssetContext, teFace.TextureID),
                                AssetContextBase.AssetType.Texture,
                                OnTextureDownloadFinished);
                        }
                    }
                }

                // Set the UserData for this face to our FaceData struct
                face.UserData        = data;
                render.Mesh.Faces[j] = face;
            }

            lock (rri.renderPrimList) {
                rri.renderPrimList[prim.LocalID] = render;
            }
        }