84 lines
2.9 KiB
Python
84 lines
2.9 KiB
Python
import numpy as np
|
|
from OpenGL.GL import *
|
|
import ctypes
|
|
import time
|
|
|
|
class WaterMesh:
|
|
def __init__(self, size=10.0, resolution=100):
|
|
self.size = size
|
|
self.resolution = resolution
|
|
self.vertices = self.generate_vertices()
|
|
self.vertex_count = len(self.vertices) // 8
|
|
|
|
self.vao = glGenVertexArrays(1)
|
|
self.vbo = glGenBuffers(1)
|
|
|
|
glBindVertexArray(self.vao)
|
|
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
|
|
glBufferData(GL_ARRAY_BUFFER, self.vertices.nbytes, self.vertices, GL_DYNAMIC_DRAW)
|
|
|
|
stride = 8 * 4
|
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, ctypes.c_void_p(0)) # pos
|
|
glEnableVertexAttribArray(0)
|
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, stride, ctypes.c_void_p(12)) # color
|
|
glEnableVertexAttribArray(1)
|
|
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, stride, ctypes.c_void_p(24)) # uv
|
|
glEnableVertexAttribArray(2)
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
|
glBindVertexArray(0)
|
|
|
|
self.start_time = time.time()
|
|
|
|
def generate_vertices(self):
|
|
step = self.size / self.resolution
|
|
verts = []
|
|
|
|
for z in range(self.resolution):
|
|
for x in range(self.resolution):
|
|
# cztery rogi jednego kwadratu
|
|
x0 = x * step - self.size / 2
|
|
x1 = (x + 1) * step - self.size / 2
|
|
z0 = z * step - self.size / 2
|
|
z1 = (z + 1) * step - self.size / 2
|
|
|
|
uv0 = (x / self.resolution, z / self.resolution)
|
|
uv1 = ((x + 1) / self.resolution, z / self.resolution)
|
|
uv2 = ((x + 1) / self.resolution, (z + 1) / self.resolution)
|
|
uv3 = (x / self.resolution, (z + 1) / self.resolution)
|
|
|
|
color = (0.2, 0.4, 1.0)
|
|
|
|
# dwa trójkąty
|
|
verts += [x0, 0, z0, *color, *uv0]
|
|
verts += [x1, 0, z0, *color, *uv1]
|
|
verts += [x1, 0, z1, *color, *uv2]
|
|
|
|
verts += [x0, 0, z0, *color, *uv0]
|
|
verts += [x1, 0, z1, *color, *uv2]
|
|
verts += [x0, 0, z1, *color, *uv3]
|
|
|
|
return np.array(verts, dtype=np.float32)
|
|
|
|
def update(self):
|
|
time_now = time.time() - self.start_time
|
|
verts = self.vertices
|
|
|
|
for i in range(0, len(verts), 8):
|
|
x = verts[i]
|
|
z = verts[i + 2]
|
|
verts[i + 1] = np.sin(x * 0.5 + time_now) * 0.2 + np.cos(z * 0.5 + time_now) * 0.2
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
|
|
glBufferSubData(GL_ARRAY_BUFFER, 0, verts.nbytes, verts)
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0)
|
|
|
|
def draw(self, shader):
|
|
shader.use()
|
|
glBindVertexArray(self.vao)
|
|
glDrawArrays(GL_TRIANGLES, 0, self.vertex_count)
|
|
glBindVertexArray(0)
|
|
|
|
def destroy(self):
|
|
glDeleteVertexArrays(1, [self.vao])
|
|
glDeleteBuffers(1, [self.vbo]) |