openMSX
GLSnow.cc
Go to the documentation of this file.
1#include "GLSnow.hh"
2
3#include "GLContext.hh"
4#include "gl_mat.hh"
5#include "Display.hh"
6#include "gl_vec.hh"
7#include "openmsx.hh"
8#include "random.hh"
9
10using namespace gl;
11
12namespace openmsx {
13
15 : Layer(Coverage::FULL, ZIndex::BACKGROUND)
16 , display(display_)
17 , noiseTexture(true, true) // enable interpolation + wrapping
18{
19 // Create noise texture.
20 auto& generator = global_urng(); // fast (non-cryptographic) random numbers
21 std::uniform_int_distribution distribution(0, 255);
22 std::array<uint8_t, 128 * 128> buf;
23 ranges::generate(buf, [&] { return distribution(generator); });
24#if OPENGL_VERSION < OPENGL_3_3
25 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 128, 128, 0,
26 GL_LUMINANCE, GL_UNSIGNED_BYTE, buf.data());
27#else
28 // GL_LUMINANCE no longer supported in newer versions
29 glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 128, 128, 0,
30 GL_RED, GL_UNSIGNED_BYTE, buf.data());
31 GLint swizzleMask[] = {GL_RED, GL_RED, GL_RED, GL_ONE};
32 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
33#endif
34
35 static constexpr std::array pos = {
36 std::array{vec2{-1, -1}, vec2{ 1, -1}, vec2{ 1, 1}, vec2{-1, 1}},
37 std::array{vec2{-1, 1}, vec2{ 1, 1}, vec2{ 1, -1}, vec2{-1, -1}},
38 std::array{vec2{-1, 1}, vec2{-1, -1}, vec2{ 1, -1}, vec2{ 1, 1}},
39 std::array{vec2{ 1, 1}, vec2{ 1, -1}, vec2{-1, -1}, vec2{-1, 1}},
40 std::array{vec2{ 1, 1}, vec2{-1, 1}, vec2{-1, -1}, vec2{ 1, -1}},
41 std::array{vec2{ 1, -1}, vec2{-1, -1}, vec2{-1, 1}, vec2{ 1, 1}},
42 std::array{vec2{ 1, -1}, vec2{ 1, 1}, vec2{-1, 1}, vec2{-1, -1}},
43 std::array{vec2{-1, -1}, vec2{-1, 1}, vec2{ 1, 1}, vec2{ 1, -1}},
44 };
45 glBindBuffer(GL_ARRAY_BUFFER, vbo[0].get());
46 glBufferData(GL_ARRAY_BUFFER, sizeof(pos), pos.data(), GL_STATIC_DRAW);
47 glBindBuffer(GL_ARRAY_BUFFER, 0);
48}
49
51{
52 // Rotate and mirror noise texture in consecutive frames to avoid
53 // seeing 'patterns' in the noise.
54 static unsigned cnt = 0;
55 cnt = (cnt + 1) % 8;
56
57 vec2 offset(random_float(0.0f, 1.0f), random_float(0.0f, 1.0f));
58 const std::array tex = {
59 offset + vec2(0.0f, 2.0f),
60 offset + vec2(2.0f, 2.0f),
61 offset + vec2(2.0f, 0.0f),
62 offset + vec2(0.0f, 0.0f),
63 };
64
65 const auto& glContext = *gl::context;
66 glContext.progTex.activate();
67 glUniform4f(glContext.unifTexColor, 1.0f, 1.0f, 1.0f, 1.0f);
68 mat4 I;
69 glUniformMatrix4fv(glContext.unifTexMvp, 1, GL_FALSE, I.data());
70
71 glBindBuffer(GL_ARRAY_BUFFER, vbo[0].get());
72 const vec2* base = nullptr;
73 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, base + 4 * cnt);
74 glEnableVertexAttribArray(0);
75
76 glBindBuffer(GL_ARRAY_BUFFER, vbo[1].get());
77 glBufferData(GL_ARRAY_BUFFER, sizeof(tex), tex.data(), GL_STREAM_DRAW);
78 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
79 glEnableVertexAttribArray(1);
80
81 noiseTexture.bind();
82 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
83 glDisableVertexAttribArray(1);
84 glDisableVertexAttribArray(0);
85 glBindBuffer(GL_ARRAY_BUFFER, 0);
86
87 display.repaintDelayed(100 * 1000); // 10fps
88}
89
90} // namespace openmsx
void bind() const
Makes this texture the active GL texture.
Definition GLUtil.hh:87
constexpr const T * data() const
Definition gl_mat.hh:100
Represents the output window/screen of openMSX.
Definition Display.hh:31
void repaintDelayed(uint64_t delta)
Definition Display.cc:380
void paint(OutputSurface &output) override
Paint this layer.
Definition GLSnow.cc:50
GLSnow(Display &display)
Definition GLSnow.cc:14
Interface for display layers.
Definition Layer.hh:14
Coverage
Describes how much of the screen is currently covered by a particular layer.
Definition Layer.hh:31
ZIndex
Determines stacking order of layers: layers with higher Z-indices are closer to the viewer.
Definition Layer.hh:19
A frame buffer where pixels can be written to.
Definition gl_mat.hh:23
vecN< 2, float > vec2
Definition gl_vec.hh:178
std::optional< Context > context
Definition GLContext.cc:10
This file implemented 3 utility functions:
Definition Autofire.cc:11
void generate(ForwardRange &&range, Generator &&g)
Definition ranges.hh:285
auto & global_urng()
Return reference to a (shared) global random number generator.
Definition random.hh:8
float random_float(float from, float upto)
Return a random float in the range [from, upto) (note: half-open interval).
Definition random.hh:50