从Python传递GLMAT4到C++(GLM::Mat4)

2024-10-02 14:18:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个boostpython应用程序,它将一个类导出到python,执行计算并将输出返回到C++:

import engine # c++ library
import glm # pyglm

class Game(engine.Application):
    def __init__(self):
        engine.Application.__init__(self, title, fullscreen)
        self.shader = engine.Shader();
        self.shader.setup("shader.vs", "shader.fs")
        self.shader.setMat4("model", glm.mat4(1.0)
    def update(self):
        ...

其他类中,着色器被C++包装并导出,如:

struct ShaderWrap : Shader, boost::python::wrapper<Shader>
{
  int setup(const char* vertexPath, const char* fragmentPath)
  {
    return Shader::setup(vertexPath, fragmentPath);
  }
  int setMat4(std::string name, glm::mat4 mat)
  {
    return Shader::setMat4(name, mat);
  }
};

...

BOOST_PYTHON_MODULE(engine)
{
  namespace python = boost::python;

  ...

  python::class_<ShaderWrap, boost::noncopyable>("Shader")
    .def("setup", &Shader::setup)
    .def("setMat4", &Shader::setMat4)
    ;

  ...
}

应用程序在self.shader.setMat4调用之前工作正常,我得到错误:

Boost.Python.ArgumentError: Python argument types in
    StaticShader.setMat4(StaticShader, str, glm::detail::tmat4x4)
did not match C++ signature:
    setMat4(StaticShader {lvalue}, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, glm::mat<4, 4, float, (glm::qualifier)0>)

我曾试图把Mat4值作为浮点,回到C++,但没有成功。 我还尝试调用value_ptr(mat4),它返回一个c_void_p,但是编译器抱怨说c_void_pvoid*不是同一类型(还尝试了各种尝试,用ctypes库强制转换它)。 this问题和{a2}问题基本上是同一个问题,但我在实现中迷失了方向

在PyGLM文档中,开发人员称该库是用C++编写的。所以

<> >强>什么可能通过^ {< CD7>}值到C++,被解释为^ {CD8>}值?< /强>

我想传递一个GL.MAT4,比如视图矩阵,在Python代码更新函数中被更新为C++,以进一步使用,并希望通过Boosi::Python在PyGLM库/GLM库之间有一个相当简单的接口。提前谢谢


Tags: selfdefsetupenginestdboostglmmat
1条回答
网友
1楼 · 发布于 2024-10-02 14:18:27

最后就这个问题联系了开发商,得到了如下回复:

这是C++对象中矩阵对象的样子:

template<int C, int R, typename T>
struct mat {
    PyObject ob_base;
    uint8_t info;
    glm::mat<C, R, T> super_type;
};

这很可能就是它与glm矩阵不完全兼容的原因

如果您使用的是最新版本的PyGLM,value_ptr(mat4)应该返回一个LP_c_float对象,即float*。 我确信有一种方法可以将这样一个指针转移到boost::python,尽管正如我所说的,我不知道如何转移

从技术上讲,您可以将指针转换为整数,然后将其转换回float*。 您可以使用以下命令获取指针的地址:

int.from_bytes(ptr, "little")

或者,您可以简单地通过字节对象发送

as_bytes = bytes(mat4)

或作为元组:

as_tuple = mat4.to_tuple()

或者作为一个numpy数组(它似乎有自己的boost::python::numpy模块):

np_arr = numpy.array(mat4)

我通过将内存地址作为^ {< CD5>}返回C++,得到正确的输出,然后进行了一些切片以将其返回到^ {< CD6>},但是我发现这个解决方案过于复杂,最终手工包装了^ {CD6>}类(参见{a1},以获得如何实现这一基本示例)。p>

相关问题 更多 >