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