openMSX
GLScaler.cc
Go to the documentation of this file.
1 #include "GLScaler.hh"
2 #include "GLContext.hh"
3 #include "gl_vec.hh"
4 #include "strCat.hh"
5 #include "xrange.hh"
6 
7 using std::string;
8 using namespace gl;
9 
10 namespace openmsx {
11 
12 GLScaler::GLScaler(const string& progName)
13 {
14  for (auto i : xrange(2)) {
15  auto header = tmpStrCat("#define SUPERIMPOSE ", char('0' + i), '\n');
16  VertexShader vShader(header, progName + ".vert");
17  FragmentShader fShader(header, progName + ".frag");
18  program[i].attach(vShader);
19  program[i].attach(fShader);
20  program[i].bindAttribLocation(0, "a_position");
21  program[i].bindAttribLocation(1, "a_texCoord");
22  program[i].link();
23  program[i].activate();
24  glUniform1i(program[i].getUniformLocation("tex"), 0);
25  if (i == 1) {
26  glUniform1i(program[i].getUniformLocation("videoTex"), 1);
27  }
28  unifTexSize[i] = program[i].getUniformLocation("texSize");
29  glUniformMatrix4fv(program[i].getUniformLocation("u_mvpMatrix"),
30  1, GL_FALSE, &gl::context->pixelMvp[0][0]);
31  }
32 }
33 
34 void GLScaler::uploadBlock(
35  unsigned /*srcStartY*/, unsigned /*srcEndY*/,
36  unsigned /*lineWidth*/, FrameSource& /*paintFrame*/)
37 {
38 }
39 
40 void GLScaler::setup(bool superImpose)
41 {
42  int i = superImpose ? 1 : 0;
43  program[i].activate();
44 }
45 
46 void GLScaler::execute(
47  ColorTexture& src, ColorTexture* superImpose,
48  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
49  unsigned dstStartY, unsigned dstEndY, unsigned dstWidth,
50  unsigned logSrcHeight, bool textureFromZero)
51 {
52  if (superImpose) {
53  glActiveTexture(GL_TEXTURE1);
54  superImpose->bind();
55  glActiveTexture(GL_TEXTURE0);
56  }
57  int i = superImpose ? 1 : 0;
58  glUniform3f(unifTexSize[i], srcWidth, src.getHeight(), logSrcHeight);
59 
60  src.bind();
61  // Note: hShift is pre-divided by srcWidth, while vShift will be divided
62  // by srcHeight later on.
63  // Note: The coordinate is put just past zero, to avoid fract() in the
64  // fragment shader to wrap around on rounding errors.
65  constexpr float BIAS = 0.001f;
66  float samplePos = (textureFromZero ? 0.5f : 0.0f) + BIAS;
67  float hShift = samplePos / dstWidth;
68  float yRatio = float(srcEndY - srcStartY) / float(dstEndY - dstStartY);
69  float vShift = samplePos * yRatio;
70 
71  // vertex positions
72  vec2 pos[4] = {
73  vec2( 0, dstStartY),
74  vec2(dstWidth, dstStartY),
75  vec2(dstWidth, dstEndY ),
76  vec2( 0, dstEndY ),
77  };
78  // texture coordinates, X-coord shared, Y-coord separate for tex0 and tex1
79  float tex0StartY = float(srcStartY + vShift) / src.getHeight();
80  float tex0EndY = float(srcEndY + vShift) / src.getHeight();
81  float tex1StartY = float(srcStartY + vShift) / logSrcHeight;
82  float tex1EndY = float(srcEndY + vShift) / logSrcHeight;
83  vec3 tex[4] = {
84  vec3(0.0f + hShift, tex0StartY, tex1StartY),
85  vec3(1.0f + hShift, tex0StartY, tex1StartY),
86  vec3(1.0f + hShift, tex0EndY , tex1EndY ),
87  vec3(0.0f + hShift, tex0EndY , tex1EndY ),
88  };
89 
90  glBindBuffer(GL_ARRAY_BUFFER, vbo[0].get());
91  glBufferData(GL_ARRAY_BUFFER, sizeof(pos), pos, GL_STREAM_DRAW);
92  glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
93 
94  glBindBuffer(GL_ARRAY_BUFFER, vbo[1].get());
95  glBufferData(GL_ARRAY_BUFFER, sizeof(tex), tex, GL_STREAM_DRAW);
96  glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
97 
98  glEnableVertexAttribArray(0);
99  glEnableVertexAttribArray(1);
100 
101  glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
102 
103  glDisableVertexAttribArray(1);
104  glDisableVertexAttribArray(0);
105  glBindBuffer(GL_ARRAY_BUFFER, 0);
106 }
107 
108 } // namespace openmsx
GLsizei getHeight() const
Definition: GLUtil.hh:113
Wrapper around an OpenGL fragment shader: a program executed on the GPU that computes the colors of p...
Definition: GLUtil.hh:374
void bind()
Makes this texture the active GL texture.
Definition: GLUtil.hh:83
Wrapper around an OpenGL vertex shader: a program executed on the GPU that computes per-vertex stuff.
Definition: GLUtil.hh:359
Interface for getting lines from a video frame.
Definition: FrameSource.hh:15
Definition: gl_mat.hh:23
vecN< 3, float > vec3
Definition: gl_vec.hh:140
vecN< 2, float > vec2
Definition: gl_vec.hh:139
std::unique_ptr< Context > context
Definition: GLContext.cc:9
This file implemented 3 utility functions:
Definition: Autofire.cc:9
TemporaryString tmpStrCat(Ts &&... ts)
Definition: strCat.hh:659
constexpr auto xrange(T e)
Definition: xrange.hh:155