noise.odin ¶
1package draw_texture
2
3import "base:runtime"
4
5import "core:c"
6import "core:fmt"
7import "core:math/linalg/glsl"
8import "core:math/noise"
9import "core:mem"
10
11import "vendor:glfw"
12import gl "vendor:OpenGL"
13
14WIDTH :: 400
15HEIGHT :: 400
16TITLE :: cstring("Open Simplex 2 Texture!")
17
18
19GL_MAJOR_VERSION :: 4
20GL_MINOR_VERSION :: 1
21
22Adjust_Noise :: struct {
23 seed: i64,
24 octaves: i32,
25 frequency: f64,
26}
27
28Vertices :: [16]f32
29
30create_vertices :: proc(x, y, width, height: f32) -> Vertices {
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 vertices: Vertices = {
49 x, y, 0.0, 1.0,
50 x, y + height, 0.0, 0.0,
51 x + width, y, 1.0, 1.0,
52 x + width, y + height, 1.0, 0.0,
53 }
54
55 return vertices
56}
57
58
59WAVELENGTH :: 120
60Pixel :: [4]u8
61
62noise_at :: proc(seed: i64, x, y: int) -> f32 {
63 return (noise.noise_2d(seed, {f64(x) / 120, f64(y) / 120}) + 1.0) / 2.0
64}
65
66create_texture_noise :: proc(texture_id: u32, adjust_noise: Adjust_Noise) {
67
68 texture_data := make([]u8, WIDTH * HEIGHT * 4)
69 defer delete(texture_data)
70
71 gl.BindTexture(gl.TEXTURE_2D, texture_id)
72 gl.ActiveTexture(gl.TEXTURE0)
73
74 gradient_location: glsl.vec2 = {f32(WIDTH / 2), f32(HEIGHT / 2)}
75
76 pixels := mem.slice_data_cast([]Pixel, texture_data)
77
78 for x := 0; x < WIDTH; x += 1 {
79
80 for y := 0; y < HEIGHT; y += 1 {
81
82 using adjust_noise := adjust_noise
83
84 noise_val: f32
85
86 {
87
88 for i := 0; i < int(octaves); i += 1 {
89 noise_val += 0.4 * ((noise.noise_2d(seed, {f64(x) / frequency / 2, f64(y) / frequency / 2}) + 1.0) / 2.0)
90 noise_val += 0.6 * ((noise.noise_2d(seed, {f64(x) / frequency * 2 ,f64(y) / frequency * 2}) + 1.0) / 2.0)
91 frequency *= glsl.exp(frequency)
92 }
93 noise_val /= f32(octaves)
94 }
95
96 val := glsl.distance_vec2({f32(x), f32(y)}, gradient_location)
97 val /= f32(HEIGHT / 2)
98
99 noise_val = noise_val - val
100
101 if noise_val < 0.0 {
102 noise_val = 0
103 }
104
105 val = glsl.clamp(val, 0.0, 1.0)
106 color := u8((noise_val) * 255.0)
107
108 switch {
109 case color < 20:
110
111 noise_val = 0.75 + 0.25 * noise_at(seed, x, y)
112 pixels[0] = {u8( 51 * noise_val), u8( 81 * noise_val), u8(251 * noise_val), 255}
113
114 case color < 30:
115
116 noise_val = 0.75 + 0.25 * noise_at(seed, x, y)
117 pixels[0] = {u8(251 * noise_val), u8(244 * noise_val), u8(189 * noise_val), 255}
118
119 case color < 60:
120
121 noise_val = 0.75 + 0.25 * noise_at(seed, x, y)
122 pixels[0] = {u8(124 * noise_val), u8(200 * noise_val), u8( 65 * noise_val), 255}
123
124 case color < 90:
125
126 noise_val = 0.75 + 0.25 * noise_at(seed, x, y)
127 pixels[0] = {u8(124 * noise_val), u8(150 * noise_val), u8( 65 * noise_val), 255}
128
129 case color < 120:
130
131 noise_val = 0.7 + 0.2 * noise_at(seed, x, y)
132 noise_val = glsl.pow(noise_val, 2)
133
134 pixels[0] = {u8(143 * noise_val), u8(143 * noise_val), u8(143 * noise_val), 255}
135
136 case:
137
138 noise_val = 0.7 + 0.2 * noise_at(seed, x, y)
139 noise_val = glsl.pow(noise_val, 2)
140
141 pixels[0] = {u8(205 * noise_val), u8(221 * noise_val), u8(246 * noise_val), 255}
142 }
143 pixels = pixels[1:]
144 }
145 }
146
147 gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, i32(WIDTH), i32(HEIGHT), 0, gl.RGBA, gl.UNSIGNED_BYTE, &texture_data[0])
148}
149
150main :: proc() {
151
152 if !bool(glfw.Init()) {
153 fmt.println("GLFW has failed to load.")
154 return
155 }
156
157 glfw.SetErrorCallback(proc "c" (error: c.int, description: cstring) {
158 context = runtime.default_context()
159 fmt.println(description)
160 })
161
162 glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, GL_MAJOR_VERSION)
163 glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, GL_MINOR_VERSION)
164 glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
165 glfw.WindowHint(glfw.OPENGL_FORWARD_COMPAT, 1)
166
167 window_handle := glfw.CreateWindow(WIDTH, HEIGHT, TITLE, nil, nil)
168
169 defer glfw.Terminate()
170 defer glfw.DestroyWindow(window_handle)
171
172 if window_handle == nil {
173 fmt.println("GLFW has failed to load the window.")
174 return
175 }
176
177
178 glfw.MakeContextCurrent(window_handle)
179
180 gl.load_up_to(GL_MAJOR_VERSION, GL_MINOR_VERSION, glfw.gl_set_proc_address)
181
182
183 glfw.SwapInterval(0)
184
185 vao: u32
186 vbo: u32
187 ebo: u32
188
189 gl.GenVertexArrays(1, &vao)
190 defer gl.DeleteVertexArrays(1, &vao)
191
192 gl.GenBuffers(1, &vbo)
193 gl.GenBuffers(1, &ebo)
194 defer gl.DeleteBuffers(1, &vbo)
195 defer gl.DeleteBuffers(1, &ebo)
196
197 gl.BindVertexArray(vao)
198 gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
199 gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo)
200
201 vertices := create_vertices(x = 0, y = 0, width = WIDTH, height = HEIGHT)
202
203
204
205
206
207
208
209
210
211
212
213
214 indices: [6]u32 = {
215 0, 1, 2,
216 2, 1, 3,
217 }
218
219 gl.EnableVertexAttribArray(0)
220 gl.VertexAttribPointer(0, 2, gl.FLOAT, false, 4 * size_of(f32), 0)
221
222 gl.EnableVertexAttribArray(1)
223 gl.VertexAttribPointer(1, 2, gl.FLOAT, false, 4 * size_of(f32), size_of(f32) * 2)
224
225 gl.BufferData(gl.ARRAY_BUFFER, len(vertices) * size_of(f32), raw_data(vertices[:]), gl.STATIC_DRAW)
226 gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(indices) * size_of(u32), raw_data(indices[:]), gl.STATIC_DRAW)
227
228 program_id: u32; ok: bool
229 if program_id, ok = gl.load_shaders("./shader.vert", "./shader.frag"); !ok {
230 fmt.println("Failed to load shaders.")
231 return
232 }
233 defer gl.DeleteProgram(program_id)
234
235 texture_id : u32
236 gl.GenTextures(1, &texture_id)
237 defer gl.DeleteTextures(1, &texture_id)
238
239 gl.BindTexture(gl.TEXTURE_2D, texture_id)
240 gl.ActiveTexture(gl.TEXTURE0)
241
242 gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT)
243 gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT)
244 gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
245 gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
246
247 ortho := glsl.mat4Ortho3d(0.0, f32(WIDTH), f32(HEIGHT), 0.0, 1.0, 100.0)
248
249 adjust_noise: Adjust_Noise
250 adjust_noise.frequency = WIDTH / 2
251 adjust_noise.octaves = 1
252 adjust_noise.seed = 360000
253
254 create_texture_noise(texture_id, adjust_noise)
255
256
257 for !glfw.WindowShouldClose(window_handle) {
258
259
260 glfw.PollEvents()
261
262 if glfw.GetKey(window_handle, glfw.KEY_COMMA) == glfw.PRESS && glfw.GetKey(window_handle, glfw.KEY_LEFT_SHIFT) == glfw.PRESS {
263 adjust_noise.frequency -= 5.0
264 adjust_noise.frequency = glsl.clamp(adjust_noise.frequency, 1, 9000)
265 create_texture_noise(texture_id, adjust_noise)
266 } else if glfw.GetKey(window_handle, glfw.KEY_COMMA) == glfw.PRESS {
267 adjust_noise.frequency += 5.0
268 create_texture_noise(texture_id, adjust_noise)
269 }
270
271 if glfw.GetKey(window_handle, glfw.KEY_PERIOD) == glfw.PRESS && glfw.GetKey(window_handle, glfw.KEY_LEFT_SHIFT) == glfw.PRESS {
272 adjust_noise.octaves -= 1.0
273 adjust_noise.octaves = glsl.clamp(adjust_noise.octaves, 1, 100)
274 create_texture_noise(texture_id, adjust_noise)
275 } else if glfw.GetKey(window_handle, glfw.KEY_PERIOD) == glfw.PRESS {
276 adjust_noise.octaves += 1.0
277 create_texture_noise(texture_id, adjust_noise)
278 }
279
280 gl.ClearColor(0.5, 0.0, 1.0, 1.0)
281 gl.Clear(gl.COLOR_BUFFER_BIT)
282
283 gl.UseProgram(program_id)
284 gl.BindVertexArray(vao)
285 gl.BindTexture(gl.TEXTURE_2D, texture_id)
286 gl.ActiveTexture(gl.TEXTURE0)
287 gl.Uniform1i(gl.GetUniformLocation(program_id, "u_texture"), 0)
288 gl.UniformMatrix4fv(gl.GetUniformLocation(program_id, "u_projection"), 1, gl.FALSE, &ortho[0][0])
289
290 gl.DrawElements(gl.TRIANGLES, i32(len(indices)), gl.UNSIGNED_INT, nil)
291
292 glfw.SwapBuffers(window_handle)
293
294 }
295}