OXYGENHUB
◆ main openmsx / src / video / scalers / GLSimpleScaler.cc
2.2 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#include "GLSimpleScaler.hh"
2
3
#include "RenderSettings.hh"
4
5
#include "narrow.hh"
6
#include "xrange.hh"
7
8
namespace openmsx {
9
10
GLSimpleScaler::GLSimpleScaler(
11
		RenderSettings& renderSettings_, GLScaler& fallback_)
12
	: GLScaler("simple")
13
	, renderSettings(renderSettings_)
14
	, fallback(fallback_)
15
{
16
	for (auto i : xrange(2)) {
17
		program[i].activate();
18
		unifTexStepX[i] = program[i].getUniformLocation("texStepX");
19
		unifCnst[i]     = program[i].getUniformLocation("cnst");
20
	}
21
}
22
23
void GLSimpleScaler::scaleImage(
24
	gl::ColorTexture& src, gl::ColorTexture* superImpose,
25
	unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
26
	unsigned dstStartY, unsigned dstEndY, unsigned dstWidth,
27
	unsigned logSrcHeight)
28
{
29
	int i = superImpose ? 1 : 0;
30
31
	GLfloat blur = narrow<float>(renderSettings.getBlurFactor()) * (1.0f / 256.0f);
32
	GLfloat scanline = narrow<float>(renderSettings.getScanlineFactor()) * (1.0f / 255.0f);
33
	unsigned yScale = (dstEndY - dstStartY) / (srcEndY - srcStartY);
34
	if (yScale == 0) {
35
		// less lines in destination than in source
36
		// (factor=1 / interlace) --> disable scanlines
37
		scanline = 1.0f;
38
		yScale = 1;
39
	}
40
41
	if ((blur != 0.0f) || (scanline != 1.0f) || superImpose) {
42
		setup(superImpose != nullptr);
43
		if ((blur != 0.0f) && (srcWidth != 1)) { // srcWidth check: workaround for ATI cards
44
			src.setInterpolation(true);
45
		}
46
		auto yScaleF = narrow<GLfloat>(yScale);
47
		GLfloat scan_a = (yScale & 1) ? 0.5f : ((yScaleF + 1.0f) / (2.0f * yScaleF));
48
		GLfloat scan_b = 2.0f - 2.0f * scanline;
49
		GLfloat scan_c = scanline;
50
		if (!superImpose) {
51
			// small optimization in simple.frag:
52
			// divide by 2 here instead of on every pixel
53
			scan_b *= 0.5f;
54
			scan_c *= 0.5f;
55
		}
56
		auto recipSrcWidth = 1.0f / narrow<float>(srcWidth);
57
		glUniform3f(unifTexStepX[i], recipSrcWidth, recipSrcWidth, 0.0f);
58
		glUniform4f(unifCnst[i], scan_a, scan_b, scan_c, blur);
59
60
		execute(src, superImpose,
61
		        srcStartY, srcEndY, srcWidth,
62
		        dstStartY, dstEndY, dstWidth,
63
		        logSrcHeight);
64
65
		src.setInterpolation(false);
66
	} else {
67
		fallback.scaleImage(src, superImpose, srcStartY, srcEndY, srcWidth,
68
		                    dstStartY, dstEndY, dstWidth, logSrcHeight);
69
	}
70
}
71
72
} // namespace openmsx