приведение памяти, полученное из функции from_address, это возможно, или обходной путь? - PullRequest
0 голосов
/ 03 июля 2019

Пример рендеринга со слоями, портированный из c ++ Superbible OpenGL, 7-е издание, рисунок 9.7, с.441. Есть интересное место, где актерский состав будет идеальным, если это возможно. В противном случае я не знаю обходной путь, возможно, поместите bufferp в класс и что-нибудь еще? Любая помощь приветствуется. Спасибо.

Обновление: не обязательно помещать bufferp в класс. Код ниже работает сейчас и дает ожидаемые результаты.

Ожидаемый результат:

expected output

файлы поддержки: gslayered_support.zip

исходный код:

#!/usr/bin/python3

import sys
import time
import ctypes

fullscreen = True
sys.path.append("./shared")

from sbmloader import SBMObject    # location of sbm file format loader
from ktxloader import KTXObject    # location of ktx file format loader
from textoverlay import OVERLAY_
from shader import shader_load, link_from_shaders

from sbmath import m3dDegToRad, m3dRadToDeg, m3dTranslateMatrix44, m3dRotationMatrix44, m3dMultiply, m3dOrtho, m3dPerspective, rotation_matrix, translate, m3dScaleMatrix44, \
    scale, m3dLookAt, normalize

try:
    from OpenGL.GLUT import *
    from OpenGL.GL import *
    from OpenGL.GLU import *
    from OpenGL.raw.GL.ARB.vertex_array_object import glGenVertexArrays, glBindVertexArray
except:
    print ('''
    ERROR: PyOpenGL not installed properly.
        ''')
    sys.exit()

import numpy as np
from math import cos, sin
import glm
identityMatrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]

myobject = SBMObject()
ktxobject = KTXObject()
overlay = OVERLAY_()

program_gslayers = GLuint(0)
program_showlayers = GLuint(0)
vao = GLuint(0)
mode=0
transform_ubo = GLuint(0)

layered_fbo = GLuint(0)
array_texture = GLuint(0)
array_depth = GLuint(0)


def load_shaders():
    global program_showlayers
    global program_gslayers

    vs = GLuint(0)
    gs = GLuint(0)
    fs = GLuint(0)

    if (program_showlayers):
        glDeleteProgram(program_showlayers)

    program_showlayers = glCreateProgram()

    vs = shader_load("showlayers.vs.glsl", GL_VERTEX_SHADER)
    fs = shader_load("showlayers.fs.glsl", GL_FRAGMENT_SHADER)

    glAttachShader(program_showlayers, vs)
    glAttachShader(program_showlayers, fs)

    glLinkProgram(program_showlayers)

    glDeleteShader(vs)
    glDeleteShader(fs)

    vs = shader_load("gslayers.vs.glsl", GL_VERTEX_SHADER)
    gs = shader_load("gslayers.gs.glsl", GL_GEOMETRY_SHADER)
    fs = shader_load("gslayers.fs.glsl", GL_FRAGMENT_SHADER)

    if (program_gslayers):
        glDeleteProgram(program_gslayers)

    program_gslayers = glCreateProgram()

    glAttachShader(program_gslayers, vs)
    glAttachShader(program_gslayers, gs)
    glAttachShader(program_gslayers, fs)

    glLinkProgram(program_gslayers)

    glDeleteShader(vs)
    glDeleteShader(gs)
    glDeleteShader(fs)



class Scene:

    def __init__(self, width, height):
        global myobject
        global transform_ubo
        global array_texture
        global array_depth
        global layered_fbo

        glGenVertexArrays(1, vao)
        glBindVertexArray(vao)

        load_shaders()

        myobject.load("torus.sbm")

        glGenBuffers(1, transform_ubo)
        glBindBuffer(GL_UNIFORM_BUFFER, transform_ubo)
        glBufferData(GL_UNIFORM_BUFFER, 17 * glm.sizeof(glm.mat4), None, GL_DYNAMIC_DRAW)

        array_texture = glGenTextures(1)
        glBindTexture(GL_TEXTURE_2D_ARRAY, array_texture)
        glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 256, 256, 16)

        array_depth = glGenTextures(1)
        glBindTexture(GL_TEXTURE_2D_ARRAY, array_depth)
        glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH_COMPONENT32, 256, 256, 16)

        glGenFramebuffers(1, layered_fbo)
        glBindFramebuffer(GL_FRAMEBUFFER, layered_fbo)
        glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, array_texture, 0)
        glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, array_depth, 0)




    def display(self):

        currentTime = time.time()

        black = [ 0.0, 0.0, 0.0, 1.0 ]
        gray =  [ 0.1, 0.1, 0.1, 1.0 ]
        one = 1.0


        T = (GLfloat * 16)(*identityMatrix)
        m3dTranslateMatrix44(T, 0.0, 0.0, -4.0)

        RY = (GLfloat * 16)(*identityMatrix)
        m3dRotationMatrix44(RY, currentTime * m3dDegToRad(5.0), 0.0, 1.0, 0.0)

        RX = (GLfloat * 16)(*identityMatrix)
        m3dRotationMatrix44(RX, currentTime * m3dDegToRad(30.0), 1.0, 0.0, 0.0)

        mv_matrix = (GLfloat * 16)(*identityMatrix)
        mv_matrix = m3dMultiply(T, m3dMultiply(RY, RX))


        proj_matrix = (GLfloat * 16)(*identityMatrix)
        proj_matrix = m3dPerspective(m3dDegToRad(50.0), float(self.width) / float(self.height), 0.1, 1000.0)

        mvp = (GLfloat * 16)(*identityMatrix)
        mvp = m3dMultiply(proj_matrix , mv_matrix)

        # not used
        class TRANSFORM_BUFFER_:
            proj_matrix = glm.mat4
            mv_matrix = [glm.mat4 for _ in range(16)]
        transform_buf = TRANSFORM_BUFFER_()

        glBindBufferBase(GL_UNIFORM_BUFFER, 0, transform_ubo)

        # TRANSFORM_BUFFER * 
        buffer = glMapBufferRange(GL_UNIFORM_BUFFER, 0, glm.sizeof(glm.mat4) * 17, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT)

        bufferp = (GLfloat * 16 * 17).from_address(buffer) 

        bufferp[0] = proj_matrix


        for i in range (1, 17):

            fi = float((i + 12) / 16.0)

            T = (GLfloat * 16)(*identityMatrix)
            m3dTranslateMatrix44(T, 0.0, 0.0, -4.0)

            RY = (GLfloat * 16)(*identityMatrix)
            m3dRotationMatrix44(RY, currentTime * m3dDegToRad(25.0) * fi, 0.0, 1.0, 0.0)

            RX = (GLfloat * 16)(*identityMatrix)
            m3dRotationMatrix44(RX, currentTime * m3dDegToRad(30.0) * fi, 1.0, 0.0, 0.0)

            mv_matrix = (GLfloat * 16)(*identityMatrix)
            mv_matrix = m3dMultiply(T, m3dMultiply(RY, RX))

            bufferp[i] = mv_matrix


        glUnmapBuffer(GL_UNIFORM_BUFFER)

        ca0 = GL_COLOR_ATTACHMENT0

        glBindFramebuffer(GL_FRAMEBUFFER, layered_fbo)
        glDrawBuffers(1, ca0)
        glViewport(0, 0, 256, 256)
        glClearBufferfv(GL_COLOR, 0, black)
        glClearBufferfv(GL_DEPTH, 0, one)
        glEnable(GL_DEPTH_TEST)
        glDepthFunc(GL_LEQUAL)

        glUseProgram(program_gslayers)

        myobject.render()

        glBindFramebuffer(GL_FRAMEBUFFER, 0)
        glDrawBuffer(GL_BACK)
        glUseProgram(program_showlayers)

        glViewport(0, 0, self.width, self.height)
        glClearBufferfv(GL_COLOR, 0, gray)

        glBindTexture(GL_TEXTURE_2D_ARRAY, array_texture)
        glDisable(GL_DEPTH_TEST)

        glBindVertexArray(vao)
        glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, 16)

        glBindTexture(GL_TEXTURE_2D_ARRAY, 0)


        glutSwapBuffers()

    def reshape(self, width, height):
        self.width = width
        self.height = height

    def keyboard(self, key, x, y ):
        global fullscreen

        print ('key:' , key)
        if key == b'\x1b': # ESC
            sys.exit()

        elif key == b'f' or key == b'F': #fullscreen toggle
            if (fullscreen == True):
                glutReshapeWindow(512, 512)
                glutPositionWindow(int((1360/2)-(512/2)), int((768/2)-(512/2)))
                fullscreen = False
            else:
                glutFullScreen()
                fullscreen = True

    def init(self):
        pass

    def timer(self, blah):
        glutPostRedisplay()
        glutTimerFunc( int(1/60), self.timer, 0)
        time.sleep(1/60.0)

if __name__ == '__main__':
    glutInit()
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
    glutInitWindowSize(512, 512)
    w1 = glutCreateWindow('OpenGL SuperBible - Layered Rendering')
    glutInitWindowPosition(int((1360/2)-(512/2)), int((768/2)-(512/2)))
    fullscreen = False
    #glutFullScreen()
    scene = Scene(512,512)
    glutReshapeFunc(scene.reshape)
    glutDisplayFunc(scene.display)
    glutKeyboardFunc(scene.keyboard)
    glutIdleFunc(scene.display)
    #glutTimerFunc( int(1/60), scene.timer, 0)
    scene.init()
    glutMainLoop()

перенесено с: gslayered.cpp

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...