protected override void Update() { base.Update(); if (changeReader == null) { changeReader = new P3dReader(); changeReader.OnComplete += HandleCompleteChange; } if (changeReader.Requested == false && registeredPaintableTexture != null && registeredPaintableTexture.Activated == true) { if (P3dReader.NeedsUpdating(changeReader, changePixels, registeredPaintableTexture.Current, downsampleSteps) == true || changeDirty == true) { changeDirty = false; var desc = registeredPaintableTexture.Current.descriptor; desc.useMipMap = false; var renderTexture = P3dHelper.GetRenderTexture(desc); P3dCommandReplace.Blit(renderTexture, texture, color); // Request new change changeReader.Request(renderTexture, DownsampleSteps, Async); P3dHelper.ReleaseRenderTexture(renderTexture); } } changeReader.UpdateRequest(); }
public static bool Downsample(RenderTexture renderTexture, int steps, ref RenderTexture temporary) { if (steps > 0 && renderTexture != null) { // Perform initial downsample to get buffer var oldActive = RenderTexture.active; var desc = new RenderTextureDescriptor(renderTexture.width / 2, renderTexture.height / 2, renderTexture.format, 0); var halfRenderTexture = GetRenderTexture(desc); P3dCommandReplace.BlitFast(halfRenderTexture, renderTexture, Color.white, Vector4.one); // Ping pong downsamples for (var i = 1; i < steps; i++) { desc.width /= 2; desc.height /= 2; renderTexture = halfRenderTexture; halfRenderTexture = GetRenderTexture(desc); Graphics.Blit(renderTexture, halfRenderTexture); ReleaseRenderTexture(renderTexture); } temporary = halfRenderTexture; RenderTexture.active = oldActive; return(true); } return(false); }
/// <summary>This method will clear the current texture state with the specified texture and color. /// NOTE: This component must be activated, and this method will not resize the current texture.</summary> public void Clear(Texture texture, Color tint) { if (activated == true) { P3dCommandReplace.Blit(current, texture, tint); } }
/// <summary>This method will resize the current texture state with the specified width and height. /// NOTE: This component must be activated.</summary> public bool Resize(int width, int height, bool copyContents = true) { if (activated == true) { if (current.width != width || current.height != height) { var descriptor = current.descriptor; descriptor.width = width; descriptor.height = height; var newCurrent = P3dHelper.GetRenderTexture(descriptor, current); if (copyContents == true) { P3dCommandReplace.Blit(newCurrent, current, Color.white); if (newCurrent.useMipMap == true) { newCurrent.GenerateMips(); } } P3dHelper.ReleaseRenderTexture(current); current = newCurrent; return(true); } } return(false); }
private void RebuildFromCommands() { P3dCommandReplace.Blit(current, texture, color); var localToWorldMatrix = transform.localToWorldMatrix; for (var i = 0; i <= stateIndex; i++) { var paintableState = paintableStates[i]; var commandCount = paintableState.Commands.Count; for (var j = 0; j < commandCount; j++) { var worldCommand = paintableState.Commands[j].SpawnCopy(); worldCommand.Transform(localToWorldMatrix, localToWorldMatrix); paintCommands.Add(worldCommand); //AddCommand(worldCommand); } } ExecuteCommands(false); NotifyOnModified(false); }
public void Request(RenderTexture texture, int downsample, bool async) { if (texture == null) { Debug.LogError("Texture null."); return; } if (requested == true) { Debug.LogError("Already requested."); return; } if (buffer != null) { Debug.LogError("Buffer exists."); return; } originalSize.x = downsampledSize.x = texture.width; originalSize.y = downsampledSize.y = texture.height; for (var i = 0; i < downsample; i++) { if (downsampledSize.x > 2) { downsampledSize.x /= 2; } if (downsampledSize.y > 2) { downsampledSize.y /= 2; } } downsampleSteps = downsample; downsampleBoost = (originalSize.x / downsampledSize.x) * (originalSize.y / downsampledSize.y); var desc = texture.descriptor; desc.useMipMap = false; desc.width = downsampledSize.x; desc.height = downsampledSize.y; buffer = P3dHelper.GetRenderTexture(desc); P3dCommandReplace.Blit(buffer, texture, Color.white); #if ASYNC_READBACK_SUPPORTED if (async == true) { request = AsyncGPUReadback.Request(buffer, 0, TextureFormat.RGBA32); requested = true; UpdateRequest(); } else #endif { CompleteDirectly(); } }
private void ExecuteCommands(List <P3dCommand> commands, bool sendNotifications, ref RenderTexture main, ref RenderTexture swap, ref Mesh preparedMesh, ref Matrix4x4 preparedMatrix) { if (swap == null) { swap = P3dHelper.GetRenderTexture(main); } if (keepUnpaintable == true) { P3dCommandReplace.BlitFast(swap, current, Color.white); } RenderTexture.active = main; for (var i = 0; i < commands.Count; i++) { var command = commands[i]; if (command.Model != null) { RenderTexture.active = swap; command.Apply(main); if (command.RequireMesh == true) { command.Model.GetPrepared(ref preparedMesh, ref preparedMatrix); P3dHelper.Draw(command.Material, preparedMesh, preparedMatrix, command.Submesh, coord); } else { P3dHelper.Draw(command.Material); } P3dHelper.Swap(ref main, ref swap); } command.Pool(); } commands.Clear(); if (main.useMipMap == true) { main.GenerateMips(); } if (sendNotifications == true) { NotifyOnModified(commands == previewCommands); } }
public static void Blit(ref RenderTexture main, ref RenderTexture swap, P3dBlendMode blendMode, Texture texture, Color color, float opacity, float minimum) { Instance.SetMaterial(blendMode, texture, color, opacity, minimum); Instance.Apply(); if (Instance.Double == true) { P3dCommandReplace.Blit(swap, main, Color.white); Instance.Material.SetTexture(P3dShader._Buffer, swap); Instance.Material.SetVector(P3dShader._BufferSize, new Vector2(swap.width, swap.height)); } P3dHelper.Blit(main, Instance.Material); }
public void Resize() { foreach (var slot in Slots) { if (slot.Texture != null) { if (slot.Texture.width != Width || slot.Texture.height != Height) { var desc = slot.Texture.descriptor; desc.width = Width; desc.height = Height; var resizedTexture = P3dHelper.GetRenderTexture(desc, slot.Texture); P3dCommandReplace.Blit(resizedTexture, slot.Texture, Color.white); P3dHelper.ReleaseRenderTexture(slot.Texture); slot.Texture = resizedTexture; } } } }
private void WriteThumbnailTex(RenderTexture texture, P3dPaintMaterial.Slot paintSlot, P3dShaderTemplate.Write write) { if (paintSlot != null) { P3dCommandReplace.Blit(texture, paintSlot.Texture, paintSlot.Color); } else { var group = P3dGroupData.GetGroupData(write.SourceGroup); if (group != null) { P3dCommandReplace.Blit(texture, group.DefaultTexture, group.DefaultColor); } else { P3dCommandReplace.Blit(texture, default(Texture), default(Color)); } } }
public void Activate() { if (activated == false) { UpdateMaterial(); if (material != null) { var finalWidth = width; var finalHeight = height; var finalTexture = material.GetTexture(slot.Name); CachedPaintable.ScaleSize(ref finalWidth, ref finalHeight); if (texture != null) { finalTexture = texture; } if (string.IsNullOrEmpty(shaderKeyword) == false) { material.EnableKeyword(shaderKeyword); } var desc = new RenderTextureDescriptor(width, height, format, 0); desc.autoGenerateMips = false; if (mipMaps == MipType.ForceOn) { desc.useMipMap = true; } else if (mipMaps == MipType.Auto && P3dHelper.HasMipMaps(finalTexture) == true) { desc.useMipMap = true; } current = P3dHelper.GetRenderTexture(desc); current.wrapMode = TextureWrapMode.Repeat; P3dCommandReplace.Blit(current, finalTexture, color); if (current.useMipMap == true) { current.GenerateMips(); } material.SetTexture(slot.Name, current); activated = true; if (string.IsNullOrEmpty(saveName) == false) { Load(); } NotifyOnModified(false); } } }
private void Render(P3dCommand command, P3dScene.Mat mat, P3dScene.Image image, P3dScene.Obj obj, int subMesh) { var oldActive = RenderTexture.active; if (image.Current == null) { if (image.Width > 0 && image.Height > 0 && image.Pixels != null && image.Pixels.Length > 0) { var texture = new Texture2D(1, 1); if (texture.LoadImage(image.Pixels) == true) { var desc = mat.Desc; desc.width = image.Width; desc.height = image.Height; image.Current = P3dHelper.GetRenderTexture(mat.Desc); P3dCommandReplace.BlitFast(image.Current, texture, Color.white); } else { image.Current = P3dHelper.GetRenderTexture(mat.Desc); P3dCommandReplace.BlitFast(image.Current, default(Texture), default(Color)); } DestroyImmediate(texture); } else { image.Current = P3dHelper.GetRenderTexture(mat.Desc); P3dCommandReplace.BlitFast(image.Current, default(Texture), default(Color)); } } var swap = P3dHelper.GetRenderTexture(image.Current.descriptor, image.Current); if (command.Preview == true) { if (image.Preview == null) { image.Preview = P3dHelper.GetRenderTexture(image.Current.descriptor, image.Current); P3dCommandReplace.BlitFast(image.Preview, image.Current, Color.white); } P3dCommandReplace.BlitFast(swap, image.Preview, Color.white); command.Apply(image.Preview); } else { P3dCommandReplace.BlitFast(swap, image.Current, Color.white); command.Apply(image.Current); } RenderTexture.active = swap; if (command.RequireMesh == true) { P3dHelper.Draw(command.Material, obj.FinalMesh, obj.Matrix, subMesh, obj.Coord); } else { P3dHelper.Draw(command.Material); } RenderTexture.active = oldActive; if (command.Preview == true) { P3dHelper.ReleaseRenderTexture(image.Preview); image.Preview = swap; previewDrawn = true; } else { P3dHelper.ReleaseRenderTexture(image.Current); image.Current = swap; } paintedGroups.Add(command.Priority); // Group is stored in priority }
public void UpdateMergedLayers(Layer currentLayer) { foreach (var mat in Mats) { foreach (var mergedLayer in mat.MergedLayers.Values) { mergedLayer.Dirty = true; if (mergedLayer.Layer != currentLayer) { mergedLayer.Clear(); mergedLayer.Layer = currentLayer; } } if (mat.Template != null) { foreach (var slot in mat.Template.Slots) { mat.UpdateMergedLayers(slot.WriteR.SourceGroup); mat.UpdateMergedLayers(slot.WriteG.SourceGroup); mat.UpdateMergedLayers(slot.WriteB.SourceGroup); mat.UpdateMergedLayers(slot.WriteA.SourceGroup); } } foreach (var pair in mat.MergedLayers) { var group = pair.Key; var mergedLayer = pair.Value; if (mergedLayer.Dirty == true) { mergedLayer.Clear(); } else { var currentLayerIndex = Layers.IndexOf(currentLayer); if (mergedLayer.Under == null) { mergedLayer.Under = P3dHelper.GetRenderTexture(mat.Desc); var groupData = P3dGroupData.GetGroupData(group); if (groupData != null) { P3dCommandReplace.Blit(mergedLayer.Under, groupData.DefaultTexture, groupData.DefaultColor); } else { P3dCommandReplace.Blit(mergedLayer.Under, default(Texture), default(Color)); } for (var i = 0; i < currentLayerIndex; i++) { TryBlendInto(ref mergedLayer.Under, Layers[i], mat.Id, group); } } // Last layer? if (currentLayerIndex == Layers.Count - 1) { if (mergedLayer.Above != null) { mergedLayer.Above = P3dHelper.ReleaseRenderTexture(mergedLayer.Above); } } else { if (mergedLayer.Above == null) { mergedLayer.Above = P3dHelper.GetRenderTexture(mat.Desc); P3dCommandReplace.Blit(mergedLayer.Above, default(Texture), default(Color)); for (var i = currentLayerIndex + 1; i < Layers.Count; i++) { TryBlendInto(ref mergedLayer.Above, Layers[i], mat.Id, group); } } } if (mergedLayer.Final == null) { mergedLayer.Final = P3dHelper.GetRenderTexture(mat.Desc); } P3dCommandReplace.Blit(mergedLayer.Final, mergedLayer.Under, Color.white); TryBlendInto(ref mergedLayer.Final, currentLayer, mat.Id, group); if (mergedLayer.Above != null) { mergedLayer.Final = P3dCommandFill.Blit(mergedLayer.Final, P3dBlendMode.AlphaBlend, mergedLayer.Above, Color.white, 1.0f, 0.0f); } } } } }