Spaces:
Building
Building
File size: 6,283 Bytes
d49f7bc |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# Copyright (c) Meta Platforms, Inc. and affiliates.
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
import numpy as np
import OpenGL.GL as GL
import ctypes
from animated_drawings.model.transform import Transform
class Box(Transform):
def __init__(self, shader_name: str = 'color_shader') -> None:
super().__init__()
self.points = np.array([
[ 0.5, 0.5, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0],
[ 0.5, -0.5, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0],
[-0.5, -0.5, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0],
[-0.5, -0.5, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0],
[-0.5, 0.5, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0],
[ 0.5, 0.5, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0],
[-0.5, -0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
[ 0.5, -0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
[ 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
[ 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
[-0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
[-0.5, -0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
[ 0.5, -0.5, -0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0],
[ 0.5, 0.5, -0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0],
[ 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0],
[ 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0],
[ 0.5, -0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0],
[ 0.5, -0.5, -0.5, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0],
[-0.5, 0.5, 0.5, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0],
[-0.5, 0.5, -0.5, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0],
[-0.5, -0.5, -0.5, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0],
[-0.5, -0.5, -0.5, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0],
[-0.5, -0.5, 0.5, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0],
[-0.5, 0.5, 0.5, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0],
[-0.5, -0.5, -0.5, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0],
[ 0.5, -0.5, -0.5, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0],
[ 0.5, -0.5, 0.5, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0],
[ 0.5, -0.5, 0.5, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0],
[-0.5, -0.5, 0.5, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0],
[-0.5, -0.5, -0.5, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0],
[ 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0],
[ 0.5, 0.5, -0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0],
[-0.5, 0.5, -0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0],
[-0.5, 0.5, -0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0],
[-0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0],
[ 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0],
], np.float32)
self.indices = np.array([2, 1, 0,
5, 4, 3,
6, 7, 8,
9, 10, 11,
14, 13, 12,
17, 16, 15,
18, 19, 20,
21, 22, 23,
24, 25, 26,
27, 28, 29,
32, 31, 30,
35, 34, 33
], np.uint32)
self.material = {
'ambient': np.array([0.4, 0.4, 0.4], np.float32),
'diffuse': np.array([0.4, 0.4, 0.4], np.float32),
'specular': np.array([0.3, 0.0, 0.0], np.float32),
'shininess': 32
}
self.shader_name: str = shader_name
self._is_opengl_initialized: bool = False # keep track of whether self._initialize_opengl_resources was called.
def _initialize_opengl_resources(self) -> None:
""" Method to initialize the OpenGL arrays and buffers necessary to draw the object.
It's better to not initialize these things unless we're definitely going to be drawing the object,
as calling GL functions without calling glfw.init() first can cause a mysterious segfault.
This way, unit tests and other non-rendering operations can proceed without requiring a Controller.
"""
self.vao = GL.glGenVertexArrays(1)
self.vbo = GL.glGenBuffers(1)
self.ebo = GL.glGenBuffers(1)
GL.glBindVertexArray(self.vao)
# buffer vertex data
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vbo)
GL.glBufferData(GL.GL_ARRAY_BUFFER, self.points, GL.GL_STATIC_DRAW)
# buffer element index data
GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, self.ebo)
GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, self.indices, GL.GL_STATIC_DRAW)
vert_bytes = 4 * self.points.shape[1] # 4 is byte size of np.float32
pos_offset = 4 * 0
color_offset = 4 * 3
normals_offset = 4 * 6
# position attributes
GL.glVertexAttribPointer(0, 3, GL.GL_FLOAT, False, vert_bytes, ctypes.c_void_p(pos_offset))
GL.glEnableVertexAttribArray(0)
# color attributes
GL.glVertexAttribPointer(1, 3, GL.GL_FLOAT, False, vert_bytes, ctypes.c_void_p(color_offset))
GL.glEnableVertexAttribArray(1)
# normals attributes
GL.glVertexAttribPointer(2, 3, GL.GL_FLOAT, False, vert_bytes, ctypes.c_void_p(normals_offset))
GL.glEnableVertexAttribArray(2)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)
GL.glBindVertexArray(0)
self._is_opengl_initialized = True
def rebuffer_vertex_data(self) -> None:
GL.glBindVertexArray(self.vao)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vbo)
GL.glBufferData(GL.GL_ARRAY_BUFFER, self.points, GL.GL_STATIC_DRAW)
def _draw(self, **kwargs) -> None:
if not self._is_opengl_initialized:
self._initialize_opengl_resources()
GL.glUseProgram(kwargs['shader_ids'][self.shader_name])
model_loc = GL.glGetUniformLocation(kwargs['shader_ids'][self.shader_name], "model")
GL.glUniformMatrix4fv(model_loc, 1, GL.GL_FALSE, self._world_transform.T)
GL.glBindVertexArray(self.vao)
GL.glDrawArrays(GL.GL_TRIANGLES, 0, 36)
|