Giter Club home page Giter Club logo

Comments (6)

 avatar commented on June 28, 2024

Update: The data I'm interested in can be retrieved in OpenGL 3 using glGetProgramiv(program_glo, gl.GL_ACTIVE_UNIFORMS) glGetUniformLocation, glGetActiveUniformName, and glGetActiveUniformsiv. For reference, the docs for these functions and explanation for what attributes can be retrieved by glGetActiveUniformsiv can be found here: https://www.khronos.org/opengl/wiki/Program_Introspection

from moderngl.

mabl avatar mabl commented on June 28, 2024

I just came across this issue, having to create arays of nested structures passed to a compute shader - and it was super painful. Having the proposed ability to generate the structure definitions on the fly, would have saved me a lot of pain.

from moderngl.

szabolcsdombi avatar szabolcsdombi commented on June 28, 2024

This will be implemented as a standalone module. It will most likely use the program interface query (seems to be available all the time but actually it is part of OpenGL 4.3+)

I have some local code for it. I just realized I did not push anything yet to https://github.com/szabolcsdombi/ubo

from moderngl.

mabl avatar mabl commented on June 28, 2024

I have some local code for it. I just realized I did not push anything yet to https://github.com/szabolcsdombi/ubo

I just came across this issue again. Could you kindly consider pushing your prototype code? Thay would be a real help in getting such complicated ctype definitions right.

from moderngl.

szabolcsdombi avatar szabolcsdombi commented on June 28, 2024

Here is a minimum working code for getting all the information needed to construct the layout:

import ctypes
from OpenGL import GL
program = zengl.inspect(pipeline)['program']
num_blocks = GL.glGetProgramiv(program, GL.GL_ACTIVE_UNIFORM_BLOCKS)
uniform_blocks = {}
for i in range(num_blocks):
    name = (ctypes.c_byte * 100)()
    length = ctypes.c_long()
    GL.glGetActiveUniformBlockName(program, i, 100, ctypes.byref(length), ctypes.byref(name))
    size = ctypes.c_long()
    GL.glGetActiveUniformBlockiv(program, i, GL.GL_UNIFORM_BLOCK_DATA_SIZE, ctypes.byref(size))
    name = bytes(name)[:length.value].decode()
    uniform_blocks[i] = {'name': name, 'size': size.value, 'members': {}}

num_uniforms = GL.glGetProgramiv(program, GL.GL_ACTIVE_UNIFORMS)
uniforms = {}
for i in range(num_uniforms):
    name = (ctypes.c_byte * 100)()
    length = ctypes.c_long()
    GL.glGetActiveUniformName(program, i, 100, ctypes.byref(length), ctypes.byref(name))
    name = bytes(name)[:length.value].decode()
    uniforms[i] = {'name': name}

uniform_indices = (ctypes.c_long * num_uniforms)()
for i in range(num_uniforms):
    uniform_indices[i] = i

info = [
    ('gltype', GL.GL_UNIFORM_TYPE),
    ('block', GL.GL_UNIFORM_BLOCK_INDEX),
    ('offset', GL.GL_UNIFORM_OFFSET),
    ('array_size', GL.GL_UNIFORM_SIZE),
    ('array_stride', GL.GL_UNIFORM_ARRAY_STRIDE),
    ('matrix_stride', GL.GL_UNIFORM_MATRIX_STRIDE),
    ('row_major', GL.GL_UNIFORM_IS_ROW_MAJOR),
]

for key, pname in info:
    params = (ctypes.c_long * num_uniforms)()
    GL.glGetActiveUniformsiv(program, num_uniforms, ctypes.byref(uniform_indices), pname, ctypes.byref(params))
    for i in range(num_uniforms):
        uniforms[i][key] = params[i]

for i in range(num_uniforms):
    if uniforms[i]['block'] != -1:
        uniform_blocks[uniforms[i]['block']]['members'][uniforms[i]['name']] = uniforms[i]

print(uniform_blocks)

I did not continue work on this after I found out it takes a tremendous amount of effort to actually parse the output for arrays.
Please see Program_Introspection#Arrays.

struct Aggregate
{
  vec2 main;
  vec2 sec[3];
};

uniform Aggregate unifArray[5];

There is no uniform named unifArray. However, there is a uniform named unifArray[0].main. There is one named unifArray[2].sec[0], which is an array of basic types. There are five of each of these. As before, the bottom-level array can be clipped off: unifArray[2].sec is equivalent to unifArray[2].sec[0].
These rules are applied recursively up the hierarchy.


PS: replace program = zengl.inspect(pipeline)['program'] with program = my_moderngl_program.glo

from moderngl.

szabolcsdombi avatar szabolcsdombi commented on June 28, 2024

This should be a separate module so I am closing this here.

from moderngl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.