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
7using namespace gl;
8
9namespace openmsx {
10
11GLScaler::GLScaler(const std::string& progName)
12{
13 for (auto i : xrange(2)) {
14 auto header = tmpStrCat("#define SUPERIMPOSE ", 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
34 unsigned /*srcStartY*/, unsigned /*srcEndY*/,
35 unsigned /*lineWidth*/, FrameSource& /*paintFrame*/)
36{
37}
38
39void GLScaler::setup(bool superImpose)
40{
41 int i = superImpose ? 1 : 0;
42 program[i].activate();
43}
44
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 constexpr float BIAS = 0.001f;
65 float samplePos = (textureFromZero ? 0.5f : 0.0f) + BIAS;
66 float hShift = samplePos / dstWidth;
67 float yRatio = float(srcEndY - srcStartY) / float(dstEndY - dstStartY);
68 float vShift = samplePos * yRatio;
69
70 // vertex positions
71 vec2 pos[4] = {
72 vec2( 0, dstStartY),
73 vec2(dstWidth, dstStartY),
74 vec2(dstWidth, dstEndY ),
75 vec2( 0, dstEndY ),
76 };
77 // texture coordinates, X-coord shared, Y-coord separate for tex0 and tex1
78 float tex0StartY = float(srcStartY + vShift) / src.getHeight();
79 float tex0EndY = float(srcEndY + vShift) / src.getHeight();
80 float tex1StartY = float(srcStartY + vShift) / logSrcHeight;
81 float tex1EndY = float(srcEndY + vShift) / logSrcHeight;
82 vec3 tex[4] = {
83 vec3(0.0f + hShift, tex0StartY, tex1StartY),
84 vec3(1.0f + hShift, tex0StartY, tex1StartY),
85 vec3(1.0f + hShift, tex0EndY , tex1EndY ),
86 vec3(0.0f + hShift, tex0EndY , tex1EndY ),
87 };
88
89 glBindBuffer(GL_ARRAY_BUFFER, vbo[0].get());
90 glBufferData(GL_ARRAY_BUFFER, sizeof(pos), pos, GL_STREAM_DRAW);
91 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
92
93 glBindBuffer(GL_ARRAY_BUFFER, vbo[1].get());
94 glBufferData(GL_ARRAY_BUFFER, sizeof(tex), tex, GL_STREAM_DRAW);
95 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
96
97 glEnableVertexAttribArray(0);
98 glEnableVertexAttribArray(1);
99
100 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
101
102 glDisableVertexAttribArray(1);
103 glDisableVertexAttribArray(0);
104 glBindBuffer(GL_ARRAY_BUFFER, 0);
105}
106
107} // namespace openmsx
GLsizei getHeight() const
Definition: GLUtil.hh:111
Wrapper around an OpenGL fragment shader: a program executed on the GPU that computes the colors of p...
Definition: GLUtil.hh:372
void activate() const
Makes this program the active shader program.
Definition: GLUtil.cc:265
void attach(const Shader &shader)
Adds a given shader to this program.
Definition: GLUtil.cc:220
void link()
Links all attached shaders together into one program.
Definition: GLUtil.cc:232
void bindAttribLocation(unsigned index, const char *name)
Bind the given name for a vertex shader attribute to the given location.
Definition: GLUtil.cc:252
GLint getUniformLocation(const char *name) const
Gets a reference to a uniform variable declared in the shader source.
Definition: GLUtil.cc:257
void bind()
Makes this texture the active GL texture.
Definition: GLUtil.hh:81
Wrapper around an OpenGL vertex shader: a program executed on the GPU that computes per-vertex stuff.
Definition: GLUtil.hh:357
Interface for getting lines from a video frame.
Definition: FrameSource.hh:17
void setup(bool superImpose)
Definition: GLScaler.cc:39
GLScaler(const std::string &progName)
Definition: GLScaler.cc:11
void execute(gl::ColorTexture &src, gl::ColorTexture *superImpose, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, unsigned dstStartY, unsigned dstEndY, unsigned dstWidth, unsigned logSrcHeight, bool textureFromZero=false)
Helper method to draw a rectangle with multiple texture coordinates.
Definition: GLScaler.cc:45
virtual void uploadBlock(unsigned srcStartY, unsigned srcEndY, unsigned lineWidth, FrameSource &paintFrame)
Definition: GLScaler.cc:33
gl::BufferObject vbo[2]
Definition: GLScaler.hh:78
GLint unifTexSize[2]
Definition: GLScaler.hh:80
gl::ShaderProgram program[2]
Definition: GLScaler.hh:79
Definition: gl_mat.hh:23
vecN< 3, float > vec3
Definition: gl_vec.hh:149
vecN< 2, float > vec2
Definition: gl_vec.hh:148
std::optional< Context > context
Definition: GLContext.cc:9
This file implemented 3 utility functions:
Definition: Autofire.cc:9
const T & get(const Event &event)
Definition: Event.hh:724
TemporaryString tmpStrCat(Ts &&... ts)
Definition: strCat.hh:617
constexpr auto xrange(T e)
Definition: xrange.hh:133