openMSX
GLRGBScaler.cc
Go to the documentation of this file.
1 #include "GLRGBScaler.hh"
2 #include "GLUtil.hh"
3 #include "RenderSettings.hh"
4 #include "memory.hh"
5 
6 using std::string;
7 
8 namespace openmsx {
9 
11  : renderSettings(renderSettings_)
12 {
13  for (int i = 0; i < 2; ++i) {
14  Data& d = data[i];
15 
16  string header = string("#define SUPERIMPOSE ")
17  + char('0' + i) + '\n';
18  VertexShader vertexShader (header, "rgb.vert");
19  FragmentShader fragmentShader(header, "rgb.frag");
20  d.scalerProgram.attach(vertexShader);
21  d.scalerProgram.attach(fragmentShader);
22  d.scalerProgram.link();
23 #ifdef GL_VERSION_2_0
24  if (GLEW_VERSION_2_0) {
25  d.scalerProgram.activate();
26  glUniform1i(d.scalerProgram.getUniformLocation("tex"), 0);
27  if (i == 1) {
28  glUniform1i(d.scalerProgram.getUniformLocation("videoTex"), 1);
29  }
30  d.texSizeLoc = d.scalerProgram.getUniformLocation("texSize");
31  d.cnstsLoc = d.scalerProgram.getUniformLocation("cnsts");
32  }
33 #endif
34  }
35 }
36 
38  ColorTexture& src, ColorTexture* superImpose,
39  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
40  unsigned dstStartY, unsigned dstEndY, unsigned dstWidth,
41  unsigned logSrcHeight)
42 {
43  Data& d = data[superImpose ? 1 : 0];
44 
45  GLfloat blur = renderSettings.getBlurFactor() / 256.0f;
46  GLfloat scanline = renderSettings.getScanlineFactor() / 255.0f;
47  unsigned yScale = (dstEndY - dstStartY) / (srcEndY - srcStartY);
48  if (yScale == 0) {
49  // less lines in destination than in source
50  // (factor=1 / interlace) --> disable scanlines
51  scanline = 1.0f;
52  yScale = 1;
53  }
54  if (srcWidth != 1) {
55  // workaround for ATI cards
56  src.enableInterpolation();
57  } else {
58  // treat border as 256-pixel wide display area
59  srcWidth = 320;
60  }
61  if (GLEW_VERSION_2_0 && ((blur != 0.0f) || (scanline != 1.0f) || superImpose)) {
62  if (superImpose) {
63  glActiveTexture(GL_TEXTURE1);
64  superImpose->bind();
65  glActiveTexture(GL_TEXTURE0);
66  }
67  d.scalerProgram.activate();
68  glUniform2f(d.texSizeLoc, srcWidth, src.getHeight());
69  GLfloat a = (yScale & 1) ? 0.5f : ((yScale + 1) / (2.0f * yScale));
70  GLfloat c1 = blur;
71  GLfloat c2 = 3.0f - 2.0f * c1;
72  glUniform4f(d.cnstsLoc,
73  a, // scan_a
74  (1.0f - scanline) * 2.0f * c2, // scan_b_c2
75  scanline * c2, // scan_c_c2
76  (c1 - c2) / c2); // scan_c1_2_2
77  }
78  drawMultiTex(src, srcStartY, srcEndY, src.getHeight(), logSrcHeight,
79  dstStartY, dstEndY, dstWidth);
81 }
82 
83 } // namespace openmsx