CathodeRetro::Internal::RGBToCRT

This is an internal class used by CathodeRetro::CathodeRetro to take an RGB image and draw it to a render target to look like it is on a CRT TV.

If you are using the CathodeRetro::CathodeRetro class, you should not need to use this class directly.

Public Members

Public Methods

(constructor)
                RGBToCRT(
                  IGraphicsDevice *deviceIn,
                  uint32_t originalInputImageWidthIn,
                  uint32_t processedRGBTextureWidthIn,
                  uint32_t scanlineCountIn,
                  float pixelAspectIn)
              
Description
Construct a new instance of the Internal::RGBToCRT class.
Parameters
deviceIn

Type: IGraphicsDevice *

Pointer to the graphics device instance that this instance should use for all of its drawing-related functionality. This pointer will be cached so the lifetime of deviceIn must extend past the lifetime of the Internal::RGBToCRT instance being created.

originalInputImageWidthIn

Type: uint32_t

The width of the original input image (the one passed to CathodeRetro::Render), before running through the generator and decoder.

processedRGBTextureWidthIn

Type: uint32_t

The width of the input texture that Render will be provided.

scanlineCountIn

Type: uint32_t

The height of the input texture that Render will be provided.

pixelAspectIn

Type: float

The pixel aspect ratio of the input signal (relative to the original input). This value comes from the SignalProperties given to the CathodeRetro class.

SetSettings
                void SetSettings(
                  const OverscanSettings &overscan, 
                  const ScreenSettings &screen)
              
Description
Set the settings that describe how the screen should appear.
Parameters
overscan

Type: const OverscanSettings &

A description of how much the various edges of the input image are cut off by the "bevel" of the TV.

screen

Type: const ScreenSettings &

Information about the properties of the screen itself.

SetOutputSize
                void SetOutputSize(
                  uint32_t outputWidth,
                  uint32_t outputHeight)
              
Description

Set the size of the final output render target that CathodeRetro::Render will be given.

If the width or height change from what they were before, this will reallocate a render target.

Parameters
outputWidth

Type: uint32_t

The expected width of the final output render target that CathodeRetro::Render will be given.

outputHeight

Type: uint32_t

The expected height of the final output render target that CathodeRetro::Render will be given.

Render
                void Render(
                  const ITexture *currentFrameRGBInput,
                  IRenderTarget *outputTexture,
                  ScanlineType scanType)
              
Description
Render a CRT TV emulation pass using the input texture as what is on-screen.
Parameters
currentFrameRGBInput

Type: const ITexture *

The input RGB frame data, representing what is "on-screen."

Its dimensions are expected to match the processedRGBTextureWidthIn (width) and scanlineCountIn (height) values that were passed to the constructor.

outputTexture

Type: IRenderTarget *

The texture that the result of this rendering will be rendered to.

Its dimensions are expected to match the outputWidth and outputHeight values passed to the most-recent call to SetOutputSize.

scanType

Type: ScanlineType

Which type of scanlines to render for this frame (even or odd).

Private Members

Private Constants

k_maskSize
                static constexpr uint32_t k_maskSize = 512
              
Description

The horizontal resolution of maskTexture, the texture that the CRT mask is rendered to.

The vertical resolution of the texture is half this value.

Given the small scale of the mask in the render output, this value is - in practice - wildly overkill, but it downsamples to the mipmaps very well.

Private Structures

AspectData
Description
Information generated by CalculateAspectData with some commonly-calculated aspect-related values.
Fields
overscanSize

Type: Vec2

This contains (as an x, y vector) the width and height of the original (pre-generation/decode) image (the original source RGB image), minus the amount of overscan specified by overscanSettings.

aspect

Type: float

This value represents the actual aspect ratio (width / height) of the screen, taking into account both the above overscanSize value and pixelAspect.

CommonConstants
Description

This contains the initial values for both ScreenTextureConstants and RGBToScreenConstants.

These values correspond to the initial four input constant values in the crt-generate-screen-texture and crt-rgb-to-crt shaders. Refer to those pages for documentation of the fields.

ScreenTextureConstants
Description
This structure maps to the constant buffer input to the crt-generate-screen-texture shader. Refer to its page for documentation of the fields.
RGBToScreenConstants
Description
This structure maps to the constant buffer input to the crt-rgb-to-crt shader. Refer to its page for documentation of the fields.
GaussianBlurConstants
Description
This structure maps to the constant buffer input to the util-gaussian-blur shader. Refer to its page for documentation of the fields.
ToneMapConstants
Description
This structure maps to the constant buffer input to the util-tonemap-and-downsample shader. Refer to its page for documentation of the fields.

Private Methods

CalculateAspectData
                AspectData CalculateAspectData()
              
Description

Calculates the dimensions of the original (pre-generation/decode) input texture would have after overscan is applied, as well as the aspect ratio of the full image.

Called by CalculateCommonConstants, RenderScreenTexture, and UpdateBlurTextures.

Return Value
Type: RGBToCRT::AspectData

The calculated data.

CalculateCommonConstants
                CommonConstants CalculateCommonConstants(
                  const AspectData &aspectData)
              
Description

Calculate some values that are common to both RGBToCRT::ScreenTextureConstants and RGBToCRT::RGBToScreenConstants.

Called by Render and RenderScreenTexture.

Parameters
aspectData

Type: const RGBToCRT::AspectData &

The output of a call to CalculateAspectData.

Return Value

Type: RGBToCRT::CommonConstants

The calculated constants.

RenderScreenTexture
                void RenderScreenTexture()
              
Description

Renders to screenTexture, which contains an image that has the CRT mask (with proper curvature applied) in the RGB channels and a mask of what is or is not visible on the screen in the alpha channel.

It's worth noting that the shader that renders this does a very expensive 64-tap sample of the mask texture to alleviate aliasing, so the RGBToCRT does a fair amount of work to only do this when necessary (after a call to SetSettings or SetOutputSize in which the values were changed).

Called by Render.

UpdateBlurTextures
                void UpdateBlurTextures()
              
Description

Calculates the required sizes for toneMapTexture, blurTexture, and blurScratchTexture. Then, if the sizes are different from the existing versions of those textures, will create new textures at the proper size.

Called by the constructor and SetSettings.

RenderMaskTexture
                void RenderMaskTexture()
              
Description

Renders a mask to maskTexture, given the MaskType value stored in screenSettings.

This uses a lanczos downsample pass to generate the mipmap levels.

This is only called after a call to SetSettings or SetOutputSize in which the values were changed.

Called by Render.

RenderBlur
                void RenderBlur(
                  const ITexture *inputTexture)
              
Description

Does a tonemap and blur of the given input texture, which is used as an approximation of CRT diffusion (the scattering of photons as they pass through the glass front of the CRT screen).

Called by Render.

Parameters
inputTexture

Type: const ITexture *

The texture to tonemap and then blur.

Private Fields

device
                IGraphicsDevice *device
              
Type
IGraphicsDevice *
Description
Pointer to the graphics device that should be used to create graphics objects and render.
originalInputImageWidth
                uint32_t originalInputImageWidth
              
Type
uint32_t
Description
The width of the original image (before the generator/decoder process).
processedRGBTextureWidth
                uint32_t processedRGBTextureWidth
              
Type
uint32_t
Description

The expected width of the texture that will be passed in to Render.

If no generator/decoder process is being used (i.e. if the CathodeRetro class is being used in RGB mode, this will be the same value as originalInputImageWidth.

scanlineCount
                uint32_t scanlineCount
              
Type
uint32_t
Description

The number of scanlines per input image (i.e. the height of the input texture).

pixelAspect
                float pixelAspect
              
Type
float
Description

The aspect ratio (width/height) of an input pixel (pre-generator/decoder) on the screen. This allows for emulation of non-square-pixel video modes.

For example:

  • On the NES, pixels were slightly stretched horizontally and have an 8:7 (8/7) aspect ratio.
  • Old mode 13h modes had slightly tall pixels on 4x3 monitors, resulting in pixels that are 5:6.

isFirstFrame
                bool isFirstFrame = true
              
Type
bool
Description

This is true before Render is called the first time, and false afterward.

Because this class keeps a copy of the previous frame (in prevRGBInput) and uses that to handle phosphor persistence, on the very first call to Render this flag is used to initialize prevRGBInput so that it can be used.

screenTextureConstantBuffer
                std::unique_ptr<IConstantBuffer> screenTextureConstantBuffer
              
Type
std::unique_ptr<IConstantBuffer>
Description
The constant buffer that is used in RenderScreenTexture as an input to the crt-generate-screen-texture shader.
rgbToScreenConstantBuffer
                std::unique_ptr<IConstantBuffer> rgbToScreenConstantBuffer
              
Type
std::unique_ptr<IConstantBuffer>
Description
The constant buffer that is used in Render as an input to the crt-rgb-to-crt shader.
toneMapConstantBuffer
                std::unique_ptr<IConstantBuffer> toneMapConstantBuffer
              
Type
std::unique_ptr<IConstantBuffer>
Description
The constant buffer that is used in RenderBlur as an input to the util-tonemap-and-downsample shader.
blurDownsampleConstantBuffer
                std::unique_ptr<IConstantBuffer> blurDownsampleConstantBuffer
              
Type
std::unique_ptr<IConstantBuffer>
Description
The constant buffer that is used in RenderBlur as an input to the util-downsample-2x shader, to do a horizontal downsample before the blurring.
gaussianBlurConstantBufferH
                std::unique_ptr<IConstantBuffer> gaussianBlurConstantBufferH
              
Type
std::unique_ptr<IConstantBuffer>
Description
The constant buffer that is used in RenderBlur as an input to the util-gaussian-blur shader, to do the horizontal blur pass.
gaussianBlurConstantBufferV
                std::unique_ptr<IConstantBuffer> gaussianBlurConstantBufferV
              
Type
std::unique_ptr<IConstantBuffer>
Description
The constant buffer that is used in RenderBlur as an input to the util-gaussian-blur shader, to do the vertical blur pass.
generateMaskConstantBuffer
                std::unique_ptr<IConstantBuffer> generateMaskConstantBuffer
              
Type
std::unique_ptr<IConstantBuffer>
Description
The constant buffer that is used in RenderMaskTexture as an input to one of the crt-generate-shadow-mask, crt-generate-slot-mask, or crt-generate-aperture-grille shaders (depending on the value of screenSettings.maskType) to generate the largest mip level of maskTexture.
maskDownsampleConstantBufferH
                std::unique_ptr<IConstantBuffer> maskDownsampleConstantBufferH
              
Type
std::unique_ptr<IConstantBuffer>
Description
The constant buffer that is used in RenderMaskTexture as an input to the util-downsample-2x shader to do the horizontal downsample into a scratch texture (halfWidthMaskTexture) during the generation of the mipmaps of maskTexture.
maskDownsampleConstantBufferV
                std::unique_ptr<IConstantBuffer> maskDownsampleConstantBufferV
              
Type
std::unique_ptr<IConstantBuffer>
Description
The constant buffer that is used in RenderMaskTexture as an input to the util-downsample-2x shader to do the vertical downsample from the scratch texture (halfWidthMaskTexture), during the generation of the mipmaps of maskTexture.
prevRGBInput
                std::unique_ptr<IRenderTarget> prevRGBInput
              
Type
std::unique_ptr<IRenderTarget>
Description
This texture is a copy of the currentFrameRGBInput parameter that was passed to the previous call to Render, and is used to emulate phosphor persistence (where a little of the previous frame is still visible).
maskTexture
                std::unique_ptr<IRenderTarget> maskTexture
              
Type
std::unique_ptr<IRenderTarget>
Description
This is a mipmapped texture, which holds the CRT mask texture that we use to generate the screen texture. It is generated by RenderMaskTexture whenever the value of value of screenSettings.maskType changes.
halfWidthMaskTexture
                std::unique_ptr<IRenderTarget> halfWidthMaskTexture
              
Type
std::unique_ptr<IRenderTarget>
Description
This is an intermediate texture used during the generation of mipmap levels in RenderMaskTexture. It has the same height as maskTexture but has half the width, and is used as the target for the horizontal pass of the downsample.
screenTexture
                std::unique_ptr<IRenderTarget> screenTexture
              
Type
std::unique_ptr<IRenderTarget>
Description
This texture has an image that has the CRT mask (with proper curvature applied) in the RGB channels and a mask of what is or is not visible on the screen in the alpha channel. It is generated by RenderScreenTexture. It has the same width and height as the final output texture of the Render method.
toneMapTexture
                std::unique_ptr<IRenderTarget> toneMapTexture
              
Type
std::unique_ptr<IRenderTarget>
Description
This texture is the target of the first pass of RenderBlur, which does the tonemapping (and also a resize to get closer to the desired blur resolution).
blurScratchTexture
                std::unique_ptr<IRenderTarget> blurScratchTexture
              
Type
std::unique_ptr<IRenderTarget>
Description
This texture is the target of the second and fourth passes of RenderBlur (and is the ultimate result of that method), and ultimately contains the blurred version of the input texture that is used to emulate CRT diffusion (the scattering of photons as they pass through the glass front of the CRT screen).
blurTexture
                std::unique_ptr<IRenderTarget> blurTexture
              
Type
std::unique_ptr<IRenderTarget>
Description
This texture is the target of the third pass of RenderBlur, which is the horizontal gaussian blur pass. It is then used in the final pass to do the vertical blur to get the final result.
screenSettings
                ScreenSettings screenSettings
              
Type
ScreenSettings
Description
The screen settings that were applied by SetSettings.
overscanSettings
                OverscanSettings overscanSettings
              
Type
OverscanSettings
Description
The overscan settings that were applied by SetSettings.
needsRenderScreenTexture
                bool needsRenderScreenTexture = false
              
Type
bool
Description
This value is set to true by SetSettings or SetOutputSize when there is a change to the way the screen texture appears (including a change to the output resolution), so that Render will call RenderScreenTexture.
needsRenderMaskTexture
                bool needsRenderMaskTexture = false
              
Type
bool
Description
This value is set to true by SetSettings when the value of screenSettings.maskType changes, so that Render will call RenderMaskTexture.
prevScanlineType
                ScanlineType prevScanlineType 
                  = ScanlineType::Progressive
              
Type
ScanlineType
Description
The scanline type from the previous call to Render. This is used by Render to ensure that the scanlines from the previous frame are rendered with the correct even/odd parity to handle both progressive and interlacing modes when phosphor persistence emulation is enabled.
downsampleDirX
                float downsampleDirX
              
Type
float
Description
The x component of the direction of the downsample during the tonemap pass in RenderBlur. This and downsampleDirY are set to do either a horizontal or vertical blur depending on which blur gets us closer to the desired aspect ratio for the final blurred texture.
downsampleDirY
                float downsampleDirY
              
Type
float
Description
The y component of the direction of the downsample during the tonemap pass in RenderBlur. This and downsampleDirX are set to do either a horizontal or vertical blur depending on which blur gets us closer to the desired aspect ratio for the final blurred texture.