Skip to content

Instantly share code, notes, and snippets.

@furby-tm
Created November 21, 2019 10:58
Show Gist options
  • Save furby-tm/90b2815cc76a5139b645c22d73ddb384 to your computer and use it in GitHub Desktop.
Save furby-tm/90b2815cc76a5139b645c22d73ddb384 to your computer and use it in GitHub Desktop.
import bgl
import numpy as np
import barnold.props as props
import ctypes
class GPU:
def __init__(self, engine, scene, width, height, offset_x, offset_y, rect):
self._width = width
self._height = height
self.buffer = bgl.Buffer(bgl.GL_SHORT, rect.shape, rect)
self.data_size = self._width * self._height * 4
self.cscene = scene.arnold
self._offset_x = offset_x
self._offset_y = offset_y
# pixels = bgl.Buffer(bgl.GL_SHORT, rect.shape, rect)
# Generate texture
self.texture = bgl.Buffer(bgl.GL_SHORT, 1)
bgl.glGenTextures(1, self.texture)
self.texture_id = self.texture[0]
if self.cscene.transparency == True:
self.user_set_format = bgl.GL_RGBA16F
else:
self.user_set_format = bgl.GL_RGB16F
self.bucket_array = engine.AI.bucket_array
self.bucket_index = engine.AI.bucket_counter
self.data_pointer = 16
# self.render_buffer = bgl.Buffer(bgl.GL_INT, 2)
# bgl.glGenBuffers(2, self.render_buffer)
# bgl.glBindBuffer(bgl.GL_PIXEL_UNPACK_BUFFER, self.render_buffer[0])
# bgl.glBufferData(bgl.GL_PIXEL_UNPACK_BUFFER, self.data_size, 0, bgl.GL_STREAM_DRAW)
# bgl.glBindBuffer(bgl.GL_PIXEL_UNPACK_BUFFER, self.render_buffer[1])
# bgl.glBufferData(bgl.GL_PIXEL_UNPACK_BUFFER, self.data_size, 0, bgl.GL_STREAM_DRAW)
# bgl.glBindBuffer(bgl.GL_PIXEL_UNPACK_BUFFER, 0)
self.index = 0
self.nextIndex = 1
self.vpointer = bgl.Buffer(bgl.GL_FLOAT, 16)
# bgl.glActiveTexture(bgl.GL_TEXTURE0)
# bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.texture[0])
# bgl.glTexImage2D(
# bgl.GL_TEXTURE_2D,
# 0,
# bgl.GL_RGBA16F,
# width,
# height,
# 0,
# bgl.GL_RGBA,
# bgl.GL_UNSIGNED_SHORT,
# pixels,
# )
# bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR)
# bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR)
# bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)
# Bind shader that converts from scene linear to display space,
# use the scene's color management settings.
self._init_opengl(engine, scene)
self._init_texture()
def _init_opengl(self, engine, scene):
engine.bind_display_space_shader(scene)
self.shader_program = bgl.Buffer(bgl.GL_INT, 1)
bgl.glGetIntegerv(bgl.GL_CURRENT_PROGRAM, self.shader_program)
# Generate vertex array
self.vertex_array = bgl.Buffer(bgl.GL_INT, 1)
bgl.glGenVertexArrays(1, self.vertex_array)
bgl.glBindVertexArray(self.vertex_array[0])
self.texturecoord_location = bgl.glGetAttribLocation(self.shader_program[0], "texCoord")
self.position_location = bgl.glGetAttribLocation(self.shader_program[0], "pos")
bgl.glEnableVertexAttribArray(self.texturecoord_location)
bgl.glEnableVertexAttribArray(self.position_location)
x1, x2 = self._offset_x[0], self._offset_x[1]
y1, y2 = self._offset_y[0], self._offset_y[1]
position = [
x1,
y2, # top left
x2,
y2, # top right
x2,
y1, # bottom right
x1,
y1, # bottom left
]
texcoord = [0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0] # reversed
position = bgl.Buffer(bgl.GL_FLOAT, len(position), position)
texcoord = bgl.Buffer(bgl.GL_FLOAT, len(texcoord), texcoord)
self.vertex_buffer = bgl.Buffer(bgl.GL_INT, 2)
bgl.glGenBuffers(2, self.vertex_buffer)
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vertex_buffer[0])
bgl.glBufferData(bgl.GL_ARRAY_BUFFER, 32, position, bgl.GL_STATIC_DRAW)
bgl.glVertexAttribPointer(
self.position_location, 2, bgl.GL_FLOAT, bgl.GL_FALSE, 0, None
)
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vertex_buffer[1])
bgl.glBufferData(bgl.GL_ARRAY_BUFFER, 32, texcoord, bgl.GL_STATIC_DRAW)
bgl.glVertexAttribPointer(
self.texturecoord_location, 2, bgl.GL_FLOAT, bgl.GL_FALSE, 0, None
)
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, 0)
bgl.glBindVertexArray(0)
engine.unbind_display_space_shader()
def __del__(self):
bgl.glDeleteBuffers(2, self.vertex_buffer)
bgl.glDeleteVertexArrays(1, self.vertex_array)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)
bgl.glDeleteTextures(1, self.texture)
# bgl.glDeleteBuffers(2, self.render_buffer)
def update(self):
self.blit_buffer()
def blit_buffer(self):
"""Blit a buffer into a texture.
"""
size = (self._width, self._height)
target = bgl.GL_TEXTURE_2D
# padding = ( 4 - (self._width * 4) % 4 ) % 4
# bufferSize = (self._width * 3 + padding) * self._height
bgl.glBindTexture(target, self.texture_id)
# if not self.vertex_buffer[self.index]:
# if not self.vertex_buffer:
# bgl.glGenBuffers(1, self.vertex_buffer)
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vertex_buffer[0])
#invalidate old contents - avoids stalling if buffer is still waiting in queue to be rendered
bgl.glBufferData(bgl.GL_ARRAY_BUFFER, 64, 0, bgl.GL_STREAM_DRAW)
# bgl.glMapBuffer(bgl.GL_ARRAY_BUFFER, bgl.GL_WRITE_ONLY)
# bgl.glMapBuffer(bgl.GL_ARRAY_BUFFER, bgl.GL_WRITE_ONLY)
# vpointer_p_float = ctypes.cast(vpointer_p, ctypes.POINTER(ctypes.c_float))
# vpointer = np.array(np.zeros(shape=((16, 1))))
x = self.bucket_array[self.bucket_index][0][0]
y = self.bucket_array[self.bucket_index][0][1]
bucket_width = self.bucket_array[self.bucket_index][0][2]
bucket_height = self.bucket_array[self.bucket_index][0][3]
self.vpointer[0] = 0.0
self.vpointer[1] = 0.0
self.vpointer[2] = x
self.vpointer[3] = y
self.vpointer[4] = 1.0
self.vpointer[5] = 0.0
self.vpointer[6] = self._width + x
self.vpointer[7] = y
self.vpointer[8] = 1.0
self.vpointer[9] = 1.0
self.vpointer[10] = self._width + x
self.vpointer[11] = self._height + y
self.vpointer[12] = 0.0
self.vpointer[13] = 1.0
self.vpointer[14] = x
self.vpointer[15] = self._height + y
bgl.glGetBufferSubData(bgl.GL_ARRAY_BUFFER, 0, 64, self.vpointer)
# buff = bgl.Buffer(bgl.GL_FLOAT, len(self.vpointer), self.vpointer)
bgl.glBufferData(bgl.GL_ARRAY_BUFFER, 64, self.vpointer, bgl.GL_STREAM_DRAW)
# bgl.glUnmapBuffer(bgl.GL_ARRAY_BUFFER)
# bgl.glBindVertexArray(self.vertex_array[0])
# texcoord_attribute = bgl.glGetAttribLocation(self.shader_program[0], "texCoord")
# position_attribute = bgl.glGetAttribLocation(self.shader_program[0], "pos")
# bgl.glEnableVertexAttribArray(self.texturecoord_location)
# bgl.glEnableVertexAttribArray(self.position_location)
# bgl.glVertexAttribPointer(
# texcoord_attribute, 2, bgl.GL_FLOAT, bgl.GL_FALSE, 16, 0
# )
# bgl.glVertexAttribPointer(
# position_attribute, 2, bgl.GL_FLOAT, bgl.GL_FALSE, 16, 8
# )
# if self.vertex_buffer[self.index]:
# bgl.glUnmapBuffer(bgl.GL_ARRAY_BUFFER)
# transfer the new part of texture
# bgl.glTexSubImage2D(
# target,
# 0,
# self._offset_x[0],
# self._offset_y[0],
# size[0],
# size[1],
# bgl.GL_RGBA,
# bgl.GL_UNSIGNED_SHORT,
# buff,
# )
self.index += 1
# bgl.glBindBuffer(bgl.GL_PIXEL_UNPACK_BUFFER, self.render_buffer[self.nextIndex])
self.nextIndex += 1
self.index = self.index % 2
self.nextIndex = self.index % 2
# bgl.glBufferData(bgl.GL_PIXEL_UNPACK_BUFFER, self.data_size, 0, bgl.GL_STREAM_DRAW)
# ptr = bgl.glMapBuffer(bgl.GL_PIXEL_UNPACK_BUFFER, bgl.GL_WRITE_ONLY)
# if ptr:
# bgl.glUnmapBuffer(bgl.GL_PIXEL_PACK_BUFFER)
err = bgl.glGetError()
if err != bgl.GL_NO_ERROR:
print("!!!!!!!!!!!!!!!GL Error:", err)
bgl.glFlush()
def _init_texture(self):
bgl.glActiveTexture(bgl.GL_TEXTURE0)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.texture_id)
self.data_pointer += 4 * 0 * self.bucket_array[self.bucket_index][0][2]
print(self.data_pointer)
bgl.glTexImage2D(
bgl.GL_TEXTURE_2D,
0,
self.user_set_format,
self._width,
self._height,
0,
bgl.GL_RGBA,
bgl.GL_UNSIGNED_SHORT,
0,
)
# bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE)
# bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE)
bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_NEAREST)
bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_NEAREST)
# bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)
def draw(self, engine, scene):
# if self._transparent:
bgl.glEnable(bgl.GL_BLEND)
bgl.glBlendFunc(bgl.GL_ONE, bgl.GL_ONE_MINUS_SRC_ALPHA)
engine.bind_display_space_shader(scene)
bgl.glActiveTexture(bgl.GL_TEXTURE0)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.texture_id)
bgl.glBindVertexArray(self.vertex_array[0])
bgl.glDrawArrays(bgl.GL_TRIANGLE_FAN, 0, 4)
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, 0)
bgl.glBindVertexArray(0)
# bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)
engine.unbind_display_space_shader()
err = bgl.glGetError()
if err != bgl.GL_NO_ERROR:
print("GL Error:", err)
# if self._transparent:
bgl.glDisable(bgl.GL_BLEND)
# bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vertex_buffer[0])
# bgl.glVertexAttribPointer(
# self.position_location, 2, bgl.GL_FLOAT, bgl.GL_FALSE, 0, None
# )
# bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vertex_buffer[1])
# bgl.glVertexAttribPointer(
# self.texturecoord_location, 2, bgl.GL_FLOAT, bgl.GL_FALSE, 0, None
# )
# bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, 0)
# bgl.glDrawArrays(bgl.GL_TRIANGLE_FAN, 0, 4)
# bgl.glBindVertexArray(0)
# bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)
@staticmethod
def restore_opengl_defaults():
bgl.glLineWidth(1)
bgl.glDisable(bgl.GL_BLEND)
@staticmethod
def _draw_texture(texture_id, x, y, width, height):
# INITIALIZATION
# Getting shader program
shader_program = bgl.Buffer(bgl.GL_INT, 1)
bgl.glGetIntegerv(bgl.GL_CURRENT_PROGRAM, shader_program)
# Generate vertex array
vertex_array = bgl.Buffer(bgl.GL_INT, 1)
bgl.glGenVertexArrays(1, vertex_array)
texturecoord_location = bgl.glGetAttribLocation(shader_program[0], "texCoord")
position_location = bgl.glGetAttribLocation(shader_program[0], "pos")
# Generate geometry buffers for drawing textured quad
position = [x, y, x + width, y, x + width, y + height, x, y + height]
position = bgl.Buffer(bgl.GL_FLOAT, len(position), position)
texcoord = [0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0]
texcoord = bgl.Buffer(bgl.GL_FLOAT, len(texcoord), texcoord)
vertex_buffer = bgl.Buffer(bgl.GL_INT, 2)
bgl.glGenBuffers(2, vertex_buffer)
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, vertex_buffer[0])
bgl.glBufferData(bgl.GL_ARRAY_BUFFER, 32, position, bgl.GL_STATIC_DRAW)
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, vertex_buffer[1])
bgl.glBufferData(bgl.GL_ARRAY_BUFFER, 32, texcoord, bgl.GL_STATIC_DRAW)
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, 0)
# DRAWING
bgl.glActiveTexture(bgl.GL_TEXTURE0)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, texture_id)
bgl.glBindVertexArray(vertex_array[0])
bgl.glEnableVertexAttribArray(texturecoord_location)
bgl.glEnableVertexAttribArray(position_location)
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, vertex_buffer[0])
bgl.glVertexAttribPointer(
position_location, 2, bgl.GL_FLOAT, bgl.GL_FALSE, 0, None
)
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, vertex_buffer[1])
bgl.glVertexAttribPointer(
texturecoord_location, 2, bgl.GL_FLOAT, bgl.GL_FALSE, 0, None
)
bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, 0)
bgl.glDrawArrays(bgl.GL_TRIANGLE_FAN, 0, 4)
bgl.glBindVertexArray(0)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment