openMSX
GLRGBScaler.cc
Go to the documentation of this file.
1 #include "GLRGBScaler.hh"
2 #include "GLUtil.hh"
3 #include "RenderSettings.hh"
4 
5 using std::string;
6 
7 namespace openmsx {
8 
10  : renderSettings(renderSettings_)
11 {
12  for (int i = 0; i < 2; ++i) {
13  Data& d = data[i];
14 
15  string header = string("#define SUPERIMPOSE ")
16  + char('0' + i) + '\n';
17  VertexShader vertexShader (header, "rgb.vert");
18  FragmentShader fragmentShader(header, "rgb.frag");
19  d.scalerProgram.attach(vertexShader);
20  d.scalerProgram.attach(fragmentShader);
21  d.scalerProgram.link();
22 
23  d.scalerProgram.activate();
24  glUniform1i(d.scalerProgram.getUniformLocation("tex"), 0);
25  if (i == 1) {
26  glUniform1i(d.scalerProgram.getUniformLocation("videoTex"), 1);
27  }
28  d.texSizeLoc = d.scalerProgram.getUniformLocation("texSize");
29  d.cnstsLoc = d.scalerProgram.getUniformLocation("cnsts");
30  }
31 }
32 
34  ColorTexture& src, ColorTexture* superImpose,
35  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
36  unsigned dstStartY, unsigned dstEndY, unsigned dstWidth,
37  unsigned logSrcHeight)
38 {
39  Data& d = data[superImpose ? 1 : 0];
40 
41  GLfloat blur = renderSettings.getBlurFactor() / 256.0f;
42  GLfloat scanline = renderSettings.getScanlineFactor() / 255.0f;
43  unsigned yScale = (dstEndY - dstStartY) / (srcEndY - srcStartY);
44  if (yScale == 0) {
45  // less lines in destination than in source
46  // (factor=1 / interlace) --> disable scanlines
47  scanline = 1.0f;
48  yScale = 1;
49  }
50  if (srcWidth != 1) {
51  // workaround for ATI cards
52  src.enableInterpolation();
53  } else {
54  // treat border as 256-pixel wide display area
55  srcWidth = 320;
56  }
57  if (((blur != 0.0f) || (scanline != 1.0f) || superImpose)) {
58  if (superImpose) {
59  glActiveTexture(GL_TEXTURE1);
60  superImpose->bind();
61  glActiveTexture(GL_TEXTURE0);
62  }
63  d.scalerProgram.activate();
64  glUniform2f(d.texSizeLoc, srcWidth, src.getHeight());
65  GLfloat a = (yScale & 1) ? 0.5f : ((yScale + 1) / (2.0f * yScale));
66  GLfloat c1 = blur;
67  GLfloat c2 = 3.0f - 2.0f * c1;
68  glUniform4f(d.cnstsLoc,
69  a, // scan_a
70  (1.0f - scanline) * 2.0f * c2, // scan_b_c2
71  scanline * c2, // scan_c_c2
72  (c1 - c2) / c2); // scan_c1_2_2
73  }
74  drawMultiTex(src, srcStartY, srcEndY, src.getHeight(), logSrcHeight,
75  dstStartY, dstEndY, dstWidth);
77 }
78 
79 } // namespace openmsx
virtual void scaleImage(ColorTexture &src, ColorTexture *superImpose, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, unsigned dstStartY, unsigned dstEndY, unsigned dstWidth, unsigned logSrcHeight)
Scales the image in the given area, which must consist of lines which are all equally wide...
Definition: GLRGBScaler.cc:33
Wrapper around an OpenGL fragment shader: a program executed on the GPU that computes the colors of p...
Definition: GLUtil.hh:426
Wrapper around an OpenGL vertex shader: a program executed on the GPU that computes per-vertex stuff...
Definition: GLUtil.hh:413
void drawMultiTex(ColorTexture &src, unsigned srcStartY, unsigned srcEndY, float physSrcHeight, float logSrcHeight, unsigned dstStartY, unsigned dstEndY, unsigned dstWidth, bool textureFromZero=false)
Helper method to draw a rectangle with multiple texture coordinates.
Definition: GLScaler.cc:48
GLRGBScaler(RenderSettings &renderSettings)
Definition: GLRGBScaler.cc:9
void disableInterpolation()
Disables bilinear interpolation for this texture and uses nearest neighbour instead.
Definition: GLUtil.cc:56
void bind()
Makes this texture the active GL texture.
Definition: GLUtil.hh:61
int getBlurFactor() const
The amount of horizontal blur [0..256].
GLsizei getHeight() const
Definition: GLUtil.hh:119
Class containing all settings for renderers.
void enableInterpolation()
Enables bilinear interpolation for this texture.
Definition: GLUtil.cc:49
int getScanlineFactor() const
The alpha value [0..255] of the gap between scanlines.