Skip to content

Instantly share code, notes, and snippets.

@furby-tm
Last active November 21, 2019 00:35
Show Gist options
  • Save furby-tm/b344d580b1ec896c946e43845b888e51 to your computer and use it in GitHub Desktop.
Save furby-tm/b344d580b1ec896c946e43845b888e51 to your computer and use it in GitHub Desktop.
import bgl
import numpy as np
import barnold.props as props
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.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
# 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(scene)
def _init_opengl(self, engine, scene):
engine.bind_display_space_shader(scene)
shader_program = bgl.Buffer(bgl.GL_INT, 1)
bgl.glGetIntegerv(bgl.GL_CURRENT_PROGRAM, 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])
texturecoord_location = bgl.glGetAttribLocation(shader_program[0], "texCoord")
position_location = bgl.glGetAttribLocation(shader_program[0], "pos")
bgl.glEnableVertexAttribArray(texturecoord_location)
bgl.glEnableVertexAttribArray(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(
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(
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 * 3) % 4 ) % 4
bufferSize = (self._width * 3 + padding) * self._height
bgl.glBindTexture(target, self.texture_id)
bgl.glBindBuffer(bgl.GL_PIXEL_UNPACK_BUFFER, self.render_buffer[self.index])
bgl.glPixelStorei(bgl.GL_UNPACK_ALIGNMENT, 4)
# 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,
0,
)
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)
bgl.glBindBuffer(bgl.GL_PIXEL_PACK_BUFFER, 0)
err = bgl.glGetError()
if err != bgl.GL_NO_ERROR:
print("!!!!!!!!!!!!!!!GL Error:", err)
bgl.glFlush()
def _init_texture(self, scene):
bgl.glActiveTexture(bgl.GL_TEXTURE0)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.texture_id)
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.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