Blender V2.61 - r43446

gpu.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version. 
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2006 Blender Foundation.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): Benoit Bolsee.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00035 /* python redefines */
00036 #ifdef _POSIX_C_SOURCE
00037 #undef _POSIX_C_SOURCE
00038 #endif
00039 
00040 #include <Python.h>
00041 
00042 #include "GPU_material.h"
00043 
00044 #include "DNA_scene_types.h"
00045 #include "DNA_image_types.h"
00046 #include "DNA_material_types.h"
00047 #include "DNA_lamp_types.h"
00048 #include "DNA_object_types.h"
00049 #include "DNA_ID.h"
00050 #include "DNA_customdata_types.h"
00051 
00052 #include "BLI_listbase.h"
00053 #include "BLI_utildefines.h"
00054 
00055 #include "RNA_access.h"
00056 
00057 #include "bpy_rna.h"
00058 
00059 #include "gpu.h"
00060 
00061 #define PY_MODULE_ADD_CONSTANT(module, name) PyModule_AddIntConstant(module, #name, name)
00062 
00063 PyDoc_STRVAR(M_gpu_doc,
00064              "This module provides access to the GLSL shader.");
00065 
00066 static struct PyModuleDef gpumodule = {
00067     PyModuleDef_HEAD_INIT,
00068     "gpu",     /* name of module */
00069     M_gpu_doc, /* module documentation */
00070     -1,        /* size of per-interpreter state of the module,
00071                   or -1 if the module keeps state in global variables. */
00072    NULL, NULL, NULL, NULL, NULL
00073 };
00074 
00075 PyMODINIT_FUNC
00076 PyInit_gpu(void)
00077 {
00078     PyObject* m;
00079 
00080     m = PyModule_Create(&gpumodule);
00081     if (m == NULL)
00082         return NULL;
00083 
00084     // device constants
00085     PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_VIEWMAT);
00086     PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_MAT);
00087     PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_VIEWIMAT);
00088     PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_IMAT);
00089     PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_COLOR);
00090     PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_AUTOBUMPSCALE);
00091     PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNVEC);
00092     PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNCO);
00093     PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNIMAT);
00094     PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNPERSMAT);
00095     PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNENERGY);
00096     PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNCOL);
00097     PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DBUFFER);
00098     PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DIMAGE);
00099     PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DSHADOW);
00100 
00101     PY_MODULE_ADD_CONSTANT(m, GPU_DATA_1I);
00102     PY_MODULE_ADD_CONSTANT(m, GPU_DATA_1F);
00103     PY_MODULE_ADD_CONSTANT(m, GPU_DATA_2F);
00104     PY_MODULE_ADD_CONSTANT(m, GPU_DATA_3F);
00105     PY_MODULE_ADD_CONSTANT(m, GPU_DATA_4F);
00106     PY_MODULE_ADD_CONSTANT(m, GPU_DATA_9F);
00107     PY_MODULE_ADD_CONSTANT(m, GPU_DATA_16F);
00108     PY_MODULE_ADD_CONSTANT(m, GPU_DATA_4UB);
00109 
00110     PY_MODULE_ADD_CONSTANT(m, CD_MTFACE);
00111     PY_MODULE_ADD_CONSTANT(m, CD_ORCO);
00112     PY_MODULE_ADD_CONSTANT(m, CD_TANGENT);
00113     PY_MODULE_ADD_CONSTANT(m, CD_MCOL);
00114     return m;
00115 }
00116 
00117 #define PY_DICT_ADD_STRING(d,s,f) \
00118     val = PyUnicode_FromString(s->f);   \
00119     PyDict_SetItemString(d, #f, val);   \
00120     Py_DECREF(val)
00121 
00122 #define PY_DICT_ADD_LONG(d,s,f) \
00123     val = PyLong_FromLong(s->f);    \
00124     PyDict_SetItemString(d, #f, val);   \
00125     Py_DECREF(val)
00126 
00127 #define PY_DICT_ADD_ID(d,s,f) \
00128     RNA_id_pointer_create((struct ID*)s->f, &tptr); \
00129     val = pyrna_struct_CreatePyObject(&tptr);   \
00130     PyDict_SetItemString(d, #f, val);   \
00131     Py_DECREF(val)
00132 
00133 #define PY_OBJ_ADD_ID(d,s,f) \
00134     val = PyUnicode_FromString(&s->f->id.name[2]);  \
00135     PyObject_SetAttrString(d, #f, val); \
00136     Py_DECREF(val)
00137 
00138 #define PY_OBJ_ADD_LONG(d,s,f) \
00139     val = PyLong_FromLong(s->f);    \
00140     PyObject_SetAttrString(d, #f, val); \
00141     Py_DECREF(val)
00142 
00143 #define PY_OBJ_ADD_STRING(d,s,f) \
00144     val = PyUnicode_FromString(s->f);   \
00145     PyObject_SetAttrString(d, #f, val); \
00146     Py_DECREF(val)
00147 
00148 PyDoc_STRVAR(GPU_export_shader_doc,
00149 "export_shader(scene, material)\n"
00150 "\n"
00151 "   Returns the GLSL shader that produces the visual effect of material in scene.\n"
00152 "\n"
00153 "   :return: Dictionary defining the shader, uniforms and attributes.\n"
00154 "   :rtype: Dict"
00155 );
00156 static PyObject* GPU_export_shader(PyObject* UNUSED(self), PyObject *args, PyObject *kwds)
00157 {
00158     PyObject* pyscene;
00159     PyObject* pymat;
00160     PyObject* as_pointer;
00161     PyObject* pointer;
00162     PyObject* result;
00163     PyObject* dict;
00164     PyObject* val;
00165     PyObject* seq;
00166 
00167     int i;
00168     Scene *scene;
00169     PointerRNA tptr;
00170     Material *material;
00171     GPUShaderExport *shader;
00172     GPUInputUniform *uniform;
00173     GPUInputAttribute *attribute;
00174 
00175     static const char *kwlist[] = {"scene", "material", NULL};
00176 
00177     if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO:export_shader", (char**)(kwlist), &pyscene, &pymat))
00178         return NULL;
00179 
00180     if (!strcmp(Py_TYPE(pyscene)->tp_name, "Scene") && 
00181         (as_pointer = PyObject_GetAttrString(pyscene, "as_pointer")) != NULL &&
00182         PyCallable_Check(as_pointer)) {
00183         // must be a scene object
00184         pointer = PyObject_CallObject(as_pointer, NULL);
00185         if (!pointer) {
00186             PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed");
00187             return NULL;
00188         }
00189         scene = (Scene*)PyLong_AsVoidPtr(pointer);
00190         Py_DECREF(pointer);
00191         if (!scene) {
00192             PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed");
00193             return NULL;
00194         }
00195     }
00196     else {
00197         PyErr_SetString(PyExc_TypeError, "gpu.export_shader() first argument should be of Scene type");
00198         return NULL;
00199     }
00200 
00201     if (!strcmp(Py_TYPE(pymat)->tp_name, "Material") && 
00202         (as_pointer = PyObject_GetAttrString(pymat, "as_pointer")) != NULL &&
00203         PyCallable_Check(as_pointer)) {
00204         // must be a material object
00205         pointer = PyObject_CallObject(as_pointer, NULL);
00206         if (!pointer) {
00207             PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed");
00208             return NULL;
00209         }
00210         material = (Material*)PyLong_AsVoidPtr(pointer);
00211         Py_DECREF(pointer);
00212         if (!material) {
00213             PyErr_SetString(PyExc_SystemError, "scene.as_pointer() failed");
00214             return NULL;
00215         }
00216     }
00217     else {
00218         PyErr_SetString(PyExc_TypeError, "gpu.export_shader() second argument should be of Material type");
00219         return NULL;
00220     }
00221     // we can call our internal function at last:
00222     shader = GPU_shader_export(scene, material);
00223     if (!shader) {
00224         PyErr_SetString(PyExc_RuntimeError, "cannot export shader");
00225         return NULL;
00226     }
00227     // build a dictionary
00228     result = PyDict_New();
00229     if (shader->fragment) {
00230         PY_DICT_ADD_STRING(result,shader,fragment);
00231     }
00232     if (shader->vertex) {
00233         PY_DICT_ADD_STRING(result,shader,vertex);
00234     }
00235     seq = PyList_New(BLI_countlist(&shader->uniforms));
00236     for (i=0, uniform=shader->uniforms.first; uniform; uniform=uniform->next, i++) {
00237         dict = PyDict_New();
00238         PY_DICT_ADD_STRING(dict,uniform,varname);
00239         PY_DICT_ADD_LONG(dict,uniform,datatype);
00240         PY_DICT_ADD_LONG(dict,uniform,type);
00241         if (uniform->lamp) {
00242             PY_DICT_ADD_ID(dict,uniform,lamp);
00243         }
00244         if (uniform->image) {
00245             PY_DICT_ADD_ID(dict,uniform,image);
00246         }
00247         if (uniform->type == GPU_DYNAMIC_SAMPLER_2DBUFFER ||
00248             uniform->type == GPU_DYNAMIC_SAMPLER_2DIMAGE ||
00249             uniform->type == GPU_DYNAMIC_SAMPLER_2DSHADOW) {
00250             PY_DICT_ADD_LONG(dict,uniform,texnumber);
00251         }
00252         if (uniform->texpixels) {
00253             val = PyByteArray_FromStringAndSize((const char *)uniform->texpixels, uniform->texsize * 4);
00254             PyDict_SetItemString(dict, "texpixels", val);
00255             Py_DECREF(val);
00256             PY_DICT_ADD_LONG(dict,uniform,texsize);
00257         }
00258         PyList_SET_ITEM(seq, i, dict);
00259     }
00260     PyDict_SetItemString(result, "uniforms", seq);
00261     Py_DECREF(seq);
00262 
00263     seq = PyList_New(BLI_countlist(&shader->attributes));
00264     for (i=0, attribute=shader->attributes.first; attribute; attribute=attribute->next, i++) {
00265         dict = PyDict_New();
00266         PY_DICT_ADD_STRING(dict,attribute,varname);
00267         PY_DICT_ADD_LONG(dict,attribute,datatype);
00268         PY_DICT_ADD_LONG(dict,attribute,type);
00269         PY_DICT_ADD_LONG(dict,attribute,number);
00270         if (attribute->name) {
00271             if (attribute->name[0] != 0) {
00272                 PY_DICT_ADD_STRING(dict,attribute,name);
00273             }
00274             else {
00275                 val = PyLong_FromLong(0);
00276                 PyDict_SetItemString(dict, "name", val);
00277                 Py_DECREF(val);
00278             }
00279         }
00280         PyList_SET_ITEM(seq, i, dict);
00281     }
00282     PyDict_SetItemString(result, "attributes", seq);
00283     Py_DECREF(seq);
00284 
00285     GPU_free_shader_export(shader);
00286 
00287     return result;
00288 }
00289 
00290 static PyMethodDef meth_export_shader[] = {
00291     {"export_shader", (PyCFunction)GPU_export_shader, METH_VARARGS | METH_KEYWORDS, GPU_export_shader_doc}
00292 };
00293 
00294 PyObject* GPU_initPython(void)
00295 {
00296     PyObject* module = PyInit_gpu();
00297     PyModule_AddObject(module, "export_shader", (PyObject *)PyCFunction_New(meth_export_shader, NULL));
00298     PyDict_SetItemString(PyImport_GetModuleDict(), "gpu", module);
00299 
00300     return module;
00301 }
00302