Confusion on C++ Python extensions. Things like getting C++ values for python values.
- by Matthew Mitchell
I'm wanted to convert some of my python code to C++ for speed but it's not as easy as simply making a C++ function and making a few function calls. I have no idea how to get a C++ integer from a python integer object. I have an integer which is an attribute of an object that I want to use. I also have integers which are inside a list in the object which I need to use.
I wanted to test making a C++ extension with this function:
def setup_framebuffer(surface,flip=False):
#Create texture if not done already
if surface.texture is None:
create_texture(surface)
#Render child to parent
if surface.frame_buffer is None:
surface.frame_buffer = glGenFramebuffersEXT(1)
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, c_uint(int(surface.frame_buffer)))
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, surface.texture, 0)
glPushAttrib(GL_VIEWPORT_BIT)
glViewport(0,0,surface._scale[0],surface._scale[1])
glMatrixMode(GL_PROJECTION)
glLoadIdentity() #Load the projection matrix
if flip:
gluOrtho2D(0,surface._scale[0],surface._scale[1],0)
else:
gluOrtho2D(0,surface._scale[0],0,surface._scale[1])
That function calls create_texture, so I will have to pass that function to the C++ function which I will do with the third argument. This is what I have so far, while trying to follow information on the python documentation:
#include <Python.h>
#include <GL/gl.h>
static PyMethodDef SpamMethods[] = {
...
{"setup_framebuffer", setup_framebuffer, METH_VARARGS,"Loads a texture from a Surface object to the OpenGL framebuffer."},
...
{NULL, NULL, 0, NULL} /* Sentinel */
};
static PyObject * setup_framebuffer(PyObject *self, PyObject *args){
bool flip;
PyObject *create_texture, *arg_list,*pyflip,*frame_buffer_id;
if (!PyArg_ParseTuple(args, "OOO", &surface,&pyflip,&create_texture)){
return NULL;
}
if (PyObject_IsTrue(pyflip) == 1){
flip = true;
}else{
flip = false;
}
Py_XINCREF(create_texture);
//Create texture if not done already
if(texture == NULL){
arglist = Py_BuildValue("(O)", surface)
result = PyEval_CallObject(create_texture, arglist);
Py_DECREF(arglist);
if (result == NULL){
return NULL;
}
Py_DECREF(result);
}
Py_XDECREF(create_texture);
//Render child to parent
frame_buffer_id = PyObject_GetAttr(surface, Py_BuildValue("s","frame_buffer"))
if(surface.frame_buffer == NULL){
glGenFramebuffersEXT(1,frame_buffer_id);
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, surface.frame_buffer));
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, surface.texture, 0);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0,0,surface._scale[0],surface._scale[1]);
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); //Load the projection matrix
if (flip){
gluOrtho2D(0,surface._scale[0],surface._scale[1],0);
}else{
gluOrtho2D(0,surface._scale[0],0,surface._scale[1]);
}
Py_INCREF(Py_None);
return Py_None;
}
PyMODINIT_FUNC initcscalelib(void){
PyObject *module;
module = Py_InitModule("cscalelib", Methods);
if (m == NULL){
return;
}
}
int main(int argc, char *argv[]){
/* Pass argv[0] to the Python interpreter */
Py_SetProgramName(argv[0]);
/* Initialize the Python interpreter. Required. */
Py_Initialize();
/* Add a static module */
initscalelib();
}