mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-25 07:05:48 +00:00
Merge pull request #103 from valeriog-crytek/master
Some missing GL replay features
This commit is contained in:
@@ -89,6 +89,43 @@ struct GLPipelineState
|
||||
};
|
||||
rdctype::array<Buffer> UniformBuffers;
|
||||
|
||||
struct Rasterizer
|
||||
{
|
||||
struct Viewport
|
||||
{
|
||||
Viewport() : Left(0.0f), Bottom(0.0f), Width(0.0f), Height(0.0f), MinDepth(0.0f), MaxDepth(0.0f) {}
|
||||
float Left, Bottom;
|
||||
float Width, Height;
|
||||
double MinDepth, MaxDepth;
|
||||
};
|
||||
rdctype::array<Viewport> Viewports;
|
||||
|
||||
struct Scissor
|
||||
{
|
||||
Scissor() : Left(0), Bottom(0), Width(0), Height(0), Enabled(false) {}
|
||||
int32_t Left, Bottom;
|
||||
int32_t Width, Height;
|
||||
bool32 Enabled;
|
||||
};
|
||||
rdctype::array<Scissor> Scissors;
|
||||
|
||||
struct RasterizerState
|
||||
{
|
||||
RasterizerState()
|
||||
: FillMode(eFill_Solid), CullMode(eCull_None), FrontCCW(false), DepthBias(0),
|
||||
SlopeScaledDepthBias(0.0f), DepthClamp(false),
|
||||
MultisampleEnable(false), AntialiasedLineEnable(false) {}
|
||||
TriangleFillMode FillMode;
|
||||
TriangleCullMode CullMode;
|
||||
bool32 FrontCCW;
|
||||
float DepthBias;
|
||||
float SlopeScaledDepthBias;
|
||||
bool32 DepthClamp;
|
||||
bool32 MultisampleEnable;
|
||||
bool32 AntialiasedLineEnable;
|
||||
} m_State;
|
||||
} m_Rasterizer;
|
||||
|
||||
struct FrameBuffer
|
||||
{
|
||||
FrameBuffer() : FBO(), Depth(), Stencil() {}
|
||||
|
||||
@@ -346,6 +346,7 @@ enum TriangleFillMode
|
||||
{
|
||||
eFill_Solid = 0,
|
||||
eFill_Wireframe,
|
||||
eFill_Point,
|
||||
};
|
||||
|
||||
enum TriangleCullMode
|
||||
@@ -353,6 +354,7 @@ enum TriangleCullMode
|
||||
eCull_None = 0,
|
||||
eCull_Front,
|
||||
eCull_Back,
|
||||
eCull_FrontAndBack,
|
||||
};
|
||||
|
||||
enum ReplayCreateStatus
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Crytek
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
// use some preprocessor hacks to compile the same header in both GLSL and C++ so we can define
|
||||
// classes that represent a whole cbuffer
|
||||
#if defined(__cplusplus)
|
||||
|
||||
#define uniform struct
|
||||
#define vec2 Vec2f
|
||||
#define vec3 Vec3f
|
||||
#define vec4 Vec4f
|
||||
|
||||
#define BINDING(b)
|
||||
|
||||
#else
|
||||
|
||||
#version 420 core
|
||||
|
||||
#define BINDING(b) layout (binding = b, std140)
|
||||
|
||||
#endif
|
||||
|
||||
BINDING(0) uniform texdisplay
|
||||
{
|
||||
vec2 Position;
|
||||
float Scale;
|
||||
float HDRMul;
|
||||
|
||||
vec4 Channels;
|
||||
|
||||
float RangeMinimum;
|
||||
float InverseRangeSize;
|
||||
float MipLevel;
|
||||
int FlipY;
|
||||
|
||||
vec3 TextureResolutionPS;
|
||||
int OutputDisplayFormat;
|
||||
|
||||
vec2 OutputRes;
|
||||
int RawOutput;
|
||||
float Slice;
|
||||
};
|
||||
|
||||
// some constants available to both C++ and GLSL for configuring display
|
||||
#define CUBEMAP_FACE_POS_X 0
|
||||
#define CUBEMAP_FACE_NEG_X 1
|
||||
#define CUBEMAP_FACE_POS_Y 2
|
||||
#define CUBEMAP_FACE_NEG_Y 3
|
||||
#define CUBEMAP_FACE_POS_Z 4
|
||||
#define CUBEMAP_FACE_NEG_Z 5
|
||||
|
||||
#define RESTYPE_TEX1D 0x1
|
||||
#define RESTYPE_TEX2D 0x2
|
||||
#define RESTYPE_TEX3D 0x3
|
||||
#define RESTYPE_TEXCUBE 0x4
|
||||
#define RESTYPE_TEX1DARRAY 0x5
|
||||
#define RESTYPE_TEX2DARRAY 0x6
|
||||
#define RESTYPE_TEXCUBEARRAY 0x7
|
||||
|
||||
#define TEXDISPLAY_TYPEMASK 0x7
|
||||
#define TEXDISPLAY_UINT_TEX 0x8
|
||||
#define TEXDISPLAY_SINT_TEX 0x10
|
||||
|
||||
@@ -22,52 +22,269 @@
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#version 420 core
|
||||
layout (binding = 1) uniform sampler1D tex1D;
|
||||
layout (binding = 2) uniform sampler2D tex2D;
|
||||
layout (binding = 3) uniform sampler3D tex3D;
|
||||
layout (binding = 4) uniform samplerCube texCube;
|
||||
layout (binding = 5) uniform sampler1DArray tex1DArray;
|
||||
layout (binding = 6) uniform sampler2DArray tex2DArray;
|
||||
layout (binding = 7) uniform samplerCubeArray texCubeArray;
|
||||
|
||||
layout (binding = 0, std140) uniform texdisplay
|
||||
{
|
||||
vec2 Position;
|
||||
float Scale;
|
||||
float HDRMul;
|
||||
layout (binding = 9) uniform usampler1D texUInt1D;
|
||||
layout (binding = 10) uniform usampler2D texUInt2D;
|
||||
layout (binding = 11) uniform usampler3D texUInt3D;
|
||||
layout (binding = 13) uniform usampler1DArray texUInt1DArray;
|
||||
layout (binding = 14) uniform usampler2DArray texUInt2DArray;
|
||||
|
||||
vec4 Channels;
|
||||
layout (binding = 16) uniform isampler1D texSInt1D;
|
||||
layout (binding = 17) uniform isampler2D texSInt2D;
|
||||
layout (binding = 18) uniform isampler3D texSInt3D;
|
||||
layout (binding = 20) uniform isampler1DArray texSInt1DArray;
|
||||
layout (binding = 21) uniform isampler2DArray texSInt2DArray;
|
||||
|
||||
float RangeMinimum;
|
||||
float InverseRangeSize;
|
||||
float MipLevel;
|
||||
int FlipY;
|
||||
|
||||
vec3 TextureResolutionPS;
|
||||
int OutputDisplayFormat;
|
||||
|
||||
vec2 OutputRes;
|
||||
int RawOutput;
|
||||
float Slice;
|
||||
};
|
||||
|
||||
layout (binding = 0) uniform sampler2D tex0;
|
||||
layout (location = 0) out vec4 color_out;
|
||||
|
||||
vec3 CalcCubeCoord(vec2 uv, int face)
|
||||
{
|
||||
// Map UVs to [-0.5, 0.5] and rotate
|
||||
uv -= vec2(0.5);
|
||||
vec3 coord;
|
||||
if (face == CUBEMAP_FACE_POS_X)
|
||||
coord = vec3(0.5, uv.y, -uv.x);
|
||||
else if (face == CUBEMAP_FACE_NEG_X)
|
||||
coord = vec3(-0.5, -uv.y, uv.x);
|
||||
else if (face == CUBEMAP_FACE_POS_Y)
|
||||
coord = vec3(uv.x, 0.5, uv.y);
|
||||
else if (face == CUBEMAP_FACE_NEG_Y)
|
||||
coord = vec3(uv.x, -0.5, -uv.y);
|
||||
else if (face == CUBEMAP_FACE_POS_Z)
|
||||
coord = vec3(uv.x, -uv.y, 0.5);
|
||||
else // face == CUBEMAP_FACE_NEG_Z
|
||||
coord = vec3(-uv.x, -uv.y, -0.5);
|
||||
return coord;
|
||||
}
|
||||
|
||||
uvec4 SampleTextureUInt4(vec2 pos, int type, bool flipY, int mipLevel, float slice)
|
||||
{
|
||||
uvec4 col;
|
||||
if (type == RESTYPE_TEX1D)
|
||||
{
|
||||
int size = textureSize(texUInt1D, mipLevel);
|
||||
if (pos.x < 0 || pos.y < 0 || pos.x > size) discard;
|
||||
|
||||
col = texelFetch(texUInt1D, int(pos.x), mipLevel);
|
||||
}
|
||||
else if (type == RESTYPE_TEX1DARRAY)
|
||||
{
|
||||
ivec2 size = textureSize(texUInt1DArray, mipLevel);
|
||||
if (pos.x < 0 || pos.y < 0 || pos.x > size.x) discard;
|
||||
|
||||
col = texelFetch(texUInt1DArray, ivec2(pos.x, slice), mipLevel);
|
||||
}
|
||||
else if (type == RESTYPE_TEX2D)
|
||||
{
|
||||
ivec2 size = textureSize(texUInt2D, mipLevel);
|
||||
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
|
||||
|
||||
if (flipY)
|
||||
pos.y = size.y - pos.y;
|
||||
|
||||
col = texelFetch(texUInt2D, ivec2(pos), mipLevel);
|
||||
}
|
||||
else if (type == RESTYPE_TEX2DARRAY)
|
||||
{
|
||||
ivec3 size = textureSize(texUInt2DArray, mipLevel);
|
||||
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
|
||||
|
||||
col = texelFetch(texUInt2DArray, ivec3(pos, slice), mipLevel);
|
||||
}
|
||||
else // if (type == RESTYPE_TEX3D)
|
||||
{
|
||||
ivec3 size = textureSize(texUInt3D, mipLevel);
|
||||
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
|
||||
|
||||
col = texelFetch(texUInt3D, ivec3(pos, slice), mipLevel);
|
||||
}
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
ivec4 SampleTextureSInt4(vec2 pos, int type, bool flipY, int mipLevel, float slice)
|
||||
{
|
||||
ivec4 col;
|
||||
if (type == RESTYPE_TEX1D)
|
||||
{
|
||||
int size = textureSize(texSInt1D, mipLevel);
|
||||
if (pos.x < 0 || pos.y < 0 || pos.x > size) discard;
|
||||
|
||||
col = texelFetch(texSInt1D, int(pos.x), mipLevel);
|
||||
}
|
||||
else if (type == RESTYPE_TEX1DARRAY)
|
||||
{
|
||||
ivec2 size = textureSize(texSInt1DArray, mipLevel);
|
||||
if (pos.x < 0 || pos.y < 0 || pos.x > size.x) discard;
|
||||
|
||||
col = texelFetch(texSInt1DArray, ivec2(pos.x, slice), mipLevel);
|
||||
}
|
||||
else if (type == RESTYPE_TEX2D)
|
||||
{
|
||||
ivec2 size = textureSize(texSInt2D, mipLevel);
|
||||
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
|
||||
|
||||
if (flipY)
|
||||
pos.y = size.y - pos.y;
|
||||
|
||||
col = texelFetch(texSInt2D, ivec2(pos), mipLevel);
|
||||
}
|
||||
else if (type == RESTYPE_TEX2DARRAY)
|
||||
{
|
||||
ivec3 size = textureSize(texSInt2DArray, mipLevel);
|
||||
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
|
||||
|
||||
col = texelFetch(texSInt2DArray, ivec3(pos, slice), mipLevel);
|
||||
}
|
||||
else // if (type == RESTYPE_TEX3D)
|
||||
{
|
||||
ivec3 size = textureSize(texSInt3D, mipLevel);
|
||||
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
|
||||
|
||||
col = texelFetch(texSInt3D, ivec3(pos, slice), mipLevel);
|
||||
}
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
|
||||
vec4 SampleTextureFloat4(vec2 pos, int type, bool flipY, bool linearSample, int mipLevel, float slice)
|
||||
{
|
||||
vec4 col;
|
||||
if (type == RESTYPE_TEX1D)
|
||||
{
|
||||
int size = textureSize(tex1D, mipLevel);
|
||||
if (pos.x < 0 || pos.y < 0 || pos.x > size) discard;
|
||||
|
||||
if (linearSample)
|
||||
col = texture(tex1D, pos.x / size);
|
||||
else
|
||||
col = texelFetch(tex1D, int(pos.x), mipLevel);
|
||||
}
|
||||
else if (type == RESTYPE_TEX1DARRAY)
|
||||
{
|
||||
ivec2 size = textureSize(tex1DArray, mipLevel);
|
||||
if (pos.x < 0 || pos.y < 0 || pos.x > size.x) discard;
|
||||
|
||||
if (linearSample)
|
||||
col = texture(tex1DArray, vec2(pos.x / size.x, slice));
|
||||
else
|
||||
col = texelFetch(tex1DArray, ivec2(pos.x, slice), mipLevel);
|
||||
}
|
||||
else if (type == RESTYPE_TEX2D)
|
||||
{
|
||||
ivec2 size = textureSize(tex2D, mipLevel);
|
||||
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
|
||||
|
||||
if (flipY)
|
||||
pos.y = size.y - pos.y;
|
||||
|
||||
if (linearSample)
|
||||
col = texture(tex2D, pos / size);
|
||||
else
|
||||
col = texelFetch(tex2D, ivec2(pos), mipLevel);
|
||||
}
|
||||
else if (type == RESTYPE_TEX2DARRAY)
|
||||
{
|
||||
ivec3 size = textureSize(tex2DArray, mipLevel);
|
||||
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
|
||||
|
||||
if (flipY)
|
||||
pos.y = size.y - pos.y;
|
||||
|
||||
if (linearSample)
|
||||
col = texture(tex2DArray, vec3(pos / size.xy, slice));
|
||||
else
|
||||
col = texelFetch(tex2DArray, ivec3(pos, slice), mipLevel);
|
||||
}
|
||||
else if (type == RESTYPE_TEX3D)
|
||||
{
|
||||
ivec3 size = textureSize(tex3D, mipLevel);
|
||||
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
|
||||
|
||||
if (flipY)
|
||||
pos.y = size.y - pos.y;
|
||||
|
||||
if (linearSample)
|
||||
col = texture(tex3D, vec3(pos / size.xy, slice));
|
||||
else
|
||||
col = texelFetch(tex3D, ivec3(pos, slice), mipLevel);
|
||||
}
|
||||
else if (type == RESTYPE_TEXCUBE)
|
||||
{
|
||||
ivec2 size = textureSize(texCube, mipLevel);
|
||||
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
|
||||
|
||||
if (flipY)
|
||||
pos.y = size.y - pos.y;
|
||||
|
||||
vec3 cubeCoord = CalcCubeCoord(pos / size, int(slice));
|
||||
|
||||
if (linearSample)
|
||||
col = texture(texCube, cubeCoord);
|
||||
else
|
||||
col = textureLod(texCube, cubeCoord, mipLevel);
|
||||
}
|
||||
else // type == RESTYPE_TEXCUBEARRAY
|
||||
{
|
||||
ivec3 size = textureSize(texCubeArray, mipLevel);
|
||||
if (pos.x < 0 || pos.y < 0 || pos.x > size.x || pos.y > size.y) discard;
|
||||
|
||||
if (flipY)
|
||||
pos.y = size.y - pos.y;
|
||||
|
||||
vec3 cubeCoord = CalcCubeCoord(pos / size.xy, int(slice) % 6);
|
||||
vec4 arrayCoord = vec4(cubeCoord, int(Slice) / 6);
|
||||
|
||||
if (linearSample)
|
||||
col = texture(texCubeArray, arrayCoord);
|
||||
else
|
||||
col = textureLod(texCubeArray, arrayCoord, mipLevel);
|
||||
}
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
bool uintTex = (OutputDisplayFormat & TEXDISPLAY_UINT_TEX) != 0;
|
||||
bool sintTex = (OutputDisplayFormat & TEXDISPLAY_SINT_TEX) != 0;
|
||||
|
||||
vec4 col;
|
||||
uvec4 ucol;
|
||||
ivec4 scol;
|
||||
|
||||
// calc screen co-ords with origin top left, modified by Position
|
||||
vec2 scr = vec2(gl_FragCoord.x, OutputRes.y - gl_FragCoord.y) - Position.xy;
|
||||
|
||||
// calc UVs in texture
|
||||
vec2 uv = scr/(textureSize(tex0,0)*Scale);
|
||||
|
||||
// discard if we're rendering outside input texture
|
||||
if(uv.x < 0 || uv.y < 0 || uv.x > 1 || uv.y > 1) discard;
|
||||
|
||||
// sample the texture.
|
||||
// TODO: handle uint/sint/float textures (OutputDisplayFormat).
|
||||
// TODO: Use MipLevel and Slice parameters
|
||||
// TODO: Sample from a point or linear sampler depending on if we're
|
||||
// upscaling (point) or downscaling mip 0 (linear)
|
||||
vec4 col = texture(tex0, vec2(uv.x, FlipY > 0 ? uv.y : 1.0f-uv.y));
|
||||
if (uintTex)
|
||||
{
|
||||
ucol = SampleTextureUInt4(scr / Scale, OutputDisplayFormat & TEXDISPLAY_TYPEMASK, FlipY == 0, int(MipLevel), Slice);
|
||||
}
|
||||
else if (sintTex)
|
||||
{
|
||||
scol = SampleTextureSInt4(scr / Scale, OutputDisplayFormat & TEXDISPLAY_TYPEMASK, FlipY == 0, int(MipLevel), Slice);
|
||||
}
|
||||
else
|
||||
{
|
||||
col = SampleTextureFloat4(scr / Scale, OutputDisplayFormat & TEXDISPLAY_TYPEMASK, FlipY == 0, (Scale < 1.0 && MipLevel == 0.0), int(MipLevel), Slice);
|
||||
}
|
||||
|
||||
if(RawOutput != 0)
|
||||
{
|
||||
if (uintTex)
|
||||
color_out = uintBitsToFloat(ucol);
|
||||
else if (sintTex)
|
||||
color_out = intBitsToFloat(scol);
|
||||
else
|
||||
color_out = col;
|
||||
return;
|
||||
}
|
||||
@@ -75,9 +292,19 @@ void main(void)
|
||||
// RGBM encoding
|
||||
if(HDRMul > 0.0f)
|
||||
{
|
||||
col = vec4(col.rgb * col.a * HDRMul, 1.0f);
|
||||
if (uintTex)
|
||||
col = vec4(ucol.rgb * ucol.a * uint(HDRMul), 1.0);
|
||||
else if (sintTex)
|
||||
col = vec4(scol.rgb * scol.a * int(HDRMul), 1.0);
|
||||
else
|
||||
col = vec4(col.rgb * col.a * HDRMul, 1.0);
|
||||
}
|
||||
|
||||
if (uintTex)
|
||||
col = vec4(ucol);
|
||||
else if (sintTex)
|
||||
col = vec4(scol);
|
||||
|
||||
col = ((col - RangeMinimum)*InverseRangeSize);
|
||||
|
||||
col = mix(vec4(0,0,0,1), col, Channels);
|
||||
|
||||
@@ -116,6 +116,7 @@ RESOURCE_checkerboard_frag TYPE_EMBED "glsl/checkerboard.frag"
|
||||
RESOURCE_generic_vert TYPE_EMBED "glsl/generic.vert"
|
||||
RESOURCE_generic_frag TYPE_EMBED "glsl/generic.frag"
|
||||
RESOURCE_mesh_vert TYPE_EMBED "glsl/mesh.vert"
|
||||
RESOURCE_debuguniforms_h TYPE_EMBED "glsl/debuguniforms.h"
|
||||
|
||||
RESOURCE_sourcecodepro_ttf TYPE_EMBED "sourcecodepro.ttf"
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define RESOURCE_generic_vert 205
|
||||
#define RESOURCE_generic_frag 206
|
||||
#define RESOURCE_mesh_vert 207
|
||||
#define RESOURCE_debuguniforms_h 208
|
||||
|
||||
#define RESOURCE_sourcecodepro_ttf 301
|
||||
|
||||
|
||||
@@ -79,6 +79,8 @@ GLuint GLReplay::CreateShaderProgram(const char *vsSrc, const char *psSrc)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include "data/glsl/debuguniforms.h"
|
||||
|
||||
void GLReplay::InitDebugData()
|
||||
{
|
||||
if(m_pDriver == NULL) return;
|
||||
@@ -96,7 +98,8 @@ void GLReplay::InitDebugData()
|
||||
|
||||
DebugData.blitProg = CreateShaderProgram(DebugData.blitvsSource.c_str(), DebugData.blitfsSource.c_str());
|
||||
|
||||
string texfs = GetEmbeddedResource(texdisplay_frag);
|
||||
string texfs = GetEmbeddedResource(debuguniforms_h);
|
||||
texfs += GetEmbeddedResource(texdisplay_frag);
|
||||
|
||||
DebugData.texDisplayProg = CreateShaderProgram(DebugData.blitvsSource.c_str(), texfs.c_str());
|
||||
|
||||
@@ -150,7 +153,7 @@ void GLReplay::InitDebugData()
|
||||
for(size_t i=0; i < ARRAY_COUNT(DebugData.UBOs); i++)
|
||||
{
|
||||
gl.glBindBuffer(eGL_UNIFORM_BUFFER, DebugData.UBOs[i]);
|
||||
gl.glBufferData(eGL_UNIFORM_BUFFER, Debug_UBOSize, NULL, eGL_DYNAMIC_DRAW);
|
||||
gl.glBufferData(eGL_UNIFORM_BUFFER, sizeof(texdisplay), NULL, eGL_DYNAMIC_DRAW);
|
||||
}
|
||||
|
||||
DebugData.overlayTexWidth = DebugData.overlayTexHeight = 0;
|
||||
@@ -220,6 +223,8 @@ void GLReplay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sl
|
||||
|
||||
bool GLReplay::RenderTexture(TextureDisplay cfg)
|
||||
{
|
||||
FetchTexture tex = GetTexture(cfg.texid);
|
||||
|
||||
MakeCurrentReplayContext(m_DebugCtx);
|
||||
|
||||
WrappedOpenGL &gl = *m_pDriver;
|
||||
@@ -228,42 +233,102 @@ bool GLReplay::RenderTexture(TextureDisplay cfg)
|
||||
|
||||
auto &texDetails = m_pDriver->m_Textures[cfg.texid];
|
||||
|
||||
gl.glActiveTexture(eGL_TEXTURE0);
|
||||
gl.glBindTexture(eGL_TEXTURE_2D, texDetails.resource.name);
|
||||
int resType;
|
||||
switch (texDetails.curType)
|
||||
{
|
||||
case eGL_TEXTURE_1D:
|
||||
resType = RESTYPE_TEX1D;
|
||||
break;
|
||||
default:
|
||||
RDCWARN("Unexpected texture type");
|
||||
case eGL_TEXTURE_2D:
|
||||
resType = RESTYPE_TEX2D;
|
||||
break;
|
||||
case eGL_TEXTURE_3D:
|
||||
resType = RESTYPE_TEX3D;
|
||||
break;
|
||||
case eGL_TEXTURE_CUBE_MAP:
|
||||
resType = RESTYPE_TEXCUBE;
|
||||
break;
|
||||
case eGL_TEXTURE_1D_ARRAY:
|
||||
resType = RESTYPE_TEX1DARRAY;
|
||||
break;
|
||||
case eGL_TEXTURE_2D_ARRAY:
|
||||
resType = RESTYPE_TEX2DARRAY;
|
||||
break;
|
||||
case eGL_TEXTURE_CUBE_MAP_ARRAY:
|
||||
resType = RESTYPE_TEXCUBEARRAY;
|
||||
break;
|
||||
}
|
||||
|
||||
if(cfg.mip == 0 && cfg.scale < 1.0f)
|
||||
gl.glBindSampler(0, DebugData.linearSampler);
|
||||
RDCGLenum dsTexMode = eGL_NONE;
|
||||
if (tex.creationFlags & eTextureCreate_DSV)
|
||||
{
|
||||
if (cfg.Green)
|
||||
{
|
||||
dsTexMode = eGL_STENCIL_INDEX;
|
||||
|
||||
// Stencil texture sampling is not normalized in OpenGL
|
||||
resType |= TEXDISPLAY_UINT_TEX;
|
||||
float rangeScale;
|
||||
switch (tex.format.rawType)
|
||||
{
|
||||
case eGL_STENCIL_INDEX1:
|
||||
rangeScale = 1.0f;
|
||||
break;
|
||||
case eGL_STENCIL_INDEX4:
|
||||
rangeScale = 16.0f;
|
||||
break;
|
||||
default:
|
||||
RDCWARN("Unexpected raw format for stencil visualization");
|
||||
case eGL_DEPTH24_STENCIL8:
|
||||
case eGL_DEPTH32F_STENCIL8:
|
||||
case eGL_STENCIL_INDEX8:
|
||||
rangeScale = 256.0f;
|
||||
break;
|
||||
case eGL_STENCIL_INDEX16:
|
||||
rangeScale = 65536.0f;
|
||||
break;
|
||||
}
|
||||
cfg.rangemin *= rangeScale;
|
||||
cfg.rangemax *= rangeScale;
|
||||
}
|
||||
else
|
||||
dsTexMode = eGL_DEPTH_COMPONENT;
|
||||
}
|
||||
else
|
||||
gl.glBindSampler(0, DebugData.pointSampler);
|
||||
{
|
||||
switch (tex.format.compType)
|
||||
{
|
||||
case eCompType_UInt:
|
||||
resType |= TEXDISPLAY_UINT_TEX;
|
||||
break;
|
||||
case eCompType_SNorm:
|
||||
resType |= TEXDISPLAY_SINT_TEX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gl.glActiveTexture((RDCGLenum)(eGL_TEXTURE0 + resType));
|
||||
gl.glBindTexture(texDetails.curType, texDetails.resource.name);
|
||||
|
||||
GLint origDSTexMode = eGL_DEPTH_COMPONENT;
|
||||
if (dsTexMode != eGL_NONE)
|
||||
{
|
||||
gl.glGetTexParameteriv(texDetails.curType, eGL_DEPTH_STENCIL_TEXTURE_MODE, &origDSTexMode);
|
||||
gl.glTexParameteri(texDetails.curType, eGL_DEPTH_STENCIL_TEXTURE_MODE, dsTexMode);
|
||||
}
|
||||
|
||||
if(cfg.mip == 0 && cfg.scale < 1.0f && dsTexMode == eGL_NONE)
|
||||
gl.glBindSampler(resType, DebugData.linearSampler);
|
||||
else
|
||||
gl.glBindSampler(resType, DebugData.pointSampler);
|
||||
|
||||
GLint tex_x = texDetails.width, tex_y = texDetails.height, tex_z = texDetails.depth;
|
||||
|
||||
gl.glBindBufferBase(eGL_UNIFORM_BUFFER, 0, DebugData.UBOs[0]);
|
||||
|
||||
struct uboData
|
||||
{
|
||||
Vec2f Position;
|
||||
float Scale;
|
||||
float HDRMul;
|
||||
|
||||
Vec4f Channels;
|
||||
|
||||
float RangeMinimum;
|
||||
float InverseRangeSize;
|
||||
float MipLevel;
|
||||
int32_t FlipY;
|
||||
|
||||
Vec3f TextureResolutionPS;
|
||||
int32_t OutputDisplayFormat;
|
||||
|
||||
Vec2f OutputRes;
|
||||
int32_t RawOutput;
|
||||
float Slice;
|
||||
};
|
||||
|
||||
uboData *ubo = (uboData *)gl.glMapBufferRange(eGL_UNIFORM_BUFFER, 0, sizeof(uboData), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
|
||||
RDCCOMPILE_ASSERT(sizeof(uboData) <= Debug_UBOSize, "UBO data is too big");
|
||||
texdisplay *ubo = (texdisplay *)gl.glMapBufferRange(eGL_UNIFORM_BUFFER, 0, sizeof(texdisplay), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
|
||||
float x = cfg.offx;
|
||||
float y = cfg.offy;
|
||||
@@ -297,17 +362,29 @@ bool GLReplay::RenderTexture(TextureDisplay cfg)
|
||||
|
||||
if(cfg.rangemax <= cfg.rangemin) cfg.rangemax += 0.00001f;
|
||||
|
||||
ubo->Channels.x = cfg.Red ? 1.0f : 0.0f;
|
||||
ubo->Channels.y = cfg.Green ? 1.0f : 0.0f;
|
||||
ubo->Channels.z = cfg.Blue ? 1.0f : 0.0f;
|
||||
ubo->Channels.w = cfg.Alpha ? 1.0f : 0.0f;
|
||||
if (dsTexMode == eGL_NONE)
|
||||
{
|
||||
ubo->Channels.x = cfg.Red ? 1.0f : 0.0f;
|
||||
ubo->Channels.y = cfg.Green ? 1.0f : 0.0f;
|
||||
ubo->Channels.z = cfg.Blue ? 1.0f : 0.0f;
|
||||
ubo->Channels.w = cfg.Alpha ? 1.0f : 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Both depth and stencil texture mode use the red channel
|
||||
ubo->Channels.x = 1.0f;
|
||||
ubo->Channels.y = 0.0f;
|
||||
ubo->Channels.z = 0.0f;
|
||||
ubo->Channels.w = 0.0f;
|
||||
}
|
||||
|
||||
ubo->RangeMinimum = cfg.rangemin;
|
||||
ubo->InverseRangeSize = 1.0f/(cfg.rangemax-cfg.rangemin);
|
||||
|
||||
ubo->MipLevel = (float)cfg.mip;
|
||||
ubo->Slice = (float)cfg.sliceFace;
|
||||
|
||||
ubo->OutputDisplayFormat = 0x2; // 2d. Unused for now
|
||||
ubo->OutputDisplayFormat = resType;
|
||||
|
||||
ubo->RawOutput = cfg.rawoutput ? 1 : 0;
|
||||
|
||||
@@ -335,6 +412,9 @@ bool GLReplay::RenderTexture(TextureDisplay cfg)
|
||||
|
||||
gl.glBindSampler(0, 0);
|
||||
|
||||
if (dsTexMode != eGL_NONE)
|
||||
gl.glTexParameteri(texDetails.curType, eGL_DEPTH_STENCIL_TEXTURE_MODE, origDSTexMode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,6 @@ void GLRenderState::FetchState()
|
||||
eGL_SAMPLE_ALPHA_TO_ONE,
|
||||
eGL_SAMPLE_COVERAGE,
|
||||
eGL_SAMPLE_MASK,
|
||||
eGL_SCISSOR_TEST,
|
||||
eGL_STENCIL_TEST,
|
||||
eGL_TEXTURE_CUBE_MAP_SEAMLESS,
|
||||
};
|
||||
@@ -153,7 +152,10 @@ void GLRenderState::FetchState()
|
||||
m_Real->glGetFloati_v(eGL_VIEWPORT, i, &Viewports[i].x);
|
||||
|
||||
for(GLuint i=0; i < (GLuint)ARRAY_COUNT(Scissors); i++)
|
||||
{
|
||||
m_Real->glGetIntegeri_v(eGL_SCISSOR_BOX, i, &Scissors[i].x);
|
||||
Scissors[i].enabled = (m_Real->glIsEnabledi(eGL_SCISSOR_TEST, i) == GL_TRUE);
|
||||
}
|
||||
|
||||
m_Real->glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint *)&DrawFBO);
|
||||
m_Real->glGetIntegerv(eGL_READ_FRAMEBUFFER_BINDING, (GLint *)&ReadFBO);
|
||||
@@ -256,7 +258,6 @@ void GLRenderState::ApplyState()
|
||||
eGL_SAMPLE_ALPHA_TO_ONE,
|
||||
eGL_SAMPLE_COVERAGE,
|
||||
eGL_SAMPLE_MASK,
|
||||
eGL_SCISSOR_TEST,
|
||||
eGL_STENCIL_TEST,
|
||||
eGL_TEXTURE_CUBE_MAP_SEAMLESS,
|
||||
};
|
||||
@@ -329,7 +330,15 @@ void GLRenderState::ApplyState()
|
||||
|
||||
m_Real->glViewportArrayv(0, ARRAY_COUNT(Viewports), &Viewports[0].x);
|
||||
|
||||
m_Real->glScissorArrayv(0, ARRAY_COUNT(Scissors), &Scissors[0].x);
|
||||
for (GLuint s = 0; s < (GLuint)ARRAY_COUNT(Scissors); ++s)
|
||||
{
|
||||
m_Real->glScissorIndexedv(s, &Scissors[s].x);
|
||||
|
||||
if (Scissors[s].enabled)
|
||||
m_Real->glEnablei(eGL_SCISSOR_TEST, s);
|
||||
else
|
||||
m_Real->glDisablei(eGL_SCISSOR_TEST, s);
|
||||
}
|
||||
|
||||
m_Real->glBindFramebuffer(eGL_READ_FRAMEBUFFER, ReadFBO);
|
||||
m_Real->glBindFramebuffer(eGL_DRAW_FRAMEBUFFER, DrawFBO);
|
||||
|
||||
@@ -67,7 +67,7 @@ struct GLRenderState
|
||||
eEnabled_SampleAlphaToOne,
|
||||
eEnabled_SampleCoverage,
|
||||
eEnabled_SampleMask,
|
||||
eEnabled_ScissorTest,
|
||||
//eEnabled_ScissorTest, handled below with scissor values
|
||||
eEnabled_StencilTest,
|
||||
eEnabled_TexCubeSeamless,
|
||||
eEnabled_Count,
|
||||
@@ -131,6 +131,7 @@ struct GLRenderState
|
||||
struct Scissor
|
||||
{
|
||||
int32_t x, y, width, height;
|
||||
bool enabled;
|
||||
} Scissors[16];
|
||||
|
||||
GLuint ReadFBO, DrawFBO;
|
||||
|
||||
@@ -1093,6 +1093,90 @@ void GLReplay::SavePipelineState()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Vertex post processing and rasterization
|
||||
|
||||
RDCCOMPILE_ASSERT(ARRAY_COUNT(rs.Viewports) == ARRAY_COUNT(rs.DepthRanges), "GL Viewport count does not match depth ranges count");
|
||||
create_array_uninit(pipe.m_Rasterizer.Viewports, ARRAY_COUNT(rs.Viewports));
|
||||
for (int32_t v = 0; v < pipe.m_Rasterizer.Viewports.count; ++v)
|
||||
{
|
||||
pipe.m_Rasterizer.Viewports[v].Left = rs.Viewports[v].x;
|
||||
pipe.m_Rasterizer.Viewports[v].Bottom = rs.Viewports[v].y;
|
||||
pipe.m_Rasterizer.Viewports[v].Width = rs.Viewports[v].width;
|
||||
pipe.m_Rasterizer.Viewports[v].Height = rs.Viewports[v].height;
|
||||
pipe.m_Rasterizer.Viewports[v].MinDepth = rs.DepthRanges[v].nearZ;
|
||||
pipe.m_Rasterizer.Viewports[v].MaxDepth = rs.DepthRanges[v].farZ;
|
||||
}
|
||||
|
||||
create_array_uninit(pipe.m_Rasterizer.Scissors, ARRAY_COUNT(rs.Scissors));
|
||||
for (int32_t s = 0; s < pipe.m_Rasterizer.Scissors.count; ++s)
|
||||
{
|
||||
pipe.m_Rasterizer.Scissors[s].Left = rs.Scissors[s].x;
|
||||
pipe.m_Rasterizer.Scissors[s].Bottom = rs.Scissors[s].y;
|
||||
pipe.m_Rasterizer.Scissors[s].Width = rs.Scissors[s].width;
|
||||
pipe.m_Rasterizer.Scissors[s].Height = rs.Scissors[s].height;
|
||||
pipe.m_Rasterizer.Scissors[s].Enabled = rs.Scissors[s].enabled;
|
||||
}
|
||||
|
||||
int polygonOffsetEnableEnum;
|
||||
switch (rs.PolygonMode)
|
||||
{
|
||||
default:
|
||||
RDCWARN("Unexpected value for POLYGON_MODE");
|
||||
case eGL_FILL:
|
||||
pipe.m_Rasterizer.m_State.FillMode = eFill_Solid;
|
||||
polygonOffsetEnableEnum = GLRenderState::eEnabled_PolyOffsetFill;
|
||||
break;
|
||||
case eGL_LINES:
|
||||
pipe.m_Rasterizer.m_State.FillMode = eFill_Wireframe;
|
||||
polygonOffsetEnableEnum = GLRenderState::eEnabled_PolyOffsetLine;
|
||||
break;
|
||||
case eGL_POINT:
|
||||
pipe.m_Rasterizer.m_State.FillMode = eFill_Point;
|
||||
polygonOffsetEnableEnum = GLRenderState::eEnabled_PolyOffsetPoint;
|
||||
break;
|
||||
}
|
||||
if (rs.Enabled[polygonOffsetEnableEnum])
|
||||
{
|
||||
pipe.m_Rasterizer.m_State.DepthBias = rs.PolygonOffset[1];
|
||||
pipe.m_Rasterizer.m_State.SlopeScaledDepthBias = rs.PolygonOffset[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
pipe.m_Rasterizer.m_State.DepthBias = 0.0f;
|
||||
pipe.m_Rasterizer.m_State.SlopeScaledDepthBias = 0.0f;
|
||||
}
|
||||
|
||||
if (rs.Enabled[GLRenderState::eEnabled_CullFace])
|
||||
{
|
||||
switch (rs.CullFace)
|
||||
{
|
||||
default:
|
||||
RDCWARN("Unexpected value for CULL_FACE");
|
||||
case eGL_BACK:
|
||||
pipe.m_Rasterizer.m_State.CullMode = eCull_Back;
|
||||
break;
|
||||
case eGL_FRONT:
|
||||
pipe.m_Rasterizer.m_State.CullMode = eCull_Front;
|
||||
break;
|
||||
case eGL_FRONT_AND_BACK:
|
||||
pipe.m_Rasterizer.m_State.CullMode = eCull_FrontAndBack;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pipe.m_Rasterizer.m_State.CullMode = eCull_None;
|
||||
}
|
||||
|
||||
RDCASSERT(rs.FrontFace == eGL_CCW || rs.FrontFace == eGL_CW);
|
||||
pipe.m_Rasterizer.m_State.FrontCCW = rs.FrontFace == eGL_CCW;
|
||||
pipe.m_Rasterizer.m_State.DepthClamp = rs.Enabled[GLRenderState::eEnabled_DepthClamp];
|
||||
pipe.m_Rasterizer.m_State.MultisampleEnable = rs.Enabled[GLRenderState::eEnabled_Multisample];
|
||||
pipe.m_Rasterizer.m_State.AntialiasedLineEnable = rs.Enabled[GLRenderState::eEnabled_LineSmooth];
|
||||
|
||||
// Frame buffer
|
||||
|
||||
GLuint curFBO = 0;
|
||||
gl.glGetIntegerv(eGL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&curFBO);
|
||||
|
||||
|
||||
@@ -205,8 +205,6 @@ class GLReplay : public IReplayDriver
|
||||
|
||||
GLuint emptyVAO;
|
||||
} DebugData;
|
||||
|
||||
static const size_t Debug_UBOSize = 64 * sizeof(Vec4f);
|
||||
|
||||
void InitDebugData();
|
||||
|
||||
|
||||
@@ -248,6 +248,7 @@
|
||||
<ClInclude Include="core\replay_proxy.h" />
|
||||
<ClInclude Include="core\resource_manager.h" />
|
||||
<ClInclude Include="core\socket_helpers.h" />
|
||||
<ClInclude Include="data\glsl\debuguniforms.h" />
|
||||
<ClInclude Include="data\hlsl\debugcbuffers.h" />
|
||||
<ClInclude Include="data\resource.h" />
|
||||
<ClInclude Include="data\version.h" />
|
||||
|
||||
@@ -240,6 +240,9 @@
|
||||
<ClInclude Include="data\hlsl\debugcbuffers.h">
|
||||
<Filter>Resources\hlsl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="data\glsl\debuguniforms.h">
|
||||
<Filter>Resources\glsl</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="driver\gl\gl_renderstate.h">
|
||||
<Filter>Drivers\OpenGL</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -351,6 +351,7 @@ namespace renderdoc
|
||||
{
|
||||
Solid = 0,
|
||||
Wireframe,
|
||||
Point
|
||||
};
|
||||
|
||||
public enum TriangleCullMode
|
||||
@@ -358,6 +359,7 @@ namespace renderdoc
|
||||
None = 0,
|
||||
Front,
|
||||
Back,
|
||||
FrontAndBack,
|
||||
};
|
||||
|
||||
public enum ReplayCreateStatus
|
||||
|
||||
@@ -119,6 +119,47 @@ namespace renderdoc
|
||||
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
|
||||
public Buffer[] UniformBuffers;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class Rasterizer
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class Viewport
|
||||
{
|
||||
public float Left, Bottom;
|
||||
public float Width, Height;
|
||||
public double MinDepth, MaxDepth;
|
||||
};
|
||||
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
|
||||
public Viewport[] Viewports;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class Scissor
|
||||
{
|
||||
public Int32 Left, Bottom;
|
||||
public Int32 Width, Height;
|
||||
public bool Enabled;
|
||||
};
|
||||
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
|
||||
public Scissor[] Scissors;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class RasterizerState
|
||||
{
|
||||
public TriangleFillMode FillMode;
|
||||
public TriangleCullMode CullMode;
|
||||
public bool FrontCCW;
|
||||
public float DepthBias;
|
||||
public float SlopeScaledDepthBias;
|
||||
public bool DepthClamp;
|
||||
public bool MultisampleEnable;
|
||||
public bool AntialiasedLineEnable;
|
||||
};
|
||||
[CustomMarshalAs(CustomUnmanagedType.CustomClass)]
|
||||
public RasterizerState m_State;
|
||||
};
|
||||
[CustomMarshalAs(CustomUnmanagedType.CustomClass)]
|
||||
public Rasterizer m_RS;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class FrameBuffer
|
||||
{
|
||||
|
||||
+297
-351
File diff suppressed because it is too large
Load Diff
@@ -118,8 +118,7 @@ namespace renderdocui.Windows.PipelineState
|
||||
multisampleEnable.Image = tick;
|
||||
|
||||
depthClip.Image = tick;
|
||||
depthBias.Text = "0";
|
||||
depthBiasClamp.Text = "0.0";
|
||||
depthBias.Text = "0.0";
|
||||
slopeScaledBias.Text = "0.0";
|
||||
|
||||
viewports.Nodes.Clear();
|
||||
@@ -613,14 +612,63 @@ namespace renderdocui.Windows.PipelineState
|
||||
|
||||
viewports.BeginUpdate();
|
||||
viewports.Nodes.Clear();
|
||||
if (state.m_RS.Viewports != null)
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var v in state.m_RS.Viewports)
|
||||
{
|
||||
if (v.Width != v.Height || v.Width != 0 || v.Height != 0 || showEmpty.Checked)
|
||||
{
|
||||
var node = viewports.Nodes.Add(new object[] { i, v.Left, v.Bottom, v.Width, v.Height, v.MinDepth, v.MaxDepth });
|
||||
|
||||
if (v.Width == v.Height && v.Width == 0 && v.Height == 0)
|
||||
EmptyRow(node);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
viewports.NodesSelection.Clear();
|
||||
viewports.EndUpdate();
|
||||
|
||||
bool anyScissorEnable = false;
|
||||
|
||||
scissors.BeginUpdate();
|
||||
scissors.Nodes.Clear();
|
||||
if (state.m_RS.Scissors != null)
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var s in state.m_RS.Scissors)
|
||||
{
|
||||
if (s.Width != 0 || s.Height != 0 || showEmpty.Checked)
|
||||
{
|
||||
var node = scissors.Nodes.Add(new object[] { i, s.Left, s.Bottom, s.Width, s.Height, s.Enabled });
|
||||
|
||||
if (s.Width == 0 && s.Height == 0)
|
||||
EmptyRow(node);
|
||||
}
|
||||
|
||||
if (s.Enabled)
|
||||
anyScissorEnable = true;
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
scissors.NodesSelection.Clear();
|
||||
scissors.EndUpdate();
|
||||
|
||||
fillMode.Text = state.m_RS.m_State.FillMode.ToString();
|
||||
cullMode.Text = state.m_RS.m_State.CullMode.ToString();
|
||||
frontCCW.Image = state.m_RS.m_State.FrontCCW ? tick : cross;
|
||||
|
||||
scissorEnable.Image = anyScissorEnable ? tick : cross;
|
||||
lineAAEnable.Image = state.m_RS.m_State.AntialiasedLineEnable ? tick : cross;
|
||||
multisampleEnable.Image = state.m_RS.m_State.MultisampleEnable ? tick : cross;
|
||||
|
||||
depthClip.Image = state.m_RS.m_State.DepthClamp ? cross : tick;
|
||||
depthBias.Text = Formatter.Format(state.m_RS.m_State.DepthBias);
|
||||
slopeScaledBias.Text = Formatter.Format(state.m_RS.m_State.SlopeScaledDepthBias);
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Output Merger
|
||||
|
||||
|
||||
Reference in New Issue
Block a user