Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
104 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
""" | ||
Renders 100 x 100 cubes using instancing. | ||
We are using the moderngl-window specific VAO wrapper. | ||
Each cube is animated in the vertex shader offset by gl_InstanceID | ||
""" | ||
from pathlib import Path | ||
|
||
import numpy | ||
from pyrr import Matrix44 | ||
import moderngl | ||
import moderngl_window | ||
from moderngl_window import geometry | ||
from base import CameraWindow | ||
|
||
|
||
class CubeSimpleInstanced(CameraWindow): | ||
"""Renders cubes using instancing""" | ||
title = "Plain Cube" | ||
resource_dir = (Path(__file__).parent / 'resources').resolve() | ||
aspect_ratio = None | ||
|
||
def __init__(self, **kwargs): | ||
super().__init__(**kwargs) | ||
self.wnd.mouse_exclusivity = True | ||
self.camera.projection.update(near=1, far=1000) | ||
self.cube = geometry.cube(size=(2, 2, 2)) | ||
self.prog = self.load_program('programs/cube_simple_instanced.glsl') | ||
self.prog['m_proj'].write(self.camera.projection.matrix) | ||
self.prog['m_model'].write(Matrix44.identity(dtype='f4')) | ||
|
||
# Generate per instance data represeting a grid of cubes | ||
N = 100 | ||
self.instances = N * N | ||
|
||
def gen_data(x_res, z_res, spacing=2.5): | ||
"""Generates a grid of N * N poistions and random colors on the xz plane""" | ||
for y in range(z_res): | ||
for x in range(x_res): | ||
yield -N * spacing / 2 + spacing * x | ||
yield 0 | ||
yield -N * spacing / 2 + spacing * y | ||
yield numpy.random.uniform(0, 1) | ||
yield numpy.random.uniform(0, 1) | ||
yield numpy.random.uniform(0, 1) | ||
|
||
self.instance_data = self.ctx.buffer(numpy.fromiter(gen_data(N, N), 'f4', count=self.instances * 6)) | ||
self.cube.buffer(self.instance_data, '3f 3f/i', ['in_offset', 'in_color']) | ||
|
||
def render(self, time: float, frametime: float): | ||
self.ctx.enable_only(moderngl.CULL_FACE | moderngl.DEPTH_TEST) | ||
|
||
self.prog['m_camera'].write(self.camera.matrix) | ||
self.prog['time'].value = time | ||
|
||
self.cube.render(self.prog, instances=self.instances) | ||
|
||
|
||
if __name__ == '__main__': | ||
moderngl_window.run_window_config(CubeSimpleInstanced) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#version 330 | ||
|
||
#if defined VERTEX_SHADER | ||
|
||
// Model geometry | ||
in vec3 in_position; | ||
in vec3 in_normal; | ||
|
||
// Per instance data | ||
in vec3 in_offset; | ||
in vec3 in_color; | ||
|
||
uniform mat4 m_model; | ||
uniform mat4 m_camera; | ||
uniform mat4 m_proj; | ||
uniform float time; | ||
|
||
out vec3 pos; | ||
out vec3 normal; | ||
out vec3 color; | ||
|
||
void main() { | ||
mat4 m_view = m_camera * m_model; | ||
vec4 p = m_view * vec4(in_position + in_offset + vec3(0.0, sin(gl_InstanceID + time) * 2.0, 0.0), 1.0); | ||
gl_Position = m_proj * p; | ||
mat3 m_normal = inverse(transpose(mat3(m_view))); | ||
normal = m_normal * normalize(in_normal); | ||
pos = p.xyz; | ||
color = in_color; | ||
} | ||
|
||
#elif defined FRAGMENT_SHADER | ||
|
||
out vec4 fragColor; | ||
|
||
in vec3 pos; | ||
in vec3 normal; | ||
in vec3 color; | ||
|
||
void main() { | ||
float l = dot(normalize(-pos), normalize(normal)); | ||
fragColor = vec4(color * (0.25 + abs(l) * 0.75), 1.0); | ||
} | ||
#endif |