void TextureThread() { PendingTextures.Open(); Logger.DebugLog("Started Texture Thread"); while (TextureThreadRunning) { TextureLoadItem item = null; if (!PendingTextures.Dequeue(Timeout.Infinite, ref item)) { continue; } if (TexturesPtrMap.ContainsKey(item.TeFace.TextureID)) { item.Data.TextureInfo = TexturesPtrMap[item.TeFace.TextureID]; continue; } if (LoadTexture(item.TeFace.TextureID, ref item.Data.TextureInfo.Texture, false)) { Bitmap bitmap = (Bitmap)item.Data.TextureInfo.Texture; bool hasAlpha; if (item.Data.TextureInfo.Texture.PixelFormat == System.Drawing.Imaging.PixelFormat.Format32bppArgb) { hasAlpha = true; } else { hasAlpha = false; } item.Data.TextureInfo.HasAlpha = hasAlpha; bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); var loadOnMainThread = new MethodInvoker(() => { item.Data.TextureInfo.TexturePointer = RHelp.GLLoadImage(bitmap, hasAlpha, RenderSettings.HasMipmap); TexturesPtrMap[item.TeFace.TextureID] = item.Data.TextureInfo; bitmap.Dispose(); item.Data.TextureInfo.Texture = null; SafeInvalidate(); }); if (!instance.MonoRuntime || IsHandleCreated) { BeginInvoke(loadOnMainThread); } } } Logger.DebugLog("Texture thread exited"); }
public void DownloadTexture(TextureLoadItem item, bool force) { }
public void DownloadTexture(TextureLoadItem item, bool force) { if (force || texturesRequestedThisFrame < RenderSettings.TexturesToDownloadPerFrame) { texturesRequestedThisFrame++; lock (TexturesPtrMap) { if (TexturesPtrMap.ContainsKey(item.TeFace.TextureID)) { item.Data.TextureInfo = TexturesPtrMap[item.TeFace.TextureID]; } else if (item.TeFace.TextureID == invisi1 || item.TeFace.TextureID == invisi2) { TexturesPtrMap[item.TeFace.TextureID] = item.Data.TextureInfo; TexturesPtrMap[item.TeFace.TextureID].HasAlpha = false; TexturesPtrMap[item.TeFace.TextureID].IsInvisible = true; } else { TexturesPtrMap[item.TeFace.TextureID] = item.Data.TextureInfo; if (item.TextureData == null && item.TGAData == null) { if (CacheDecodedTextures && RHelp.LoadCachedImage(item.TeFace.TextureID, out item.TGAData, out item.Data.TextureInfo.HasAlpha, out item.Data.TextureInfo.FullAlpha, out item.Data.TextureInfo.IsMask)) { PendingTextures.Enqueue(item); } else if (Client.Assets.Cache.HasAsset(item.Data.TextureInfo.TextureID)) { item.LoadAssetFromCache = true; PendingTextures.Enqueue(item); } else if (!item.Data.TextureInfo.FetchFailed) { Client.Assets.RequestImage(item.TeFace.TextureID, (state, asset) => { switch (state) { case TextureRequestState.Finished: item.TextureData = asset.AssetData; PendingTextures.Enqueue(item); break; case TextureRequestState.Aborted: case TextureRequestState.NotFound: case TextureRequestState.Timeout: item.Data.TextureInfo.FetchFailed = true; break; } }); } } else { PendingTextures.Enqueue(item); } } } } }
public void DownloadTexture(TextureLoadItem item, bool force) { if (force || texturesRequestedThisFrame < RenderSettings.TexturesToDownloadPerFrame) { lock (TexturesPtrMap) { if (TexturesPtrMap.ContainsKey(item.TeFace.TextureID)) { item.Data.TextureInfo = TexturesPtrMap[item.TeFace.TextureID]; } else if (item.TeFace.TextureID == invisi1 || item.TeFace.TextureID == invisi2) { TexturesPtrMap[item.TeFace.TextureID] = item.Data.TextureInfo; TexturesPtrMap[item.TeFace.TextureID].HasAlpha = false; TexturesPtrMap[item.TeFace.TextureID].IsInvisible = true; } else { TexturesPtrMap[item.TeFace.TextureID] = item.Data.TextureInfo; if (item.TextureData == null && item.TGAData == null) { if (CacheDecodedTextures && RHelp.LoadCachedImage(item.TeFace.TextureID, out item.TGAData, out item.Data.TextureInfo.HasAlpha, out item.Data.TextureInfo.FullAlpha, out item.Data.TextureInfo.IsMask)) { PendingTextures.Enqueue(item); } else if (Client.Assets.Cache.HasAsset(item.Data.TextureInfo.TextureID)) { item.LoadAssetFromCache = true; PendingTextures.Enqueue(item); } else if (!item.Data.TextureInfo.FetchFailed) { TextureDownloadCallback handler = (state, asset) => { switch (state) { case TextureRequestState.Finished: item.TextureData = asset.AssetData; PendingTextures.Enqueue(item); break; case TextureRequestState.Aborted: case TextureRequestState.NotFound: case TextureRequestState.Timeout: item.Data.TextureInfo.FetchFailed = true; break; } }; if (item.ImageType == ImageType.ServerBaked && !string.IsNullOrEmpty(item.BakeName)) { // Server side bake Client.Assets.RequestServerBakedImage(item.AvatarID, item.TeFace.TextureID, item.BakeName, handler); } else { // Regular texture Client.Assets.RequestImage(item.TeFace.TextureID, item.ImageType, handler); } texturesRequestedThisFrame++; } } else { PendingTextures.Enqueue(item); } } } } }
private void UpdatePrimBlocking(Primitive prim) { FacetedMesh mesh = null; FacetedMesh existingMesh = null; lock (Prims) { if (Prims.ContainsKey(prim.LocalID)) { existingMesh = Prims[prim.LocalID]; } } if (prim.Textures == null) return; try { if (prim.Sculpt != null && prim.Sculpt.SculptTexture != UUID.Zero) { if (prim.Sculpt.Type != SculptType.Mesh) { // Regular sculptie Image img = null; if (!LoadTexture(prim.Sculpt.SculptTexture, ref img, true)) return; mesh = renderer.GenerateFacetedSculptMesh(prim, (Bitmap)img, DetailLevel.Highest); } else { // Mesh AutoResetEvent gotMesh = new AutoResetEvent(false); bool meshSuccess = false; Client.Assets.RequestMesh(prim.Sculpt.SculptTexture, (success, meshAsset) => { if (!success || !FacetedMesh.TryDecodeFromAsset(prim, meshAsset, DetailLevel.Highest, out mesh)) { Logger.Log("Failed to fetch or decode the mesh asset", Helpers.LogLevel.Warning, Client); } else { meshSuccess = true; } gotMesh.Set(); }); if (!gotMesh.WaitOne(20 * 1000, false)) return; if (!meshSuccess) return; } } else { mesh = renderer.GenerateFacetedMesh(prim, DetailLevel.Highest); } } catch { return; } // Create a FaceData struct for each face that stores the 3D data // in a OpenGL friendly format for (int j = 0; j < mesh.Faces.Count; j++) { Face face = mesh.Faces[j]; FaceData data = new FaceData(); // Vertices for this face data.Vertices = new float[face.Vertices.Count * 3]; data.Normals = 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; 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; } // Indices for this face data.Indices = face.Indices.ToArray(); // Texture transform for this face Primitive.TextureEntryFace teFace = prim.Textures.GetFace((uint)j); renderer.TransformTexCoords(face.Vertices, face.Center, teFace, prim.Scale); // 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; } // Set the UserData for this face to our FaceData struct face.UserData = data; mesh.Faces[j] = face; if (existingMesh != null && j < existingMesh.Faces.Count && existingMesh.Faces[j].TextureFace.TextureID == teFace.TextureID && ((FaceData)existingMesh.Faces[j].UserData).TextureInfo.TexturePointer != 0 ) { FaceData existingData = (FaceData)existingMesh.Faces[j].UserData; data.TextureInfo.TexturePointer = existingData.TextureInfo.TexturePointer; } else { var textureItem = new TextureLoadItem() { Data = data, Prim = prim, TeFace = teFace }; PendingTextures.Enqueue(textureItem); } } lock (Prims) { Prims[prim.LocalID] = mesh; } SafeInvalidate(); }
private void UpdatePrimBlocking(Primitive prim) { FacetedMesh mesh = null; FacetedMesh existingMesh = null; lock (Prims) { if (Prims.ContainsKey(prim.LocalID)) { existingMesh = Prims[prim.LocalID]; } } if (prim.Textures == null) { return; } try { if (prim.Sculpt != null && prim.Sculpt.SculptTexture != UUID.Zero) { if (prim.Sculpt.Type != SculptType.Mesh) { // Regular sculptie Image img = null; if (!LoadTexture(prim.Sculpt.SculptTexture, ref img, true)) { return; } mesh = renderer.GenerateFacetedSculptMesh(prim, (Bitmap)img, DetailLevel.Highest); } else { // Mesh AutoResetEvent gotMesh = new AutoResetEvent(false); bool meshSuccess = false; Client.Assets.RequestMesh(prim.Sculpt.SculptTexture, (success, meshAsset) => { if (!success || !FacetedMesh.TryDecodeFromAsset(prim, meshAsset, DetailLevel.Highest, out mesh)) { Logger.Log("Failed to fetch or decode the mesh asset", Helpers.LogLevel.Warning, Client); } else { meshSuccess = true; } gotMesh.Set(); }); if (!gotMesh.WaitOne(20 * 1000, false)) { return; } if (!meshSuccess) { return; } } } else { mesh = renderer.GenerateFacetedMesh(prim, DetailLevel.Highest); } } catch { return; } // Create a FaceData struct for each face that stores the 3D data // in a OpenGL friendly format for (int j = 0; j < mesh.Faces.Count; j++) { Face face = mesh.Faces[j]; FaceData data = new FaceData { Vertices = new float[face.Vertices.Count * 3], Normals = new float[face.Vertices.Count * 3] }; // Vertices for this face 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; 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; } // Indices for this face data.Indices = face.Indices.ToArray(); // Texture transform for this face Primitive.TextureEntryFace teFace = prim.Textures.GetFace((uint)j); renderer.TransformTexCoords(face.Vertices, face.Center, teFace, prim.Scale); // 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; } // Set the UserData for this face to our FaceData struct face.UserData = data; mesh.Faces[j] = face; if (existingMesh != null && j < existingMesh.Faces.Count && existingMesh.Faces[j].TextureFace.TextureID == teFace.TextureID && ((FaceData)existingMesh.Faces[j].UserData).TextureInfo.TexturePointer != 0 ) { FaceData existingData = (FaceData)existingMesh.Faces[j].UserData; data.TextureInfo.TexturePointer = existingData.TextureInfo.TexturePointer; } else { var textureItem = new TextureLoadItem() { Data = data, Prim = prim, TeFace = teFace }; PendingTextures.Enqueue(textureItem); } } lock (Prims) { Prims[prim.LocalID] = mesh; } SafeInvalidate(); }
public void DownloadTexture(TextureLoadItem item) { lock (TexturesPtrMap) { if (TexturesPtrMap.ContainsKey(item.TeFace.TextureID)) { item.Data.TextureInfo = TexturesPtrMap[item.TeFace.TextureID]; } else { TexturesPtrMap[item.TeFace.TextureID] = item.Data.TextureInfo; if (item.TextureData == null && item.TGAData == null) { if (CacheDecodedTextures && RHelp.LoadCachedImage(item.TeFace.TextureID, out item.TGAData, out item.Data.TextureInfo.HasAlpha, out item.Data.TextureInfo.FullAlpha, out item.Data.TextureInfo.IsMask)) { PendingTextures.Enqueue(item); } else if (Client.Assets.Cache.HasAsset(item.Data.TextureInfo.TextureID)) { item.LoadAssetFromCache = true; PendingTextures.Enqueue(item); } else if (!item.Data.TextureInfo.FetchFailed) { Client.Assets.RequestImage(item.TeFace.TextureID, (state, asset) => { switch (state) { case TextureRequestState.Finished: item.TextureData = asset.AssetData; PendingTextures.Enqueue(item); break; case TextureRequestState.Aborted: case TextureRequestState.NotFound: case TextureRequestState.Timeout: item.Data.TextureInfo.FetchFailed = true; break; } }); } } else { PendingTextures.Enqueue(item); } } } }