示例#1
0
        public PixelValue PickPixel(ResourceId texID, bool customShader, UInt32 x, UInt32 y, UInt32 sliceFace, UInt32 mip, UInt32 sample)
        {
            IntPtr mem = CustomMarshal.Alloc(typeof(PixelValue));

            bool success = ReplayOutput_PickPixel(m_Real, texID, customShader, x, y, sliceFace, mip, sample, mem);

            PixelValue ret = null;

            if (success)
            {
                ret = (PixelValue)CustomMarshal.PtrToStructure(mem, typeof(PixelValue), false);
            }

            CustomMarshal.Free(mem);

            return(ret);
        }
示例#2
0
        public bool GetMinMax(ResourceId tex, UInt32 sliceFace, UInt32 mip, out PixelValue minval, out PixelValue maxval)
        {
            IntPtr mem1 = CustomMarshal.Alloc(typeof(PixelValue));
            IntPtr mem2 = CustomMarshal.Alloc(typeof(PixelValue));

            bool success = ReplayRenderer_GetMinMax(m_Real, tex, sliceFace, mip, mem1, mem2);

            if (success)
            {
                minval = (PixelValue)CustomMarshal.PtrToStructure(mem1, typeof(PixelValue), true);
                maxval = (PixelValue)CustomMarshal.PtrToStructure(mem2, typeof(PixelValue), true);
            }
            else
            {
                minval = null;
                maxval = null;
            }

            CustomMarshal.Free(mem1);
            CustomMarshal.Free(mem2);

            return(success);
        }
示例#3
0
        private void UI_UpdateChannels()
        {
            FetchTexture tex = CurrentTexture;

            channelStrip.SuspendLayout();

            if (tex != null && (tex.creationFlags & TextureCreationFlags.SwapBuffer) != 0)
            {
                // swapbuffer is always srgb for 8-bit types, linear for 16-bit types
                gammaDisplay.Enabled = false;

                if (tex.format.compByteWidth == 2 && !tex.format.special)
                    m_TexDisplay.linearDisplayAsGamma = false;
                else
                    m_TexDisplay.linearDisplayAsGamma = true;
            }
            else
            {
                if (tex != null && !tex.format.srgbCorrected)
                    gammaDisplay.Enabled = true;
                else
                    gammaDisplay.Enabled = false;

                m_TexDisplay.linearDisplayAsGamma = !gammaDisplay.Enabled || gammaDisplay.Checked;
            }

            if (tex != null && tex.format.srgbCorrected)
                m_TexDisplay.linearDisplayAsGamma = false;

            bool dsv = false;
            if(tex != null)
                dsv = ((tex.creationFlags & TextureCreationFlags.DSV) != 0) || (tex.format.compType == FormatComponentType.Depth);

            if (dsv &&
                (string)channels.SelectedItem != "Custom")
            {
                customRed.Visible = false;
                customGreen.Visible = false;
                customBlue.Visible = false;
                customAlpha.Visible = false;
                mulLabel.Visible = false;
                hdrMul.Visible = false;
                customShader.Visible = false;
                customCreate.Visible = false;
                customEdit.Visible = false;
                customDelete.Visible = false;
                depthStencilToolstrip.Visible = true;

                backcolorPick.Visible = false;
                checkerBack.Visible = false;

                mulSep.Visible = false;

                m_TexDisplay.Red = depthDisplay.Checked;
                m_TexDisplay.Green = stencilDisplay.Checked;
                m_TexDisplay.Blue = false;
                m_TexDisplay.Alpha = false;

                m_TexDisplay.HDRMul = -1.0f;
                if (m_TexDisplay.CustomShader != ResourceId.Null) { m_CurPixelValue = null; m_CurRealValue = null; UI_UpdateStatusText(); }
                m_TexDisplay.CustomShader = ResourceId.Null;
            }
            else if ((string)channels.SelectedItem == "RGBA" || !m_Core.LogLoaded)
            {
                customRed.Visible = true;
                customGreen.Visible = true;
                customBlue.Visible = true;
                customAlpha.Visible = true;
                mulLabel.Visible = false;
                hdrMul.Visible = false;
                customShader.Visible = false;
                customCreate.Visible = false;
                customEdit.Visible = false;
                customDelete.Visible = false;
                depthStencilToolstrip.Visible = false;

                backcolorPick.Visible = true;
                checkerBack.Visible = true;

                mulSep.Visible = false;

                m_TexDisplay.Red = customRed.Checked;
                m_TexDisplay.Green = customGreen.Checked;
                m_TexDisplay.Blue = customBlue.Checked;
                m_TexDisplay.Alpha = customAlpha.Checked;

                m_TexDisplay.HDRMul = -1.0f;
                if (m_TexDisplay.CustomShader != ResourceId.Null) { m_CurPixelValue = null; m_CurRealValue = null; UI_UpdateStatusText(); }
                m_TexDisplay.CustomShader = ResourceId.Null;
            }
            else if ((string)channels.SelectedItem == "RGBM")
            {
                customRed.Visible = true;
                customGreen.Visible = true;
                customBlue.Visible = true;
                customAlpha.Visible = false;
                mulLabel.Visible = true;
                hdrMul.Visible = true;
                customShader.Visible = false;
                customCreate.Visible = false;
                customEdit.Visible = false;
                customDelete.Visible = false;
                depthStencilToolstrip.Visible = false;

                backcolorPick.Visible = false;
                checkerBack.Visible = false;

                mulSep.Visible = true;

                m_TexDisplay.Red = customRed.Checked;
                m_TexDisplay.Green = customGreen.Checked;
                m_TexDisplay.Blue = customBlue.Checked;
                m_TexDisplay.Alpha = false;

                float mul = 32.0f;

                if (!float.TryParse(hdrMul.Text, out mul))
                    hdrMul.Text = mul.ToString();

                m_TexDisplay.HDRMul = mul;
                if (m_TexDisplay.CustomShader != ResourceId.Null) { m_CurPixelValue = null; m_CurRealValue = null; UI_UpdateStatusText(); }
                m_TexDisplay.CustomShader = ResourceId.Null;
            }
            else if ((string)channels.SelectedItem == "Custom")
            {
                customRed.Visible = true;
                customGreen.Visible = true;
                customBlue.Visible = true;
                customAlpha.Visible = true;
                mulLabel.Visible = false;
                hdrMul.Visible = false;
                customShader.Visible = true;
                customCreate.Visible = true;
                customEdit.Visible = true;
                customDelete.Visible = true;
                depthStencilToolstrip.Visible = false;

                backcolorPick.Visible = false;
                checkerBack.Visible = false;

                mulSep.Visible = false;

                m_TexDisplay.Red = customRed.Checked;
                m_TexDisplay.Green = customGreen.Checked;
                m_TexDisplay.Blue = customBlue.Checked;
                m_TexDisplay.Alpha = customAlpha.Checked;

                m_TexDisplay.HDRMul = -1.0f;

                m_TexDisplay.CustomShader = ResourceId.Null;
                if (m_CustomShaders.ContainsKey(customShader.Text.ToUpperInvariant()))
                {
                    if (m_TexDisplay.CustomShader == ResourceId.Null) { m_CurPixelValue = null; m_CurRealValue = null; UI_UpdateStatusText(); }
                    m_TexDisplay.CustomShader = m_CustomShaders[customShader.Text.ToUpperInvariant()];
                    customDelete.Enabled = customEdit.Enabled = true;
                }
                else
                {
                    customDelete.Enabled = customEdit.Enabled = false;
                }
            }

            m_TexDisplay.FlipY = flip_y.Checked;

            channelStrip.ResumeLayout();

            m_Core.Renderer.BeginInvoke(RT_UpdateAndDisplay);
            m_Core.Renderer.BeginInvoke(RT_UpdateVisualRange);
        }
示例#4
0
        private void UI_OnTextureSelectionChanged(bool newdraw)
        {
            FetchTexture tex = CurrentTexture;

            // reset high-water mark
            m_HighWaterStatusLength = 0;

            if (tex == null) return;

            bool newtex = (m_TexDisplay.texid != tex.ID);

            // save settings for this current texture
            if (m_Core.Config.TextureViewer_PerTexSettings)
            {
                if (!m_TextureSettings.ContainsKey(m_TexDisplay.texid))
                    m_TextureSettings.Add(m_TexDisplay.texid, new TexSettings());

                m_TextureSettings[m_TexDisplay.texid].r = customRed.Checked;
                m_TextureSettings[m_TexDisplay.texid].g = customGreen.Checked;
                m_TextureSettings[m_TexDisplay.texid].b = customBlue.Checked;
                m_TextureSettings[m_TexDisplay.texid].a = customAlpha.Checked;

                m_TextureSettings[m_TexDisplay.texid].displayType = channels.SelectedIndex;
                m_TextureSettings[m_TexDisplay.texid].customShader = customShader.Text;

                m_TextureSettings[m_TexDisplay.texid].depth = depthDisplay.Checked;
                m_TextureSettings[m_TexDisplay.texid].stencil = stencilDisplay.Checked;

                m_TextureSettings[m_TexDisplay.texid].mip = mipLevel.SelectedIndex;
                m_TextureSettings[m_TexDisplay.texid].slice = sliceFace.SelectedIndex;

                m_TextureSettings[m_TexDisplay.texid].minrange = rangeHistogram.BlackPoint;
                m_TextureSettings[m_TexDisplay.texid].maxrange = rangeHistogram.WhitePoint;

                m_TextureSettings[m_TexDisplay.texid].typeHint = m_Following.GetTypeHint(m_Core);
            }

            m_TexDisplay.texid = tex.ID;

            // interpret the texture according to the currently following type.
            if(!CurrentTextureIsLocked)
                m_TexDisplay.typeHint = m_Following.GetTypeHint(m_Core);
            else
                m_TexDisplay.typeHint = FormatComponentType.None;

            // if there is no such type or it isn't being followed, use the last seen interpretation
            if (m_TexDisplay.typeHint == FormatComponentType.None && m_TextureSettings.ContainsKey(m_TexDisplay.texid))
                m_TexDisplay.typeHint = m_TextureSettings[m_TexDisplay.texid].typeHint;

            // try to maintain the pan in the new texture. If the new texture
            // is approx an integer multiple of the old texture, just changing
            // the scale will keep everything the same. This is useful for
            // downsample chains and things where you're flipping back and forth
            // between overlapping textures, but even in the non-integer case
            // pan will be kept approximately the same.
            PointF curSize = new PointF((float)CurrentTexture.width, (float)CurrentTexture.height);
            float curArea = curSize.Area();
            float prevArea = m_PrevSize.Area();

            if (prevArea > 0.0f)
            {
                float prevX = m_TexDisplay.offx;
                float prevY = m_TexDisplay.offy;
                float prevScale = m_TexDisplay.scale;

                // allow slight difference in aspect ratio for rounding errors
                // in downscales (e.g. 1680x1050 -> 840x525 -> 420x262 in the
                // last downscale the ratios are 1.6 and 1.603053435).
                if (Math.Abs(curSize.Aspect() - m_PrevSize.Aspect()) < 0.01f)
                {
                    m_TexDisplay.scale *= m_PrevSize.X / curSize.X;
                    CurrentZoomValue = m_TexDisplay.scale;
                }
                else
                {
                    // this scale factor is arbitrary really, only intention is to have
                    // integer scales come out precisely, other 'similar' sizes will be
                    // similar ish
                    float scaleFactor = (float)(Math.Sqrt(curArea) / Math.Sqrt(prevArea));

                    m_TexDisplay.offx = prevX * scaleFactor;
                    m_TexDisplay.offy = prevY * scaleFactor;
                }
            }

            m_PrevSize = curSize;

            // refresh scroll position
            ScrollPosition = ScrollPosition;

            UI_UpdateStatusText();

            mipLevel.Items.Clear();

            m_TexDisplay.mip = 0;
            m_TexDisplay.sliceFace = 0;

            bool usemipsettings = true;
            bool useslicesettings = true;

            if (tex.msSamp > 1)
            {
                for (int i = 0; i < tex.msSamp; i++)
                    mipLevel.Items.Add(String.Format("Sample {0}", i));

                // add an option to display unweighted average resolved value,
                // to get an idea of how the samples average
                if(tex.format.compType != FormatComponentType.UInt &&
                    tex.format.compType != FormatComponentType.SInt &&
                    tex.format.compType != FormatComponentType.Depth &&
                    (tex.creationFlags & TextureCreationFlags.DSV) == 0)
                    mipLevel.Items.Add("Average val");

                mipLevelLabel.Text = "Sample";

                mipLevel.SelectedIndex = 0;
            }
            else
            {
                for (int i = 0; i < tex.mips; i++)
                    mipLevel.Items.Add(i + " - " + Math.Max(1, tex.width >> i) + "x" + Math.Max(1, tex.height >> i));

                mipLevelLabel.Text = "Mip";

                int highestMip = -1;

                // only switch to the selected mip for outputs, and when changing drawcall
                if (!CurrentTextureIsLocked && m_Following.Type != FollowType.ReadOnly && newdraw)
                    highestMip = m_Following.GetHighestMip(m_Core);

                // assuming we get a valid mip for the highest mip, only switch to it
                // if we've selected a new texture, or if it's different than the last mip.
                // This prevents the case where the user has clicked on another mip and
                // we don't want to snap their view back when stepping between events with the
                // same mip used. But it does mean that if they are stepping between
                // events with different mips used, then we will update in that case.
                if (highestMip >= 0 && (newtex || highestMip != prevHighestMip))
                {
                    usemipsettings = false;
                    mipLevel.SelectedIndex = Helpers.Clamp(highestMip, 0, (int)tex.mips - 1);
                }

                if (mipLevel.SelectedIndex == -1)
                    mipLevel.SelectedIndex = Helpers.Clamp(prevHighestMip, 0, (int)tex.mips - 1);

                prevHighestMip = highestMip;
            }

            if (tex.mips == 1 && tex.msSamp <= 1)
            {
                mipLevel.Enabled = false;
            }
            else
            {
                mipLevel.Enabled = true;
            }

            sliceFace.Items.Clear();

            if (tex.numSubresources == tex.mips && tex.depth <= 1)
            {
                sliceFace.Enabled = false;
            }
            else
            {
                sliceFace.Enabled = true;

                sliceFace.Visible = sliceFaceLabel.Visible = true;

                String[] cubeFaces = { "X+", "X-", "Y+", "Y-", "Z+", "Z-" };

                UInt32 numSlices = (Math.Max(1, tex.depth) * tex.numSubresources) / tex.mips;

                // for 3D textures, display the number of slices at this mip
                if(tex.depth > 1)
                    numSlices = Math.Max(1, tex.depth >> (int)mipLevel.SelectedIndex);

                for (UInt32 i = 0; i < numSlices; i++)
                {
                    if (tex.cubemap)
                    {
                        String name = cubeFaces[i%6];
                        if (numSlices > 6)
                            name = string.Format("[{0}] {1}", (i / 6), cubeFaces[i%6]); // Front 1, Back 2, 3, 4 etc for cube arrays
                        sliceFace.Items.Add(name);
                    }
                    else
                    {
                        sliceFace.Items.Add("Slice " + i);
                    }
                }

                int firstArraySlice = -1;
                // only switch to the selected mip for outputs, and when changing drawcall
                if (!CurrentTextureIsLocked && m_Following.Type != FollowType.ReadOnly && newdraw)
                    firstArraySlice = m_Following.GetFirstArraySlice(m_Core);

                // see above with highestMip and prevHighestMip for the logic behind this
                if (firstArraySlice >= 0 && (newtex || firstArraySlice != prevFirstArraySlice))
                {
                    useslicesettings = false;
                    sliceFace.SelectedIndex = Helpers.Clamp(firstArraySlice, 0, (int)numSlices - 1);
                }

                if (sliceFace.SelectedIndex == -1)
                    sliceFace.SelectedIndex = Helpers.Clamp(prevFirstArraySlice, 0, (int)numSlices - 1);

                prevFirstArraySlice = firstArraySlice;
            }

            // because slice and mip are specially set above, we restore any per-tex settings to apply
            // even if we don't switch to a new texture.
            // Note that if the slice or mip was changed because that slice or mip is the selected one
            // at the API level, we leave this alone.
            if (m_Core.Config.TextureViewer_PerTexSettings && m_TextureSettings.ContainsKey(tex.ID))
            {
                if (usemipsettings)
                    mipLevel.SelectedIndex = m_TextureSettings[tex.ID].mip;

                if (useslicesettings)
                    sliceFace.SelectedIndex = m_TextureSettings[tex.ID].slice;
            }

            // handling for if we've switched to a new texture
            if (newtex)
            {
                // if we save certain settings per-texture, restore them (if we have any)
                if (m_Core.Config.TextureViewer_PerTexSettings && m_TextureSettings.ContainsKey(tex.ID))
                {
                    channels.SelectedIndex = m_TextureSettings[tex.ID].displayType;

                    customShader.Text = m_TextureSettings[tex.ID].customShader;

                    customRed.Checked = m_TextureSettings[tex.ID].r;
                    customGreen.Checked = m_TextureSettings[tex.ID].g;
                    customBlue.Checked = m_TextureSettings[tex.ID].b;
                    customAlpha.Checked = m_TextureSettings[tex.ID].a;

                    depthDisplay.Checked = m_TextureSettings[m_TexDisplay.texid].depth;
                    stencilDisplay.Checked = m_TextureSettings[m_TexDisplay.texid].stencil;

                    norangePaint = true;
                    rangeHistogram.SetRange(m_TextureSettings[m_TexDisplay.texid].minrange, m_TextureSettings[m_TexDisplay.texid].maxrange);
                    norangePaint = false;
                }
                else if (m_Core.Config.TextureViewer_PerTexSettings)
                {
                    // if we are using per-tex settings, reset back to RGB
                    channels.SelectedIndex = 0;

                    customShader.Text = "";

                    customRed.Checked = true;
                    customGreen.Checked = true;
                    customBlue.Checked = true;
                    customAlpha.Checked = false;

                    stencilDisplay.Checked = false;
                    depthDisplay.Checked = true;

                    norangePaint = true;
                    UI_SetHistogramRange(tex, m_TexDisplay.typeHint);
                    norangePaint = false;
                }

                // reset the range if desired
                if (m_Core.Config.TextureViewer_ResetRange)
                {
                    UI_SetHistogramRange(tex, m_TexDisplay.typeHint);
                }
            }

            UI_UpdateFittedScale();

            UI_UpdateTextureDetails();

            UI_UpdateChannels();

            if (autoFit.Checked)
                AutoFitRange();

            m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
            {
                RT_UpdateVisualRange(r);

                RT_UpdateAndDisplay(r);

                if (tex.ID != ResourceId.Null)
                {
                    if (m_Output != null)
                        RT_PickPixelsAndUpdate(m_PickedPoint.X, m_PickedPoint.Y, true);

                    var us = r.GetUsage(tex.ID);

                    var tb = m_Core.TimelineBar;

                    if (tb != null && tb.Visible && !tb.IsDisposed)
                    {
                        this.BeginInvoke(new Action(() =>
                        {
                            tb.HighlightResource(tex.ID, tex.name, us);
                        }));
                    }
                }
                else
                {
                    m_CurPixelValue = null;
                    m_CurRealValue = null;
                }
            });
        }
示例#5
0
        private void RT_UpdatePixelColour(PixelValue withCustom, PixelValue realValue, bool UpdateHover)
        {
            m_CurPixelValue = withCustom;
            if (UpdateHover)
                m_CurHoverValue = withCustom;
            m_CurRealValue = realValue;

            this.BeginInvoke(new Action(UI_UpdateStatusText));
        }
示例#6
0
        private void RT_UpdateHoverColour(PixelValue v)
        {
            m_CurHoverValue = v;

            this.BeginInvoke(new Action(UI_UpdateStatusText));
        }
示例#7
0
        private void UI_OnTextureSelectionChanged()
        {
            FetchTexture tex = CurrentTexture;

            // reset high-water mark
            m_HighWaterStatusLength = 0;

            if (tex == null) return;

            bool newtex = (m_TexDisplay.texid != tex.ID);

            // save settings for this current texture
            if (m_Core.Config.TextureViewer_PerTexSettings)
            {
                if (!m_TextureSettings.ContainsKey(m_TexDisplay.texid))
                    m_TextureSettings.Add(m_TexDisplay.texid, new TexSettings());

                m_TextureSettings[m_TexDisplay.texid].r = customRed.Checked;
                m_TextureSettings[m_TexDisplay.texid].g = customGreen.Checked;
                m_TextureSettings[m_TexDisplay.texid].b = customBlue.Checked;
                m_TextureSettings[m_TexDisplay.texid].a = customAlpha.Checked;

                m_TextureSettings[m_TexDisplay.texid].depth = depthDisplay.Checked;
                m_TextureSettings[m_TexDisplay.texid].stencil = stencilDisplay.Checked;

                m_TextureSettings[m_TexDisplay.texid].mip = mipLevel.SelectedIndex;
                m_TextureSettings[m_TexDisplay.texid].slice = sliceFace.SelectedIndex;
            }

            m_TexDisplay.texid = tex.ID;

            m_CurPixelValue = null;
            m_CurRealValue = null;

            // try to maintain the pan in the new texture. If the new texture
            // is an integer multiple of the old texture, this will keep the
            // top left pixel the same. Due to the difference in scale, the rest
            // of the image will be out though. This is useful for downsample chains and
            // things where you're flipping back and forth between overlapping
            // textures, but really needs a mode where the zoom level is changed
            // to compensate as well.
            float curArea = (float)CurrentTexture.width * (float)CurrentTexture.height;

            if(m_PrevArea > 0.0f)
            {
                float prevX = m_TexDisplay.offx;
                float prevY = m_TexDisplay.offy;

                // this scale factor is arbitrary really, only intention is to have
                // integer scales come out precisely, other 'similar' sizes will be
                // similar ish
                float scaleFactor = (float)(Math.Sqrt(curArea) / Math.Sqrt(m_PrevArea));

                m_TexDisplay.offx = prevX * scaleFactor;
                m_TexDisplay.offy = prevY * scaleFactor;
            }

            m_PrevArea = curArea;

            // refresh scroll position
            ScrollPosition = ScrollPosition;

            UI_UpdateStatusText();

            mipLevel.Items.Clear();
            sliceFace.Items.Clear();

            m_TexDisplay.mip = 0;
            m_TexDisplay.sliceFace = 0;

            bool usemipsettings = true;
            bool useslicesettings = true;

            if (tex.msSamp > 1)
            {
                for (int i = 0; i < tex.msSamp; i++)
                    mipLevel.Items.Add(String.Format("Sample {0}", i));

                // add an option to display unweighted average resolved value,
                // to get an idea of how the samples average
                if(tex.format.compType != FormatComponentType.UInt &&
                    tex.format.compType != FormatComponentType.SInt &&
                    tex.format.compType != FormatComponentType.Depth &&
                    (tex.creationFlags & TextureCreationFlags.DSV) == 0)
                    mipLevel.Items.Add("Average val");

                mipLevelLabel.Text = "Sample";

                mipLevel.SelectedIndex = 0;
            }
            else
            {
                for (int i = 0; i < tex.mips; i++)
                    mipLevel.Items.Add(i + " - " + Math.Max(1, tex.width >> i) + "x" + Math.Max(1, tex.height >> i));

                mipLevelLabel.Text = "Mip";

                int highestMip = m_Following.GetHighestMip(m_Core);
                // assuming we get a valid mip for the highest mip, only switch to it
                // if we've selected a new texture, or if it's different than the last mip.
                // This prevents the case where the user has clicked on another mip and
                // we don't want to snap their view back when stepping between events with the
                // same mip used. But it does mean that if they are stepping between
                // events with different mips used, then we will update in that case.
                if (highestMip >= 0 && (newtex || highestMip != prevHighestMip))
                {
                    usemipsettings = false;
                    mipLevel.SelectedIndex = Helpers.Clamp(highestMip, 0, (int)tex.mips - 1);
                }

                prevHighestMip = highestMip;
            }

            if (tex.mips == 1 && tex.msSamp <= 1)
            {
                mipLevel.Enabled = false;
            }
            else
            {
                mipLevel.Enabled = true;
            }

            if (tex.numSubresources == tex.mips && tex.depth <= 1)
            {
                sliceFace.Enabled = false;
            }
            else
            {
                sliceFace.Enabled = true;

                sliceFace.Visible = sliceFaceLabel.Visible = true;

                String[] cubeFaces = { "X+", "X-", "Y+", "Y-", "Z+", "Z-" };

                UInt32 numSlices = (Math.Max(1, tex.depth) * tex.numSubresources) / tex.mips;

                for (UInt32 i = 0; i < numSlices; i++)
                {
                    if (tex.cubemap)
                    {
                        String name = cubeFaces[i%6];
                        if (numSlices > 6)
                            name = string.Format("[{0}] {1}", (i / 6), cubeFaces[i%6]); // Front 1, Back 2, 3, 4 etc for cube arrays
                        sliceFace.Items.Add(name);
                    }
                    else
                    {
                        sliceFace.Items.Add("Slice " + i);
                    }
                }

                int firstArraySlice = m_Following.GetFirstArraySlice(m_Core);
                // see above with highestMip and prevHighestMip for the logic behind this
                if (firstArraySlice >= 0 && (newtex || firstArraySlice != prevFirstArraySlice))
                {
                    useslicesettings = false;
                    sliceFace.SelectedIndex = Helpers.Clamp(firstArraySlice, 0, (int)numSlices - 1);
                }

                prevFirstArraySlice = firstArraySlice;
            }

            // because slice and mip are specially set above, we restore any per-tex settings to apply
            // even if we don't switch to a new texture.
            // Note that if the slice or mip was changed because that slice or mip is the selected one
            // at the API level, we leave this alone.
            if (m_Core.Config.TextureViewer_PerTexSettings && m_TextureSettings.ContainsKey(tex.ID))
            {
                if (usemipsettings)
                    mipLevel.SelectedIndex = m_TextureSettings[tex.ID].mip;

                if (useslicesettings)
                    sliceFace.SelectedIndex = m_TextureSettings[tex.ID].slice;
            }

            // handling for if we've switched to a new texture
            if (newtex)
            {
                // if we save certain settings per-texture, restore them (if we have any)
                if (m_Core.Config.TextureViewer_PerTexSettings && m_TextureSettings.ContainsKey(tex.ID))
                {
                    customRed.Checked = m_TextureSettings[tex.ID].r;
                    customGreen.Checked = m_TextureSettings[tex.ID].g;
                    customBlue.Checked = m_TextureSettings[tex.ID].b;
                    customAlpha.Checked = m_TextureSettings[tex.ID].a;

                    depthDisplay.Checked = m_TextureSettings[m_TexDisplay.texid].depth;
                    stencilDisplay.Checked = m_TextureSettings[m_TexDisplay.texid].stencil;
                }
                else if (m_Core.Config.TextureViewer_PerTexSettings)
                {
                    // if we are using per-tex settings, reset back to RGB
                    customRed.Checked = true;
                    customGreen.Checked = true;
                    customBlue.Checked = true;
                    customAlpha.Checked = false;

                    stencilDisplay.Checked = false;
                    depthDisplay.Checked = true;
                }

                // reset the range if desired
                if (m_Core.Config.TextureViewer_ResetRange)
                {
                    rangeHistogram.SetRange(0.0f, 1.0f);
                }
            }

            UI_UpdateFittedScale();

            //render.Width = (int)(CurrentTexDisplayWidth * m_TexDisplay.scale);
            //render.Height = (int)(CurrentTexDisplayHeight * m_TexDisplay.scale);

            UI_UpdateTextureDetails();

            UI_UpdateChannels();

            if (autoFit.Checked)
                AutoFitRange();

            m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
            {
                RT_UpdateVisualRange(r);

                RT_UpdateAndDisplay(r);

                if (tex.ID != ResourceId.Null)
                {
                    var us = r.GetUsage(tex.ID);

                    var tb = m_Core.TimelineBar;

                    if (tb != null && tb.Visible && !tb.IsDisposed)
                    {
                        this.BeginInvoke(new Action(() =>
                        {
                            tb.HighlightResource(tex.ID, tex.name, us);
                        }));
                    }
                }
            });
        }
示例#8
0
        private void UI_UpdateChannels()
        {
            FetchTexture tex = CurrentTexture;

            channelStrip.SuspendLayout();

            if (tex != null && (tex.creationFlags & TextureCreationFlags.DSV) > 0 &&
                (string)channels.SelectedItem != "Custom")
            {
                customRed.Visible = false;
                customGreen.Visible = false;
                customBlue.Visible = false;
                customAlpha.Visible = false;
                mulLabel.Visible = false;
                hdrMul.Visible = false;
                customShader.Visible = false;
                customCreate.Visible = false;
                customEdit.Visible = false;
                customDelete.Visible = false;
                depthStencilToolstrip.Visible = true;

                backcolorPick.Visible = false;
                checkerBack.Visible = false;

                mulSep.Visible = false;

                m_TexDisplay.Red = depthDisplay.Checked;
                m_TexDisplay.Green = stencilDisplay.Checked;
                m_TexDisplay.Blue = false;
                m_TexDisplay.Alpha = false;

                m_TexDisplay.HDRMul = -1.0f;
                if (m_TexDisplay.CustomShader != ResourceId.Null) { m_CurPixelValue = null; m_CurRealValue = null; UI_UpdateStatusText(); }
                m_TexDisplay.CustomShader = ResourceId.Null;
            }
            else if ((string)channels.SelectedItem == "RGBA" || !m_Core.LogLoaded)
            {
                customRed.Visible = true;
                customGreen.Visible = true;
                customBlue.Visible = true;
                customAlpha.Visible = true;
                mulLabel.Visible = false;
                hdrMul.Visible = false;
                customShader.Visible = false;
                customCreate.Visible = false;
                customEdit.Visible = false;
                customDelete.Visible = false;
                depthStencilToolstrip.Visible = false;

                backcolorPick.Visible = true;
                checkerBack.Visible = true;

                checkerBack.Enabled = backcolorPick.Enabled = customAlpha.Checked;

                mulSep.Visible = false;

                m_TexDisplay.Red = customRed.Checked;
                m_TexDisplay.Green = customGreen.Checked;
                m_TexDisplay.Blue = customBlue.Checked;
                m_TexDisplay.Alpha = customAlpha.Checked;

                m_TexDisplay.HDRMul = -1.0f;
                if (m_TexDisplay.CustomShader != ResourceId.Null) { m_CurPixelValue = null; m_CurRealValue = null; UI_UpdateStatusText(); }
                m_TexDisplay.CustomShader = ResourceId.Null;
            }
            else if ((string)channels.SelectedItem == "RGBM")
            {
                customRed.Visible = true;
                customGreen.Visible = true;
                customBlue.Visible = true;
                customAlpha.Visible = false;
                mulLabel.Visible = true;
                hdrMul.Visible = true;
                customShader.Visible = false;
                customCreate.Visible = false;
                customEdit.Visible = false;
                customDelete.Visible = false;
                depthStencilToolstrip.Visible = false;

                backcolorPick.Visible = false;
                checkerBack.Visible = false;

                mulSep.Visible = true;

                m_TexDisplay.Red = customRed.Checked;
                m_TexDisplay.Green = customGreen.Checked;
                m_TexDisplay.Blue = customBlue.Checked;
                m_TexDisplay.Alpha = false;

                float mul = 32.0f;

                if (!float.TryParse(hdrMul.Text, out mul))
                    hdrMul.Text = mul.ToString();

                m_TexDisplay.HDRMul = mul;
                if (m_TexDisplay.CustomShader != ResourceId.Null) { m_CurPixelValue = null; m_CurRealValue = null; UI_UpdateStatusText(); }
                m_TexDisplay.CustomShader = ResourceId.Null;
            }
            else if ((string)channels.SelectedItem == "Custom")
            {
                customRed.Visible = false;
                customGreen.Visible = false;
                customBlue.Visible = false;
                customAlpha.Visible = false;
                mulLabel.Visible = false;
                hdrMul.Visible = false;
                customShader.Visible = true;
                customCreate.Visible = true;
                customEdit.Visible = true;
                customDelete.Visible = true;
                depthStencilToolstrip.Visible = false;

                backcolorPick.Visible = false;
                checkerBack.Visible = false;

                mulSep.Visible = false;

                m_TexDisplay.Red = customRed.Checked;
                m_TexDisplay.Green = customGreen.Checked;
                m_TexDisplay.Blue = customBlue.Checked;
                m_TexDisplay.Alpha = customAlpha.Checked;

                m_TexDisplay.HDRMul = -1.0f;

                m_TexDisplay.CustomShader = ResourceId.Null;
                if (m_CustomShaders.ContainsKey(customShader.Text.ToLowerInvariant()))
                {
                    if (m_TexDisplay.CustomShader == ResourceId.Null) { m_CurPixelValue = null; m_CurRealValue = null; UI_UpdateStatusText(); }
                    m_TexDisplay.CustomShader = m_CustomShaders[customShader.Text.ToLowerInvariant()];
                    customDelete.Enabled = customEdit.Enabled = true;
                    customCreate.Enabled = false;
                }
                else
                {
                    customDelete.Enabled = customEdit.Enabled = false;
                    customCreate.Enabled = true;
                }
            }

            channelStrip.ResumeLayout();

            m_Core.Renderer.BeginInvoke(RT_UpdateAndDisplay);
            m_Core.Renderer.BeginInvoke(RT_UpdateVisualRange);
        }
示例#9
0
        private void UI_OnTextureSelectionChanged()
        {
            FetchTexture tex = CurrentTexture;

            if (tex == null) return;

            if (m_TexDisplay.texid != tex.ID &&
                m_Core.Config.TextureViewer_ResetRange)
            {
                rangeHistogram.RangeMin = 0.0f;
                rangeHistogram.RangeMax = 1.0f;
                rangeHistogram.BlackPoint = 0.0f;
                rangeHistogram.WhitePoint = 1.0f;
            }

            m_TexDisplay.texid = tex.ID;

            m_CurPixelValue = null;
            m_CurRealValue = null;

            ScrollPosition = ScrollPosition;

            UI_UpdateStatusText();

            mipLevel.Items.Clear();
            sliceFace.Items.Clear();

            for (int i = 0; i < tex.mips; i++)
                mipLevel.Items.Add(i + " - " + Math.Max(1, tex.width >> i) + "x" + Math.Max(1, tex.height >> i));

            mipLevel.SelectedIndex = 0;
            m_TexDisplay.mip = 0;
            m_TexDisplay.sliceFace = 0;

            if (tex.mips == 1)
            {
                mipLevel.Enabled = false;
            }
            else
            {
                mipLevel.Enabled = true;
            }

            if (tex.numSubresources == tex.mips && tex.depth <= 1)
            {
                sliceFace.Enabled = false;
            }
            else
            {
                sliceFace.Enabled = true;

                sliceFace.Visible = sliceFaceLabel.Visible = true;

                String[] cubeFaces = { "X+", "X-", "Y+", "Y-", "Z+", "Z-" };

                UInt32 numSlices = (Math.Max(1, tex.depth) * tex.numSubresources) / tex.mips;

                for (UInt32 i = 0; i < numSlices; i++)
                {
                    if (tex.cubemap)
                    {
                        String name = cubeFaces[i%6];
                        if (numSlices > 6)
                            name = string.Format("[{0}] {1}", (i / 6), cubeFaces[i%6]); // Front 1, Back 2, 3, 4 etc for cube arrays
                        sliceFace.Items.Add(name);
                    }
                    else
                    {
                        sliceFace.Items.Add("Slice " + i);
                    }
                }

                sliceFace.SelectedIndex = (int)m_Following.GetFirstArraySlice(m_Core);
            }

            UI_UpdateFittedScale();

            //render.Width = (int)(CurrentTexDisplayWidth * m_TexDisplay.scale);
            //render.Height = (int)(CurrentTexDisplayHeight * m_TexDisplay.scale);

            UI_UpdateTextureDetails();

            UI_UpdateChannels();

            m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
            {
                RT_UpdateVisualRange(r);

                RT_UpdateAndDisplay(r);

                if (tex.ID != ResourceId.Null)
                {
                    var us = r.GetUsage(tex.ID);

                    var tb = m_Core.TimelineBar;

                    if (tb != null && tb.Visible && !tb.IsDisposed)
                    {
                        this.BeginInvoke(new Action(() =>
                        {
                            tb.HighlightResource(tex.ID, tex.name, us);
                        }));
                    }
                }
            });
        }
示例#10
0
        public bool GetMinMax(ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, out PixelValue minval, out PixelValue maxval)
        {
            IntPtr mem1 = CustomMarshal.Alloc(typeof(PixelValue));
            IntPtr mem2 = CustomMarshal.Alloc(typeof(PixelValue));

            bool success = ReplayRenderer_GetMinMax(m_Real, tex, sliceFace, mip, sample, mem1, mem2);

            if (success)
            {
                minval = (PixelValue)CustomMarshal.PtrToStructure(mem1, typeof(PixelValue), true);
                maxval = (PixelValue)CustomMarshal.PtrToStructure(mem2, typeof(PixelValue), true);
            }
            else
            {
                minval = null;
                maxval = null;
            }

            CustomMarshal.Free(mem1);
            CustomMarshal.Free(mem2);

            return success;
        }
示例#11
0
        private void UI_OnTextureSelectionChanged()
        {
            FetchTexture tex = CurrentTexture;

            if (tex == null) return;

            bool newtex = (m_TexDisplay.texid != tex.ID);

            // save settings for this current texture
            if (m_Core.Config.TextureViewer_PerTexSettings)
            {
                if (!m_TextureSettings.ContainsKey(m_TexDisplay.texid))
                    m_TextureSettings.Add(m_TexDisplay.texid, new TexSettings());

                m_TextureSettings[m_TexDisplay.texid].r = customRed.Checked;
                m_TextureSettings[m_TexDisplay.texid].g = customGreen.Checked;
                m_TextureSettings[m_TexDisplay.texid].b = customBlue.Checked;
                m_TextureSettings[m_TexDisplay.texid].a = customAlpha.Checked;

                m_TextureSettings[m_TexDisplay.texid].depth = depthDisplay.Checked;
                m_TextureSettings[m_TexDisplay.texid].stencil = stencilDisplay.Checked;

                m_TextureSettings[m_TexDisplay.texid].mip = mipLevel.SelectedIndex;
                m_TextureSettings[m_TexDisplay.texid].slice = sliceFace.SelectedIndex;
            }

            m_TexDisplay.texid = tex.ID;

            m_CurPixelValue = null;
            m_CurRealValue = null;

            ScrollPosition = ScrollPosition;

            UI_UpdateStatusText();

            mipLevel.Items.Clear();
            sliceFace.Items.Clear();

            if (tex.msSamp > 1)
            {
                for (int i = 0; i < tex.msSamp; i++)
                    mipLevel.Items.Add(String.Format("Sample {0}", i));

                // add an option to display unweighted average resolved value,
                // to get an idea of how the samples average
                if(tex.format.compType != FormatComponentType.UInt &&
                    tex.format.compType != FormatComponentType.SInt &&
                    tex.format.compType != FormatComponentType.Depth &&
                    (tex.creationFlags & TextureCreationFlags.DSV) == 0)
                    mipLevel.Items.Add("Average val");

                mipLevelLabel.Text = "Sample";
            }
            else
            {
                for (int i = 0; i < tex.mips; i++)
                    mipLevel.Items.Add(i + " - " + Math.Max(1, tex.width >> i) + "x" + Math.Max(1, tex.height >> i));

                mipLevelLabel.Text = "Mip";
            }

            mipLevel.SelectedIndex = 0;
            m_TexDisplay.mip = 0;
            m_TexDisplay.sliceFace = 0;

            if (tex.mips == 1 && tex.msSamp <= 1)
            {
                mipLevel.Enabled = false;
            }
            else
            {
                mipLevel.Enabled = true;
            }

            if (tex.numSubresources == tex.mips && tex.depth <= 1)
            {
                sliceFace.Enabled = false;
            }
            else
            {
                sliceFace.Enabled = true;

                sliceFace.Visible = sliceFaceLabel.Visible = true;

                String[] cubeFaces = { "X+", "X-", "Y+", "Y-", "Z+", "Z-" };

                UInt32 numSlices = (Math.Max(1, tex.depth) * tex.numSubresources) / tex.mips;

                for (UInt32 i = 0; i < numSlices; i++)
                {
                    if (tex.cubemap)
                    {
                        String name = cubeFaces[i%6];
                        if (numSlices > 6)
                            name = string.Format("[{0}] {1}", (i / 6), cubeFaces[i%6]); // Front 1, Back 2, 3, 4 etc for cube arrays
                        sliceFace.Items.Add(name);
                    }
                    else
                    {
                        sliceFace.Items.Add("Slice " + i);
                    }
                }

                int firstArraySlice = (int)m_Following.GetFirstArraySlice(m_Core);
                sliceFace.SelectedIndex = Helpers.Clamp(firstArraySlice, 0, (int)numSlices - 1);
            }

            // mip and slice were reset to 0 above, we must restore any per-tex settings to apply
            // even if we don't switch to a new texture
            if (m_Core.Config.TextureViewer_PerTexSettings && m_TextureSettings.ContainsKey(tex.ID))
            {
                mipLevel.SelectedIndex = m_TextureSettings[tex.ID].mip;
                sliceFace.SelectedIndex = m_TextureSettings[tex.ID].slice;
            }

            // handling for if we've switched to a new texture
            if (newtex)
            {
                // if we save certain settings per-texture, restore them (if we have any)
                if (m_Core.Config.TextureViewer_PerTexSettings && m_TextureSettings.ContainsKey(tex.ID))
                {
                    customRed.Checked = m_TextureSettings[tex.ID].r;
                    customGreen.Checked = m_TextureSettings[tex.ID].g;
                    customBlue.Checked = m_TextureSettings[tex.ID].b;
                    customAlpha.Checked = m_TextureSettings[tex.ID].a;

                    depthDisplay.Checked = m_TextureSettings[m_TexDisplay.texid].depth;
                    stencilDisplay.Checked = m_TextureSettings[m_TexDisplay.texid].stencil;
                }
                else if (m_Core.Config.TextureViewer_PerTexSettings)
                {
                    // if we are using per-tex settings, reset back to RGB
                    customRed.Checked = true;
                    customGreen.Checked = true;
                    customBlue.Checked = true;
                    customAlpha.Checked = false;

                    stencilDisplay.Checked = false;
                    depthDisplay.Checked = true;
                }

                // reset the range if desired
                if (m_Core.Config.TextureViewer_ResetRange)
                {
                    rangeHistogram.RangeMin = 0.0f;
                    rangeHistogram.RangeMax = 1.0f;
                    rangeHistogram.BlackPoint = 0.0f;
                    rangeHistogram.WhitePoint = 1.0f;
                }
            }

            UI_UpdateFittedScale();

            //render.Width = (int)(CurrentTexDisplayWidth * m_TexDisplay.scale);
            //render.Height = (int)(CurrentTexDisplayHeight * m_TexDisplay.scale);

            UI_UpdateTextureDetails();

            UI_UpdateChannels();

            m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
            {
                RT_UpdateVisualRange(r);

                RT_UpdateAndDisplay(r);

                if (tex.ID != ResourceId.Null)
                {
                    var us = r.GetUsage(tex.ID);

                    var tb = m_Core.TimelineBar;

                    if (tb != null && tb.Visible && !tb.IsDisposed)
                    {
                        this.BeginInvoke(new Action(() =>
                        {
                            tb.HighlightResource(tex.ID, tex.name, us);
                        }));
                    }
                }
            });
        }
示例#12
0
        public bool GetMinMax(out PixelValue minval, out PixelValue maxval)
        {
            IntPtr mem1 = CustomMarshal.Alloc(typeof(PixelValue));
            IntPtr mem2 = CustomMarshal.Alloc(typeof(PixelValue));

            bool success = ReplayOutput_GetMinMax(m_Real, mem1, mem2);

            if (success)
            {
                minval = (PixelValue)CustomMarshal.PtrToStructure(mem1, typeof(PixelValue), true);
                maxval = (PixelValue)CustomMarshal.PtrToStructure(mem2, typeof(PixelValue), true);
            }
            else
            {
                minval = null;
                maxval = null;
            }

            CustomMarshal.Free(mem1);
            CustomMarshal.Free(mem2);

            return success;
        }