openMSX
GLSnow.cc
Go to the documentation of this file.
1 #include "GLSnow.hh"
2 #include "GLContext.hh"
3 #include "gl_mat.hh"
4 #include "Display.hh"
5 #include "gl_vec.hh"
6 #include "openmsx.hh"
7 #include "random.hh"
8 
9 using namespace gl;
10 
11 namespace openmsx {
12 
13 GLSnow::GLSnow(Display& display_)
14  : Layer(COVER_FULL, Z_BACKGROUND)
15  , display(display_)
16  , noiseTexture(true, true) // enable interpolation + wrapping
17 {
18  // Create noise texture.
19  auto& generator = global_urng(); // fast (non-cryptographic) random numbers
20  std::uniform_int_distribution<int> distribution(0, 255);
21  byte buf[128 * 128];
22  for (auto& b : buf) {
23  b = distribution(generator);
24  }
25  glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 128, 128, 0,
26  GL_LUMINANCE, GL_UNSIGNED_BYTE, buf);
27 }
28 
29 void GLSnow::paint(OutputSurface& /*output*/)
30 {
31  // Rotate and mirror noise texture in consecutive frames to avoid
32  // seeing 'patterns' in the noise.
33  static const vec2 pos[8][4] = {
34  { { -1, -1 }, { 1, -1 }, { 1, 1 }, { -1, 1 } },
35  { { -1, 1 }, { 1, 1 }, { 1, -1 }, { -1, -1 } },
36  { { -1, 1 }, { -1, -1 }, { 1, -1 }, { 1, 1 } },
37  { { 1, 1 }, { 1, -1 }, { -1, -1 }, { -1, 1 } },
38  { { 1, 1 }, { -1, 1 }, { -1, -1 }, { 1, -1 } },
39  { { 1, -1 }, { -1, -1 }, { -1, 1 }, { 1, 1 } },
40  { { 1, -1 }, { 1, 1 }, { -1, 1 }, { -1, -1 } },
41  { { -1, -1 }, { -1, 1 }, { 1, 1 }, { 1, -1 } }
42  };
43  static unsigned cnt = 0;
44  cnt = (cnt + 1) % 8;
45 
46  vec2 offset(random_float(0.0f, 1.0f) ,random_float(0.0f, 1.0f));
47  const vec2 tex[4] = {
48  offset + vec2(0.0f, 2.0f),
49  offset + vec2(2.0f, 2.0f),
50  offset + vec2(2.0f, 0.0f),
51  offset + vec2(0.0f, 0.0f)
52  };
53 
54  gl::context->progTex.activate();
55  glUniform4f(gl::context->unifTexColor, 1.0f, 1.0f, 1.0f, 1.0f);
56  mat4 I;
57  glUniformMatrix4fv(gl::context->unifTexMvp, 1, GL_FALSE, &I[0][0]);
58  glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, pos[cnt]);
59  glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, tex);
60  glEnableVertexAttribArray(0);
61  glEnableVertexAttribArray(1);
62  noiseTexture.bind();
63  glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
64 
65  display.repaintDelayed(100 * 1000); // 10fps
66 }
67 
68 } // namespace openmsx
signed char offset
Definition: CPUCore.cc:252
Represents the output window/screen of openMSX.
Definition: Display.hh:32
unsigned char byte
8 bit unsigned integer
Definition: openmsx.hh:27
Interface for display layers.
Definition: Layer.hh:11
A frame buffer where pixels can be written to.
void bind()
Makes this texture the active GL texture.
Definition: GLUtil.hh:75
std::unique_ptr< Context > context
Definition: GLContext.cc:9
float random_float(float from, float upto)
Return a random float in the range [from, upto) (note: half-open interval).
Definition: random.hh:50
void repaintDelayed(uint64_t delta)
Definition: Display.cc:388
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:7
std::minstd_rand0 & global_urng()
Return reference to a (shared) global random number generator.
Definition: random.hh:8
vecN< 2, float > vec2
Definition: gl_vec.hh:118
Definition: gl_mat.hh:23
void paint(OutputSurface &output) override
Paint this layer.
Definition: GLSnow.cc:29