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