changed how textures are scaled for play screen and debug window

rather than integer scaling and smoothing an unscaled texture, a
bilinear scaled texture is sharpened. this seems to produce better
results
This commit is contained in:
JetSetIlly 2023-03-05 11:17:53 +00:00
parent 2fcf87c7c4
commit b2c950ce6b
12 changed files with 79 additions and 197 deletions

View file

@ -245,11 +245,12 @@ The following projects are used in the `Gopher2600` project:
Both 6502.ts and Stella were used as reference for the Audio implementation.
Some ideas for the fragment shader taken from:
Some ideas for the fragment shaders taken from:
* https://github.com/libretro/glsl-shaders/blob/master/crt/shaders/crt-pi.glsl
* https://www.shadertoy.com/view/ltB3zD
* https://github.com/mattiasgustavsson/crtview
* https://gist.github.com/Beefster09/7264303ee4b4b2086f372f1e70e8eddd
The Festival Speech Synthesis System is an optional program that can be run
alongside the emulator for [AtariVox](https://github.com/JetSetIlly/Gopher2600-Docs/wiki/AtariVox-and-SaveKey) support

View file

@ -176,7 +176,7 @@ func (rnd *glsl) render() {
shader = rnd.shaders[dbgscrShaderID]
case rnd.img.wm.dbgScr.overlayTexture:
shader = rnd.shaders[overlayShaderID]
case rnd.img.playScr.scaledTexture:
case rnd.img.playScr.displayTexture:
shader = rnd.shaders[playscrShaderID]
case rnd.img.wm.windows[winSelectROMID].(*winSelectROM).thmbTexture:
shader = rnd.shaders[colorShaderID]

View file

@ -103,7 +103,7 @@ func newCRTSequencer(img *SdlImgui) *crtSequencer {
sh := &crtSequencer{
img: img,
seq: framebuffer.NewSequence(5),
scalingShader: newScalingShader(),
scalingShader: newSharpenShader(),
phosphorShader: newPhosphorShader(img),
blackCorrectionShader: newBlackCorrectionShader(),
blurShader: newBlurShader(),
@ -165,8 +165,8 @@ func (sh *crtSequencer) flushPhosphor() {
// occurs but crt effects are not applied.
//
// integerScaling instructs the scaling shader not to perform any smoothing
func (sh *crtSequencer) process(env shaderEnvironment, moreProcessing bool, integerScaling bool,
numScanlines int, numClocks int, scalingImage scalingImage, prefs crtSeqPrefs) uint32 {
func (sh *crtSequencer) process(env shaderEnvironment, moreProcessing bool,
numScanlines int, numClocks int, scalingImage sharpenImage, prefs crtSeqPrefs) uint32 {
// we'll be chaining many shaders together so use internal projection
env.useInternalProj = true
@ -183,7 +183,7 @@ func (sh *crtSequencer) process(env shaderEnvironment, moreProcessing bool, inte
// scale image
if scalingImage != nil {
env.srcTextureID = sh.seq.Process(crtSeqProcessedSrc, func() {
sh.scalingShader.(*scalingShader).setAttributesArgs(env, scalingImage, integerScaling)
sh.scalingShader.(*sharpenShader).setAttributesArgs(env, scalingImage)
env.draw()
})
}

View file

@ -175,7 +175,7 @@ func (sh *dbgScrShader) setAttributes(env shaderEnvironment) {
prefs.Enabled = true
prefs.Bevel = false
env.srcTextureID = sh.crt.process(env, true, false,
env.srcTextureID = sh.crt.process(env, true,
sh.img.wm.dbgScr.numScanlines, specification.ClksVisible,
sh.img.wm.dbgScr, prefs)
} else {
@ -193,7 +193,7 @@ func (sh *dbgScrShader) setAttributes(env shaderEnvironment) {
prefs := newCrtSeqPrefs(sh.img.crtPrefs)
prefs.Enabled = false
env.srcTextureID = sh.crt.process(env, true, true,
env.srcTextureID = sh.crt.process(env, true,
sh.img.wm.dbgScr.numScanlines, specification.ClksVisible,
sh.img.wm.dbgScr, prefs)
}

View file

@ -67,7 +67,7 @@ func (sh *playscrShader) setAttributes(env shaderEnvironment) {
sh.screenshot.process(env, sh.img.playScr)
sh.crt.process(env, false, false,
sh.crt.process(env, false,
sh.img.playScr.visibleScanlines, specification.ClksVisible,
sh.img.playScr, newCrtSeqPrefs(sh.img.crtPrefs))
}

View file

@ -106,12 +106,12 @@ func (sh *screenshotSequencer) startProcess(mode screenshotMode) {
sh.crt.flushPhosphor()
}
func (sh *screenshotSequencer) process(env shaderEnvironment, scalingImage scalingImage) {
func (sh *screenshotSequencer) process(env shaderEnvironment, scalingImage sharpenImage) {
if sh.exposureCt <= 0 {
return
}
textureID := sh.crt.process(env, true, false,
textureID := sh.crt.process(env, true,
sh.img.playScr.visibleScanlines, specification.ClksVisible,
sh.img.playScr, sh.prefs)
@ -122,8 +122,8 @@ func (sh *screenshotSequencer) process(env shaderEnvironment, scalingImage scali
}
// SavesJPEG writes the texture to the specified path.
func (sh *screenshotSequencer) SaveJPEG(textureID uint32, path string, scalingImage scalingImage) {
_, width, height := scalingImage.scaledTextureSpec()
func (sh *screenshotSequencer) SaveJPEG(textureID uint32, path string, scalingImage sharpenImage) {
_, width, height := scalingImage.textureSpec()
img := image.NewRGBA(image.Rect(0, 0, int(width), int(height)))
if img == nil {
logger.Log("screenshot", "save failed: cannot allocate image data")

View file

@ -303,53 +303,31 @@ func (sh *blendShader) setAttributesArgs(env shaderEnvironment, modulate float32
gl.Uniform1i(sh.newFrame, 1)
}
type scalingShader struct {
type sharpenShader struct {
shader
scaledWidth int32
scaledHeight int32
unscaledWidth int32
unscaledHeight int32
unscaledTexture int32
integerScaling int32
texture int32
}
func newScalingShader() shaderProgram {
sh := &scalingShader{}
sh.createProgram(string(shaders.YFlipVertexShader), string(shaders.ScalingShader))
sh.unscaledWidth = gl.GetUniformLocation(sh.handle, gl.Str("UnscaledWidth"+"\x00"))
sh.unscaledHeight = gl.GetUniformLocation(sh.handle, gl.Str("UnscaledHeight"+"\x00"))
sh.scaledWidth = gl.GetUniformLocation(sh.handle, gl.Str("ScaledWidth"+"\x00"))
sh.scaledHeight = gl.GetUniformLocation(sh.handle, gl.Str("ScaledHeight"+"\x00"))
sh.unscaledTexture = gl.GetUniformLocation(sh.handle, gl.Str("UnscaledTexture"+"\x00"))
sh.integerScaling = gl.GetUniformLocation(sh.handle, gl.Str("IntegerScaling"+"\x00"))
func newSharpenShader() shaderProgram {
sh := &sharpenShader{}
sh.createProgram(string(shaders.YFlipVertexShader), string(shaders.SharpenShader))
sh.texture = gl.GetUniformLocation(sh.handle, gl.Str("Texture"+"\x00"))
return sh
}
type scalingImage interface {
unscaledTextureSpec() (uint32, float32, float32)
scaledTextureSpec() (uint32, float32, float32)
// sharpenImage is used by the sharpen shader
type sharpenImage interface {
// returns texture ID and the width and height of the texture
textureSpec() (uint32, float32, float32)
}
// nolint: unparam
func (sh *scalingShader) setAttributesArgs(env shaderEnvironment, scalingImage scalingImage, integerScaling bool) {
ut, uw, uh := scalingImage.unscaledTextureSpec()
_, w, h := scalingImage.scaledTextureSpec()
func (sh *sharpenShader) setAttributesArgs(env shaderEnvironment, scalingImage sharpenImage) {
t, _, _ := scalingImage.textureSpec()
sh.shader.setAttributes(env)
gl.Uniform1f(sh.unscaledWidth, uw)
gl.Uniform1f(sh.unscaledHeight, uh)
gl.Uniform1f(sh.scaledWidth, w)
gl.Uniform1f(sh.scaledHeight, h)
if integerScaling {
gl.Uniform1i(sh.integerScaling, 1)
} else {
gl.Uniform1i(sh.integerScaling, 0)
}
gl.ActiveTexture(gl.TEXTURE1)
gl.BindTexture(gl.TEXTURE_2D, ut)
gl.Uniform1i(sh.unscaledTexture, 1)
gl.BindTexture(gl.TEXTURE_2D, t)
gl.Uniform1i(sh.texture, 1)
}
type guiShader struct {

View file

@ -37,13 +37,8 @@ type playScr struct {
// (re)create textures on next render()
createTextures bool
// textures. scaledTexture is the presentation texture. unscaledTexture is
// the unscaled pixels from screen that are passed through the scaling shader
scaledTexture uint32
unscaledTexture uint32
// the pixels we use to clear scaledTexture with
emptyScaledPixels []uint8
// textures. displayTexture is the presentation texture
displayTexture uint32
// the tv screen has captured mouse input
isCaptured bool
@ -52,12 +47,10 @@ type playScr struct {
imagePosMax imgui.Vec2
// scaling of texture and calculated dimensions
xscaling float32
yscaling float32
scaledWidth float32
scaledHeight float32
unscaledWidth float32
unscaledHeight float32
xscaling float32
yscaling float32
scaledWidth float32
scaledHeight float32
// number of scanlines in current image. taken from screen but is crit section safe
visibleScanlines int
@ -93,28 +86,19 @@ func newPlayScr(img *SdlImgui) *playScr {
}
// set texture, creation of textures will be done after every call to resize()
gl.GenTextures(1, &win.scaledTexture)
gl.BindTexture(gl.TEXTURE_2D, win.scaledTexture)
gl.GenTextures(1, &win.displayTexture)
gl.BindTexture(gl.TEXTURE_2D, win.displayTexture)
// mag and min changed in setScaling() according to whether we want pixel
// perfect rendering
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
// clamp to edge is important for LINEAR filtering. not noticeable for
// NEAREST filtering
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
// source texture - unscaled screen pixels. parameters the same as for
// the screen texture
gl.GenTextures(1, &win.unscaledTexture)
gl.BindTexture(gl.TEXTURE_2D, win.unscaledTexture)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.MIRRORED_REPEAT)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT)
// set scale and padding on startup. scale and padding will be recalculated
// on window resize and textureRenderer.resize()
win.scr.crit.section.Lock()
@ -129,7 +113,7 @@ func (win *playScr) draw() {
defer win.img.screen.crit.section.Unlock()
dl := imgui.BackgroundDrawList()
dl.AddImage(imgui.TextureID(win.scaledTexture), win.imagePosMin, win.imagePosMax)
dl.AddImage(imgui.TextureID(win.displayTexture), win.imagePosMin, win.imagePosMax)
win.peripheralLeft.draw(win)
win.peripheralRight.draw(win)
@ -238,18 +222,8 @@ func (win *playScr) render() {
// (re)create textures
// empty pixels for screen texture
win.emptyScaledPixels = make([]uint8, int(win.scaledWidth)*int(win.scaledHeight)*4)
// screen texture
gl.BindTexture(gl.TEXTURE_2D, win.scaledTexture)
gl.TexImage2D(gl.TEXTURE_2D, 0,
gl.RGBA, int32(pixels.Bounds().Size().X), int32(pixels.Bounds().Size().Y), 0,
gl.RGBA, gl.UNSIGNED_BYTE,
gl.Ptr(win.emptyScaledPixels))
// unscaled screen texture
gl.BindTexture(gl.TEXTURE_2D, win.unscaledTexture)
gl.BindTexture(gl.TEXTURE_2D, win.displayTexture)
gl.TexImage2D(gl.TEXTURE_2D, 0,
gl.RGBA, int32(pixels.Bounds().Size().X), int32(pixels.Bounds().Size().Y), 0,
gl.RGBA, gl.UNSIGNED_BYTE,
@ -261,14 +235,7 @@ func (win *playScr) render() {
// is "unstable"
// screen texture
gl.BindTexture(gl.TEXTURE_2D, win.scaledTexture)
gl.TexSubImage2D(gl.TEXTURE_2D, 0,
0, 0, int32(pixels.Bounds().Size().X), int32(pixels.Bounds().Size().Y),
gl.RGBA, gl.UNSIGNED_BYTE,
gl.Ptr(win.emptyScaledPixels))
// unscaled screen texture
gl.BindTexture(gl.TEXTURE_2D, win.unscaledTexture)
gl.BindTexture(gl.TEXTURE_2D, win.displayTexture)
gl.TexSubImage2D(gl.TEXTURE_2D, 0,
0, 0, int32(pixels.Bounds().Size().X), int32(pixels.Bounds().Size().Y),
gl.RGBA, gl.UNSIGNED_BYTE,
@ -320,19 +287,12 @@ func (win *playScr) setScaling() {
win.xscaling = scaling * pixelWidth * win.scr.crit.frameInfo.Spec.AspectBias
win.scaledWidth = w * win.xscaling
win.scaledHeight = h * win.yscaling
win.unscaledWidth = w
win.unscaledHeight = h
// get visibleScanlines while we're in critical section
win.visibleScanlines = win.scr.crit.frameInfo.VisibleBottom - win.scr.crit.frameInfo.VisibleTop
}
// unscaledTextureSpec implements the scalingImage specification
func (win *playScr) unscaledTextureSpec() (uint32, float32, float32) {
return win.unscaledTexture, win.unscaledWidth, win.unscaledHeight
}
// unscaledTextureSpec implements the scalingImage specification
func (win *playScr) scaledTextureSpec() (uint32, float32, float32) {
return win.scaledTexture, win.scaledWidth, win.scaledHeight
// textureSpec implements the scalingImage specification
func (win *playScr) textureSpec() (uint32, float32, float32) {
return win.displayTexture, win.scaledWidth, win.scaledHeight
}

View file

@ -1,46 +0,0 @@
uniform float ScaledWidth;
uniform float ScaledHeight;
uniform float UnscaledWidth;
uniform float UnscaledHeight;
uniform sampler2D Texture;
uniform sampler2D UnscaledTexture;
uniform int IntegerScaling;
in vec2 Frag_UV;
in vec4 Frag_Color;
out vec4 Out_Color;
void main()
{
Out_Color = Frag_Color * texture(Texture, Frag_UV.st);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st), 1.0);
if (IntegerScaling == 1) {
return;
}
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st-vec2(0.0, 0.00025)), 0.75);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st-vec2(0.0, 0.0005)), 0.75);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st-vec2(0.0, 0.00075)), 0.75);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st-vec2(0.0, 0.001)), 0.75);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st-vec2(0.0, 0.00125)), 0.5);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st-vec2(0.0, 0.0015)), 0.5);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st-vec2(0.0, 0.00175)), 0.5);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st-vec2(0.0, 0.002)), 0.5);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st-vec2(0.0, 0.00225)), 0.25);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st-vec2(0.0, 0.0025)), 0.25);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st-vec2(0.0, 0.00275)), 0.25);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st-vec2(0.0, 0.003)), 0.25);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st+vec2(0.0, 0.00025)), 0.75);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st+vec2(0.0, 0.0005)), 0.75);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st+vec2(0.0, 0.00075)), 0.75);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st+vec2(0.0, 0.001)), 0.75);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st+vec2(0.0, 0.00125)), 0.5);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st+vec2(0.0, 0.0015)), 0.5);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st+vec2(0.0, 0.00175)), 0.5);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st+vec2(0.0, 0.002)), 0.5);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st+vec2(0.0, 0.00225)), 0.25);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st+vec2(0.0, 0.0025)), 0.25);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st+vec2(0.0, 0.00275)), 0.25);
Out_Color = mix(Out_Color, texture(UnscaledTexture, Frag_UV.st+vec2(0.0, 0.003)), 0.25);
}

View file

@ -38,8 +38,8 @@ var DbgScrOverlayShader []byte
//go:embed "dbgscr_helpers.frag"
var DbgScrHelpersShader []byte
//go:embed "scaling.frag"
var ScalingShader []byte
//go:embed "sharpen.frag"
var SharpenShader []byte
//go:embed "crt_effects.frag"
var CRTEffectsFragShader []byte

View file

@ -0,0 +1,23 @@
uniform sampler2D Texture;
in vec2 Frag_UV;
in vec4 Frag_Color;
out vec4 Out_Color;
// sharpen function taken from (licenced under CC0):
// https://gist.github.com/Beefster09/7264303ee4b4b2086f372f1e70e8eddd
#define sharpness 1
float sharpen(float pix_coord) {
float norm = (fract(pix_coord) - 0.5) * 2.0;
float norm2 = norm * norm;
return floor(pix_coord) + norm * pow(norm2, sharpness) / 2.0 + 0.5;
}
void main() {
vec2 vres = textureSize(Texture, 0);
Out_Color = texture(Texture, vec2(
sharpen(Frag_UV.x * vres.x) / vres.x,
sharpen(Frag_UV.y * vres.y) / vres.y
));
}

View file

@ -50,7 +50,6 @@ type winDbgScr struct {
displayTexture uint32
elementsTexture uint32
overlayTexture uint32
screenTexture uint32
// the pixels we use to clear normalTexture with
emptyScaledPixels []uint8
@ -77,12 +76,10 @@ type winDbgScr struct {
screenOrigin imgui.Vec2
// scaling of texture and calculated dimensions
xscaling float32
yscaling float32
scaledWidth float32
scaledHeight float32
unscaledWidth float32
unscaledHeight float32
xscaling float32
yscaling float32
scaledWidth float32
scaledHeight float32
// the dimensions required for the combo widgets
specComboDim imgui.Vec2
@ -107,21 +104,14 @@ func newWinDbgScr(img *SdlImgui) (window, error) {
// set texture, creation of textures will be done after every call to resize()
gl.GenTextures(1, &win.displayTexture)
gl.BindTexture(gl.TEXTURE_2D, win.displayTexture)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
gl.GenTextures(1, &win.overlayTexture)
gl.BindTexture(gl.TEXTURE_2D, win.overlayTexture)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
gl.GenTextures(1, &win.screenTexture)
gl.BindTexture(gl.TEXTURE_2D, win.screenTexture)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.MIRRORED_REPEAT)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT)
gl.GenTextures(1, &win.elementsTexture)
gl.BindTexture(gl.TEXTURE_2D, win.elementsTexture)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
@ -712,7 +702,7 @@ func (win *winDbgScr) render() {
gl.TexImage2D(gl.TEXTURE_2D, 0,
gl.RGBA, int32(pixels.Bounds().Size().X), int32(pixels.Bounds().Size().Y), 0,
gl.RGBA, gl.UNSIGNED_BYTE,
gl.Ptr(win.emptyScaledPixels))
gl.Ptr(pixels.Pix))
gl.BindTexture(gl.TEXTURE_2D, win.overlayTexture)
gl.TexImage2D(gl.TEXTURE_2D, 0,
@ -720,13 +710,6 @@ func (win *winDbgScr) render() {
gl.RGBA, gl.UNSIGNED_BYTE,
gl.Ptr(overlay.Pix))
// unscaled screen texture
gl.BindTexture(gl.TEXTURE_2D, win.screenTexture)
gl.TexImage2D(gl.TEXTURE_2D, 0,
gl.RGBA, int32(pixels.Bounds().Size().X), int32(pixels.Bounds().Size().Y), 0,
gl.RGBA, gl.UNSIGNED_BYTE,
gl.Ptr(pixels.Pix))
gl.BindTexture(gl.TEXTURE_2D, win.elementsTexture)
gl.TexImage2D(gl.TEXTURE_2D, 0,
gl.RGBA, int32(elements.Bounds().Size().X), int32(elements.Bounds().Size().Y), 0,
@ -739,7 +722,7 @@ func (win *winDbgScr) render() {
gl.TexSubImage2D(gl.TEXTURE_2D, 0,
0, 0, int32(pixels.Bounds().Size().X), int32(pixels.Bounds().Size().Y),
gl.RGBA, gl.UNSIGNED_BYTE,
gl.Ptr(win.emptyScaledPixels))
gl.Ptr(pixels.Pix))
gl.BindTexture(gl.TEXTURE_2D, win.overlayTexture)
gl.TexSubImage2D(gl.TEXTURE_2D, 0,
@ -747,13 +730,6 @@ func (win *winDbgScr) render() {
gl.RGBA, gl.UNSIGNED_BYTE,
gl.Ptr(overlay.Pix))
// unscaled screen texture
gl.BindTexture(gl.TEXTURE_2D, win.screenTexture)
gl.TexSubImage2D(gl.TEXTURE_2D, 0,
0, 0, int32(pixels.Bounds().Size().X), int32(pixels.Bounds().Size().Y),
gl.RGBA, gl.UNSIGNED_BYTE,
gl.Ptr(pixels.Pix))
gl.BindTexture(gl.TEXTURE_2D, win.elementsTexture)
gl.TexSubImage2D(gl.TEXTURE_2D, 0,
0, 0, int32(elements.Bounds().Size().X), int32(elements.Bounds().Size().Y),
@ -803,22 +779,12 @@ func (win *winDbgScr) setScaling() {
win.xscaling = scaling * pixelWidth * win.scr.crit.frameInfo.Spec.AspectBias
win.scaledWidth = w * win.xscaling
win.scaledHeight = h * win.yscaling
win.unscaledWidth = w
win.unscaledHeight = h
// get numscanlines while we're in critical section
win.numScanlines = win.scr.crit.frameInfo.VisibleBottom - win.scr.crit.frameInfo.VisibleTop
}
// unscaledTextureSpec implements the scalingImage specification
func (win *winDbgScr) unscaledTextureSpec() (uint32, float32, float32) {
if win.elements && !win.crtPreview {
return win.elementsTexture, win.unscaledWidth, win.unscaledHeight
}
return win.screenTexture, win.unscaledWidth, win.unscaledHeight
}
// unscaledTextureSpec implements the scalingImage specification
func (win *winDbgScr) scaledTextureSpec() (uint32, float32, float32) {
// textureSpec implements the scalingImage specification
func (win *winDbgScr) textureSpec() (uint32, float32, float32) {
return win.displayTexture, win.scaledWidth, win.scaledHeight
}