openMSX
GLSimpleScaler.cc
Go to the documentation of this file.
1#include "GLSimpleScaler.hh"
2#include "RenderSettings.hh"
3#include "narrow.hh"
4#include "xrange.hh"
5
6namespace openmsx {
7
9 RenderSettings& renderSettings_, GLScaler& fallback_)
10 : GLScaler("simple")
11 , renderSettings(renderSettings_)
12 , fallback(fallback_)
13{
14 for (auto i : xrange(2)) {
15 program[i].activate();
16 unifTexStepX[i] = program[i].getUniformLocation("texStepX");
17 unifCnst[i] = program[i].getUniformLocation("cnst");
18 }
19}
20
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()) / 256.0f;
30 GLfloat scanline = narrow<float>(renderSettings.getScanlineFactor()) / 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
39 if ((blur != 0.0f) || (scanline != 1.0f) || superImpose) {
40 setup(superImpose != nullptr);
41 if ((blur != 0.0f) && (srcWidth != 1)) { // srcWidth check: workaround for ATI cards
42 src.setInterpolation(true);
43 }
44 auto yScaleF = narrow<GLfloat>(yScale);
45 GLfloat scan_a = (yScale & 1) ? 0.5f : ((yScaleF + 1.0f) / (2.0f * yScaleF));
46 GLfloat scan_b = 2.0f - 2.0f * scanline;
47 GLfloat scan_c = scanline;
48 if (!superImpose) {
49 // small optimization in simple.frag:
50 // divide by 2 here instead of on every pixel
51 scan_b *= 0.5f;
52 scan_c *= 0.5f;
53 }
54 auto recipSrcWidth = 1.0f / narrow<float>(srcWidth);
55 glUniform3f(unifTexStepX[i], recipSrcWidth, recipSrcWidth, 0.0f);
56 glUniform4f(unifCnst[i], scan_a, scan_b, scan_c, blur);
57
58 execute(src, superImpose,
59 srcStartY, srcEndY, srcWidth,
60 dstStartY, dstEndY, dstWidth,
61 logSrcHeight);
62
63 src.setInterpolation(false);
64 } else {
65 fallback.scaleImage(src, superImpose, srcStartY, srcEndY, srcWidth,
66 dstStartY, dstEndY, dstWidth, logSrcHeight);
67 }
68}
69
70} // namespace openmsx
void setInterpolation(bool interpolation)
Enable/disable bilinear interpolation for this texture.
Definition: GLUtil.cc:47
Abstract base class for OpenGL scalers.
Definition: GLScaler.hh:16
void setup(bool superImpose)
Definition: GLScaler.cc:40
std::array< gl::ShaderProgram, 2 > program
Definition: GLScaler.hh:80
void execute(gl::ColorTexture &src, gl::ColorTexture *superImpose, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, unsigned dstStartY, unsigned dstEndY, unsigned dstWidth, unsigned logSrcHeight, bool textureFromZero=false)
Helper method to draw a rectangle with multiple texture coordinates.
Definition: GLScaler.cc:46
virtual void scaleImage(gl::ColorTexture &src, gl::ColorTexture *superImpose, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, unsigned dstStartY, unsigned dstEndY, unsigned dstWidth, unsigned logSrcHeight)=0
Scales the image in the given area, which must consist of lines which are all equally wide.
GLSimpleScaler(RenderSettings &renderSettings, GLScaler &fallback)
void scaleImage(gl::ColorTexture &src, gl::ColorTexture *superImpose, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, unsigned dstStartY, unsigned dstEndY, unsigned dstWidth, unsigned logSrcHeight) override
Scales the image in the given area, which must consist of lines which are all equally wide.
Class containing all settings for renderers.
int getScanlineFactor() const
The alpha value [0..255] of the gap between scanlines.
int getBlurFactor() const
The amount of horizontal blur [0..256].
This file implemented 3 utility functions:
Definition: Autofire.cc:9
constexpr auto xrange(T e)
Definition: xrange.hh:133