openMSX
GLSimpleScaler.cc
Go to the documentation of this file.
1 #include "GLSimpleScaler.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, "simple.vert");
19  FragmentShader fragmentShader(header, "simple.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  data[i].scalerProgram.activate();
26  GLint texLoc = d.scalerProgram.getUniformLocation("tex");
27  glUniform1i(texLoc, 0);
28  if (i == 1) {
29  GLint texLoc2 = d.scalerProgram.getUniformLocation("videoTex");
30  glUniform1i(texLoc2, 1);
31  }
32  data[i].texSizeLoc = d.scalerProgram.getUniformLocation("texSize");
33  data[i].texStepXLoc = d.scalerProgram.getUniformLocation("texStepX");
34  data[i].cnstLoc = d.scalerProgram.getUniformLocation("cnst");
35  }
36 #endif
37  }
38 }
39 
41  ColorTexture& src, ColorTexture* superImpose,
42  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
43  unsigned dstStartY, unsigned dstEndY, unsigned dstWidth,
44  unsigned logSrcHeight)
45 {
46  Data& d = data[superImpose ? 1 : 0];
47 
48  GLfloat blur = renderSettings.getBlurFactor() / 256.0f;
49  GLfloat scanline = renderSettings.getScanlineFactor() / 255.0f;
50  unsigned yScale = (dstEndY - dstStartY) / (srcEndY - srcStartY);
51  if (yScale == 0) {
52  // less lines in destination than in source
53  // (factor=1 / interlace) --> disable scanlines
54  scanline = 1.0f;
55  yScale = 1;
56  }
57 
58  if ((blur != 0.0f) && (srcWidth != 1)) { // srcWidth check: workaround for ATI cards
59  src.enableInterpolation();
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  GLfloat scan_a = (yScale & 1) ? 0.5f : ((yScale + 1) / (2.0f * yScale));
69  GLfloat scan_b = 2.0f - 2.0f * scanline;
70  GLfloat scan_c = scanline;
71  if (!superImpose) {
72  // small optimization in simple.frag:
73  // divide by 2 here instead of on every pixel
74  scan_b *= 0.5f;
75  scan_c *= 0.5f;
76  }
77  glUniform2f(d.texSizeLoc, srcWidth, src.getHeight());
78  glUniform3f(d.texStepXLoc, 1.0f / srcWidth, 1.0f / srcWidth, 0.0f);
79  glUniform4f(d.cnstLoc, scan_a, scan_b, scan_c, blur);
80  }
81 
82  // actually draw texture
83  drawMultiTex(src, srcStartY, srcEndY, src.getHeight(), logSrcHeight,
84  dstStartY, dstEndY, dstWidth);
86 }
87 
88 } // namespace openmsx