45 #include <SDL_syswm.h>
47 #include "SDL_image/SDL_image.h"
50 #include <X11/Xutil.h>
54 #include <Python/structmember.h>
56 #include <structmember.h>
68 typedef SDL_Surface *(*PFN_IMG_LOAD)(
const char *);
102 {
"fovAngle", T_FLOAT, offsetof(
Camera, fovAngle), 0,
"The Field Of View angle."},
103 {
"nearPlane", T_FLOAT, offsetof(
Camera, nearPlane), 0,
"The Near Clipping Plane."},
104 {
"farPlane", T_FLOAT, offsetof(
Camera, farPlane), 0,
"The Far Clipping Plane."},
105 {
"projection", T_UINT, offsetof(
Camera, projection), 0,
"The projection type, 0 for orthogonal, 1 for perspective."},
106 {
"stereoMode", T_UINT, offsetof(
Camera, stereoMode), 0,
"The Stereo Mode, 0 for no stereo, 1 for toe-in, 2 for off-axis."},
107 {
"eyeSeparation", T_FLOAT, offsetof(
Camera, eyeSeparation), 0,
"The Eye Separation."},
108 {
"eyeX", T_FLOAT, offsetof(
Camera, eyeX), 0,
"The x position of the eye."},
109 {
"eyeY", T_FLOAT, offsetof(
Camera, eyeY), 0,
"The y position of the eye."},
110 {
"eyeZ", T_FLOAT, offsetof(
Camera, eyeZ), 0,
"The z position of the eye."},
111 {
"focusX", T_FLOAT, offsetof(
Camera, focusX), 0,
"The x position of the focus."},
112 {
"focusY", T_FLOAT, offsetof(
Camera, focusY), 0,
"The y position of the focus."},
113 {
"focusZ", T_FLOAT, offsetof(
Camera, focusZ), 0,
"The z position of the focus."},
114 {
"upX", T_FLOAT, offsetof(
Camera, upX), 0,
"The x of the up vector."},
115 {
"upY", T_FLOAT, offsetof(
Camera, upY), 0,
"The y of the up vector."},
116 {
"upZ", T_FLOAT, offsetof(
Camera, upZ), 0,
"The z of the up vector."},
128 "Converts world coordinates to screen coordinates."
131 "Converts 2D screen coordinates to world coordinates."
134 "Converts 3D screen coordinates to world coordinates."
139 static PyObject *
Camera_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
145 PyObject_HEAD_INIT(NULL)
165 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
193 if (PyType_Ready(&CameraType) < 0)
196 Py_INCREF(&CameraType);
197 PyModule_AddObject(module,
"Camera", (PyObject*)&CameraType);
205 static PyObject *
Camera_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
214 self->nearPlane = 0.1f;
215 self->farPlane = 100.0f;
217 self->projection = 1;
219 self->stereoMode = 0;
220 self->eyeSeparation = 1.0f;
233 return (PyObject*)
self;
246 if (!PyArg_ParseTuple(args,
"|s", &path))
263 {
"textureId", T_UINT, offsetof(
Texture, textureId), READONLY,
"The id of the OpenGL texture."},
264 {
"width", T_UINT, offsetof(
Texture, width), READONLY,
"The width of the texture in pixels."},
265 {
"height", T_UINT, offsetof(
Texture, height), READONLY,
"The height of the texture in pixels."},
275 "Loads the specified image from file"
281 static PyObject *
Texture_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
287 PyObject_HEAD_INIT(NULL)
307 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
323 (initproc)Texture_init,
335 if (PyType_Ready(&TextureType) < 0)
338 Py_INCREF(&TextureType);
339 PyModule_AddObject(module,
"Texture", (PyObject*)&TextureType);
350 glDeleteTextures(1, &self->textureId);
353 self->ob_type->tp_free((PyObject*)
self);
361 static PyObject *
Texture_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
369 glGenTextures(1, &self->textureId);
374 return (PyObject*)
self;
387 if (!PyArg_ParseTuple(args,
"|s", &path))
390 if (path && !
mhLoadTexture(path, self->textureId, &self->width, &self->height))
398 if (PyString_Check(path))
403 else if (PyUnicode_Check(path))
405 path = PyUnicode_AsUTF8String(path);
415 PyErr_SetString(PyExc_TypeError,
"String or Unicode object expected");
419 return Py_BuildValue(
"");
422 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
432 # if defined(__ppc__)
433 register uint32_t word;
434 __asm__(
"lwbrx %0,%2,%1" :
"=r" (word) :
"r" (&inValue),
"b" (0));
436 # elif defined(__x86__) || defined(__i386__) || defined (__x86_64__)
437 register uint32_t word;
438 __asm__(
"bswap %0" :
"=r" (word) :
"0" (inValue));
442 return (((inValue ) & 0xff) << 24) |
443 (((inValue >> 8) & 0xff) << 16) |
444 (((inValue >> 16) & 0xff) << 8) |
445 (((inValue >> 24) & 0xff));
447 #endif // #if SDL_BYTEORDER == SDL_BIG_ENDIAN
463 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
464 memcpy(destPtr, srcPtr, inLongs << 2);
467 for (i=0; i<inLongs; ++i)
469 *(destPtr++) =
swapLong(*(srcPtr++));
484 unsigned char *line = (
unsigned char*)malloc(surface->pitch);
485 const size_t lineBytes = surface->pitch;
486 const size_t lineLongs = lineBytes >> 2;
488 unsigned char *pixelsA;
489 unsigned char *pixelsB;
495 if (SDL_MUSTLOCK(surface)) SDL_LockSurface(surface);
497 pixelsA = (
unsigned char*)surface->pixels;
498 pixelsB = (
unsigned char*)surface->pixels + (surface->h - 1) * lineBytes;
500 for (lineIndex = 0; lineIndex < surface->h >> 1; lineIndex++)
502 memcpy((uint32_t*)line, (
const uint32_t*)pixelsA, lineBytes);
506 pixelsA += lineBytes;
507 pixelsB -= lineBytes;
509 if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface);
520 GLuint
mhLoadTexture(
const char *fname, GLuint texture,
int *width,
int *height)
522 int internalFormat, format;
523 SDL_Surface *surface;
528 glGenTextures(1, &texture);
530 #ifndef __APPLE__ // OS X utilizes the SDL_image framework for image loading!
541 PyErr_Format(PyExc_RuntimeError,
"Could not load %s, SDL_image not found", fname);
550 PyErr_Format(PyExc_RuntimeError,
"Could not load %s, IMG_Load not found", fname);
553 #endif // ifndef __APPLE__
554 surface = (SDL_Surface*)
IMG_Load(fname);
558 PyErr_Format(PyExc_RuntimeError,
"Could not load %s, %s", fname, SDL_GetError());
562 switch (surface->format->BytesPerPixel)
565 internalFormat = GL_ALPHA8;
570 if (surface->format->Rshift)
577 if (surface->format->Rshift)
583 SDL_FreeSurface(surface);
584 PyErr_Format(PyExc_RuntimeError,
"Could not load %s, unsupported pixel format", fname);
594 glBindTexture(GL_TEXTURE_1D, texture);
595 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE_EXT);
596 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE_EXT);
597 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
598 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
599 gluBuild1DMipmaps(GL_TEXTURE_1D, internalFormat, surface->w, format, GL_UNSIGNED_BYTE, surface->pixels);
600 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
604 glBindTexture(GL_TEXTURE_2D, texture);
605 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE_EXT);
606 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE_EXT);
610 #if defined(__APPLE__)
611 const int isFont = (strstr(fname,
"/fonts/") != NULL);
614 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
615 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
621 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
622 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
624 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
625 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
629 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
630 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
632 gluBuild2DMipmaps(GL_TEXTURE_2D, internalFormat, surface->w, surface->h, format, GL_UNSIGNED_BYTE, surface->pixels);
634 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
640 *height = surface->h;
642 SDL_FreeSurface(surface);
652 if (GLEW_VERSION_2_0)
654 v = glCreateShader(GL_VERTEX_SHADER);
656 glShaderSource(v, 1, &source, NULL);
659 glGetShaderiv(v, GL_COMPILE_STATUS, &status);
660 if (status != GL_TRUE)
664 glGetShaderiv(v, GL_INFO_LOG_LENGTH, &logLength);
669 GLsizei charsWritten;
671 log = (
char*)malloc(logLength);
672 glGetShaderInfoLog(v, logLength, &charsWritten, log);
673 PyErr_Format(PyExc_RuntimeError,
"Error compiling vertex shader: %s", log);
677 PyErr_SetString(PyExc_RuntimeError,
"Error compiling vertex shader");
684 else if (GLEW_ARB_shader_objects)
686 v = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
688 glShaderSourceARB(v, 1, &source, NULL);
690 glCompileShaderARB(v);
691 glGetObjectParameterivARB(v, GL_OBJECT_COMPILE_STATUS_ARB, &status);
692 if (status != GL_TRUE)
696 glGetObjectParameterivARB(v, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logLength);
701 GLsizei charsWritten;
703 log = (
char*)malloc(logLength);
704 glGetInfoLogARB(v, logLength, &charsWritten, log);
705 PyErr_Format(PyExc_RuntimeError,
"Error compiling vertex shader: %s", log);
709 PyErr_SetString(PyExc_RuntimeError,
"Error compiling vertex shader");
718 PyErr_SetString(PyExc_RuntimeError,
"No shader support detected");
728 if (GLEW_VERSION_2_0)
730 f = glCreateShader(GL_FRAGMENT_SHADER);
732 glShaderSource(f, 1, &source, NULL);
735 glGetShaderiv(f, GL_COMPILE_STATUS, &status);
736 if (status != GL_TRUE)
740 glGetShaderiv(f, GL_INFO_LOG_LENGTH, &logLength);
745 GLsizei charsWritten;
747 log = (
char*)malloc(logLength);
748 glGetShaderInfoLog(f, logLength, &charsWritten, log);
749 PyErr_Format(PyExc_RuntimeError,
"Error compiling fragment shader: %s", log);
753 PyErr_SetString(PyExc_RuntimeError,
"Error compiling fragment shader");
760 else if (GLEW_ARB_shader_objects)
762 f = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
764 glShaderSourceARB(f, 1, &source, NULL);
766 glCompileShaderARB(f);
767 glGetObjectParameterivARB(f, GL_OBJECT_COMPILE_STATUS_ARB, &status);
768 if (status != GL_TRUE)
772 glGetObjectParameterivARB(f, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logLength);
777 GLsizei charsWritten;
779 log = (
char*)malloc(logLength);
780 glGetInfoLogARB(f, logLength, &charsWritten, log);
781 PyErr_Format(PyExc_RuntimeError,
"Error compiling fragment shader: %s", log);
785 PyErr_SetString(PyExc_RuntimeError,
"Error compiling fragment shader");
794 PyErr_SetString(PyExc_RuntimeError,
"No shader support detected");
804 if (GLEW_VERSION_2_0)
806 p = glCreateProgram();
808 glAttachShader(p, vertexShader);
809 glAttachShader(p, fragmentShader);
812 glGetProgramiv(p, GL_LINK_STATUS, &status);
813 if (status != GL_TRUE)
817 glGetProgramiv(p, GL_INFO_LOG_LENGTH, &logLength);
822 GLsizei charsWritten;
824 log = (
char*)malloc(logLength);
825 glGetProgramInfoLog(p, logLength, &charsWritten, log);
826 PyErr_Format(PyExc_RuntimeError,
"Error linking shader: %s", log);
830 PyErr_SetString(PyExc_RuntimeError,
"Error linking shader");
837 else if (GLEW_ARB_shader_objects)
839 p = glCreateProgramObjectARB();
841 glAttachObjectARB(p, vertexShader);
842 glAttachObjectARB(p, fragmentShader);
845 glGetObjectParameterivARB(p, GL_OBJECT_LINK_STATUS_ARB , &status);
846 if (status != GL_TRUE)
850 glGetObjectParameterivARB(p, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logLength);
855 GLsizei charsWritten;
857 log = (
char*)malloc(logLength);
858 glGetInfoLogARB(p, logLength, &charsWritten, log);
859 PyErr_Format(PyExc_RuntimeError,
"Error linking shader: %s", log);
863 PyErr_SetString(PyExc_RuntimeError,
"Error linking shader");
872 PyErr_SetString(PyExc_RuntimeError,
"No shader support detected");
888 int mhGrabScreen(
int x,
int y,
int width,
int height,
const char *filename)
891 SDL_Surface *surface;
894 if (width <= 0 || height <= 0)
896 PyErr_Format(PyExc_RuntimeError,
"width or height is 0");
900 surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 24, 0xFF, 0xFF00, 0xFF0000, 0);
901 glGetIntegerv(GL_VIEWPORT, viewport);
903 if (SDL_LockSurface(surface))
905 SDL_FreeSurface(surface);
906 PyErr_Format(PyExc_RuntimeError,
"Could not lock surface to grab region to file %s, %s", filename, SDL_GetError());
912 glPixelStorei(GL_PACK_ALIGNMENT, 4);
917 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
922 glReadPixels(x, viewport[3] - y - height, width, height, format, GL_UNSIGNED_BYTE, surface->pixels);
925 SDL_UnlockSurface(surface);
927 if (SDL_SaveBMP(surface, filename))
929 SDL_FreeSurface(surface);
930 PyErr_Format(PyExc_RuntimeError,
"Could not access file to grab region to file %s, %s", filename, SDL_GetError());
934 SDL_FreeSurface(surface);
948 void mhKeyDown(
int key,
unsigned short character,
int modifiers)
953 void mhKeyUp(
int key,
unsigned short character,
int modifiers)
981 event.type = SDL_USEREVENT;
983 event.user.data1 = param;
984 event.user.data2 = NULL;
986 SDL_PushEvent(&event);
1018 SDL_WM_GrabInput(SDL_GRAB_ON);
1022 if (b != 4 && b != 5)
1031 if (b != 4 && b != 5)
1059 SDL_WM_GrabInput(SDL_GRAB_OFF);
1063 if (b != 4 && b != 5)
1120 glGetIntegerv(GL_VIEWPORT, viewport);
1122 width = viewport[2];
1123 height = viewport[3];
1126 if (pickingBufferSize != width * height * 3)
1128 pickingBufferSize = width * height * 3;
1129 pickingBuffer = (
unsigned char*)realloc(pickingBuffer, pickingBufferSize);
1130 assert(pickingBuffer != NULL);
1134 glDisable(GL_LIGHTING);
1137 glDisable (GL_BLEND);
1138 glDisable(GL_MULTISAMPLE);
1141 glClearColor(0.0, 0.0, 0.0, 0.0);
1142 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1144 for (i = 0; i < PyList_Size(
G.cameras); i++)
1151 glPixelStorei(GL_PACK_ALIGNMENT, 1);
1154 glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pickingBuffer);
1155 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1158 glEnable (GL_BLEND);
1159 glEnable(GL_MULTISAMPLE);
1162 glEnable(GL_LIGHTING);
1204 glGetIntegerv(GL_VIEWPORT, viewport);
1206 y = viewport[3] - y;
1208 if (y < 0 || y >= viewport[3] || x < 0 || x >= viewport[2])
1210 memset(
G.color_picked, 0, 3);
1217 memcpy(
G.color_picked, pickingBuffer + (y * viewport[2] + x) * 3, 3);
1232 GLdouble modelview[16], projection[16];
1233 double world[3], screen[3];
1235 if (!PyArg_ParseTuple(args,
"ddd", world, world + 1, world + 2))
1240 glGetIntegerv(GL_VIEWPORT, viewport);
1241 glGetDoublev(GL_PROJECTION_MATRIX, projection);
1242 glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
1244 gluProject(world[0], world[1], world[2], modelview, projection, viewport, screen, screen + 1, screen + 2);
1245 screen[1] = viewport[3] - screen[1];
1247 return Py_BuildValue(
"[d,d,d]", screen[0], screen[1], screen[2]);
1262 GLdouble modelview[16], projection[16];
1264 double screen[2], world[3];
1266 if (!PyArg_ParseTuple(args,
"dd", screen, screen + 1))
1271 glGetIntegerv(GL_VIEWPORT, viewport);
1272 glGetDoublev(GL_PROJECTION_MATRIX, projection);
1273 glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
1275 glReadPixels((GLint)screen[0], (GLint)(viewport[3] - screen[1]), 1, 1, GL_DEPTH_COMPONENT, GL_DOUBLE, &z);
1276 gluUnProject(screen[0], viewport[3] - screen[1], z, modelview, projection, viewport, world, world + 1, world + 2);
1278 return Py_BuildValue(
"[d,d,d]", world[0], world[1], world[2]);
1293 GLdouble modelview[16], projection[16];
1294 double screen[3], world[3];
1296 if (!PyArg_ParseTuple(args,
"ddd", screen, screen + 1, screen + 2))
1301 glGetIntegerv(GL_VIEWPORT, viewport);
1302 glGetDoublev(GL_PROJECTION_MATRIX, projection);
1303 glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
1305 gluUnProject(screen[0], viewport[3] - screen[1], screen[2], modelview, projection, viewport, world, world + 1, world + 2);
1307 return Py_BuildValue(
"[d,d,d]", world[0], world[1], world[2]);
1322 glViewport(0, 0, w, h);
1324 glMatrixMode(GL_PROJECTION);
1328 glMatrixMode(GL_MODELVIEW);
1343 glClearColor(
G.clearColor[0],
G.clearColor[1],
G.clearColor[2],
G.clearColor[3]);
1344 glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
1353 SDL_GL_SwapBuffers();
1363 const float lightPos[] = { -10.99f, 20.0f, 20.0f, 1.0f};
1364 const float ambientLight[] = { 0.0f, 0.0f, 0.0f, 1.0f};
1365 const float diffuseLight[] = { 1.0f, 1.0f, 1.0f, 1.0f};
1366 const float specularLight[] = {1.0f, 1.0f, 1.0f, 1.0f};
1367 const float MatAmb[] = {0.11f, 0.11f, 0.11f, 1.0f};
1368 const float MatDif[] = {1.0f, 1.0f, 1.0f, 1.0f};
1369 const float MatSpc[] = {0.2f, 0.2f, 0.2f, 1.0f};
1370 const float MatShn[] = {10.0f};
1375 glEnable(GL_DEPTH_TEST);
1379 glDisable(GL_DITHER);
1380 glEnable(GL_LIGHTING);
1381 glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
1382 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
1383 glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
1384 glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
1385 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
1386 glMaterialfv(GL_FRONT, GL_AMBIENT, MatAmb);
1387 glMaterialfv(GL_FRONT, GL_DIFFUSE, MatDif);
1388 glMaterialfv(GL_FRONT, GL_SPECULAR, MatSpc);
1389 glMaterialfv(GL_FRONT, GL_SHININESS, MatShn);
1391 glEnable(GL_LIGHT0);
1392 glEnable(GL_COLOR_MATERIAL);
1393 glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
1396 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1398 glEnableClientState(GL_NORMAL_ARRAY);
1399 glEnableClientState(GL_COLOR_ARRAY);
1400 glEnableClientState(GL_VERTEX_ARRAY);
1410 glDisableClientState(GL_VERTEX_ARRAY);
1411 glDisableClientState(GL_NORMAL_ARRAY);
1413 glDisableClientState(GL_COLOR_ARRAY);
1414 printf(
"Exit from event loop\n");
1434 glMatrixMode(GL_PROJECTION);
1442 glMatrixMode(GL_MODELVIEW);
1451 glMatrixMode(GL_PROJECTION);
1455 glMatrixMode(GL_MODELVIEW);
1471 double aspectratio =
G.windowWidth / (double)
G.windowHeight;
1473 double left = - aspectratio * widthdiv2;
1474 double right = aspectratio * widthdiv2;
1475 double top = widthdiv2;
1476 double bottom = -widthdiv2;
1490 glMatrixMode(GL_PROJECTION);
1495 glMatrixMode(GL_MODELVIEW);
1497 gluLookAt(camera->
eyeX + eyePosition, camera->
eyeY, camera->
eyeZ,
1541 iterator = PyObject_GetIter(
G.world);
1543 for (obj = (Object3D*)PyIter_Next(iterator); obj; obj = (Object3D*)PyIter_Next(iterator))
1548 if (obj->inMovableCamera == cameraType)
1550 if (obj->isVisible && (!pickMode || obj->isPickable))
1554 glTranslatef(obj->x, obj->y, obj->z);
1555 glRotatef(obj->rx, 1, 0, 0);
1556 glRotatef(obj->ry, 0, 1, 0);
1557 glRotatef(obj->rz, 0, 0, 1);
1558 glScalef(obj->sx, obj->sy, obj->sz);
1560 if (obj->texture && !pickMode && obj->isSolid)
1562 glEnable(GL_TEXTURE_2D);
1563 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1564 glBindTexture(GL_TEXTURE_2D, obj->texture);
1565 glTexCoordPointer(2, GL_FLOAT, 0, obj->UVs);
1569 glVertexPointer(3, GL_FLOAT, 0, obj->verts);
1570 glNormalPointer(GL_FLOAT, 0, obj->norms);
1576 glColorPointer(3, GL_UNSIGNED_BYTE, 0, obj->colors);
1581 glColorPointer(4, GL_UNSIGNED_BYTE, 0, obj->colors2);
1585 if (obj->shadeless || pickMode)
1587 glDisable(GL_LIGHTING);
1591 if (!pickMode && obj->shader && obj->isSolid)
1593 if (GLEW_VERSION_2_0)
1596 glUseProgram(obj->shader);
1600 if (obj->shaderParameters)
1602 GLint parameterCount = 0;
1604 int currentTextureSampler = 1;
1606 glGetProgramiv(obj->shader, GL_ACTIVE_UNIFORMS, ¶meterCount);
1608 for (index = 0; index < parameterCount; index++)
1616 glGetActiveUniform(obj->shader, index,
sizeof(name), &length, &size, &type, name);
1618 value = PyDict_GetItemString(obj->shaderParameters, name);
1626 glUniform1f(index, PyFloat_AsDouble(value));
1631 if (!PyList_Check(value) || PyList_Size(value) != 2)
1633 glUniform2f(index, PyFloat_AsDouble(PyList_GetItem(value, 0)), PyFloat_AsDouble(PyList_GetItem(value, 1)));
1638 if (!PyList_Check(value) || PyList_Size(value) != 3)
1640 glUniform3f(index, PyFloat_AsDouble(PyList_GetItem(value, 0)), PyFloat_AsDouble(PyList_GetItem(value, 1)),
1641 PyFloat_AsDouble(PyList_GetItem(value, 2)));
1646 if (!PyList_Check(value) || PyList_Size(value) != 4)
1648 glUniform4f(index, PyFloat_AsDouble(PyList_GetItem(value, 0)), PyFloat_AsDouble(PyList_GetItem(value, 1)),
1649 PyFloat_AsDouble(PyList_GetItem(value, 2)), PyFloat_AsDouble(PyList_GetItem(value, 3)));
1654 glActiveTexture(GL_TEXTURE0 + currentTextureSampler);
1655 glBindTexture(GL_TEXTURE_1D, PyInt_AsLong(value));
1656 glUniform1i(index, currentTextureSampler++);
1661 glActiveTexture(GL_TEXTURE0 + currentTextureSampler);
1662 glBindTexture(GL_TEXTURE_2D, PyInt_AsLong(value));
1663 glUniform1i(index, currentTextureSampler++);
1671 else if (GLEW_ARB_shader_objects)
1673 glUseProgramObjectARB(obj->shader);
1677 if (obj->shaderParameters)
1679 GLint parameterCount = 0;
1681 int currentTextureSampler = 1;
1683 glGetObjectParameterivARB(obj->shader, GL_OBJECT_ACTIVE_UNIFORMS_ARB, ¶meterCount);
1685 for (index = 0; index < parameterCount; index++)
1693 glGetActiveUniformARB(obj->shader, index,
sizeof(name), &length, &size, &type, name);
1695 value = PyDict_GetItemString(obj->shaderParameters, name);
1703 glUniform1fARB(index, PyFloat_AsDouble(value));
1708 if (!PyList_Check(value) || PyList_Size(value) != 2)
1710 glUniform2fARB(index, PyFloat_AsDouble(PyList_GetItem(value, 0)), PyFloat_AsDouble(PyList_GetItem(value, 1)));
1715 if (!PyList_Check(value) || PyList_Size(value) != 3)
1717 glUniform3fARB(index, PyFloat_AsDouble(PyList_GetItem(value, 0)), PyFloat_AsDouble(PyList_GetItem(value, 1)),
1718 PyFloat_AsDouble(PyList_GetItem(value, 2)));
1723 if (!PyList_Check(value) || PyList_Size(value) != 4)
1725 glUniform4fARB(index, PyFloat_AsDouble(PyList_GetItem(value, 0)), PyFloat_AsDouble(PyList_GetItem(value, 1)),
1726 PyFloat_AsDouble(PyList_GetItem(value, 2)), PyFloat_AsDouble(PyList_GetItem(value, 3)));
1731 glActiveTexture(GL_TEXTURE0 + currentTextureSampler);
1732 glBindTexture(GL_TEXTURE_1D, PyInt_AsLong(value));
1733 glUniform1iARB(index, currentTextureSampler++);
1738 glActiveTexture(GL_TEXTURE0 + currentTextureSampler);
1739 glBindTexture(GL_TEXTURE_2D, PyInt_AsLong(value));
1740 glUniform1iARB(index, currentTextureSampler++);
1751 if (!obj->isSolid && !pickMode)
1753 glDisableClientState(GL_COLOR_ARRAY);
1754 glColor3f(0.0f, 0.0f, 0.0f);
1755 glPolygonMode(GL_FRONT_AND_BACK , GL_LINE);
1756 glDrawElements(GL_QUADS, obj->nQuads * 4, GL_UNSIGNED_INT, obj->quads);
1757 glEnableClientState(GL_COLOR_ARRAY);
1758 glPolygonMode(GL_FRONT_AND_BACK , GL_FILL);
1759 glEnable(GL_POLYGON_OFFSET_FILL);
1760 glPolygonOffset(1.0, 1.0);
1761 glDrawElements(GL_QUADS, obj->nQuads * 4, GL_UNSIGNED_INT, obj->quads);
1762 glDisable(GL_POLYGON_OFFSET_FILL);
1765 glDrawElements(GL_QUADS, obj->nQuads * 4, GL_UNSIGNED_INT, obj->quads);
1768 if (!pickMode && obj->shader && obj->isSolid)
1770 if (GLEW_VERSION_2_0)
1772 else if (GLEW_ARB_shader_objects)
1773 glUseProgramObjectARB(0);
1774 glActiveTexture(GL_TEXTURE0);
1778 if (obj->shadeless || pickMode)
1780 glEnable(GL_LIGHTING);
1783 if (obj->texture && !pickMode && obj->isSolid)
1785 glDisable(GL_TEXTURE_2D);
1786 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1793 Py_DECREF((PyObject*)obj);
1796 Py_DECREF(iterator);
1810 for (i = 0; i < PyList_Size(
G.cameras); i++)
1817 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
1820 glClear(GL_DEPTH_BUFFER_BIT);
1821 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
1825 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1828 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1862 if (
G.pendingUpdate)
1867 G.pendingUpdate = 1;
1869 ev.type = SDL_VIDEOEXPOSE;
1883 if (
G.fullscreen == fullscreen)
1888 G.fullscreen = fullscreen;
1906 g_screen = SDL_SetVideoMode(
G.windowWidth,
G.windowHeight, 24, SDL_OPENGL | (
G.fullscreen ? SDL_FULLSCREEN : 0) | SDL_RESIZABLE);
1922 unsigned int colorkey;
1924 const SDL_VideoInfo *info;
1928 if (SDL_Init(SDL_INIT_VIDEO) < 0)
1930 printf(
"Unable to init SDL: %s\n", SDL_GetError());
1934 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
1935 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
1936 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
1937 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
1938 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
1939 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
1940 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
1941 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
1943 info = SDL_GetVideoInfo();
1948 image = SDL_LoadBMP(
"mh_icon.bmp");
1951 colorkey = SDL_MapRGB(image->format, 255, 255, 255);
1952 SDL_SetColorKey(image, SDL_SRCCOLORKEY, colorkey);
1953 SDL_WM_SetIcon(image, NULL);
1967 g_screen = SDL_SetVideoMode(
G.windowWidth,
G.windowHeight, 24, SDL_OPENGL | (
G.fullscreen ? SDL_FULLSCREEN : 0) | SDL_RESIZABLE);
1970 printf(
"No antialiasing available, turning off antialiasing.\n");
1971 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
1972 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
1973 g_screen = SDL_SetVideoMode(
G.windowWidth,
G.windowHeight, 24, SDL_OPENGL | (
G.fullscreen ? SDL_FULLSCREEN : 0) | SDL_RESIZABLE);
1976 printf(
"No 24 bit z buffer available, switching to 16 bit.\n");
1977 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
1978 g_screen = SDL_SetVideoMode(
G.windowWidth,
G.windowHeight, 24, SDL_OPENGL | (
G.fullscreen ? SDL_FULLSCREEN : 0) | SDL_RESIZABLE);
1981 printf(
"No 16 bit z buffer available, exiting.\n");
1987 SDL_WM_SetCaption(
"MakeHuman",
"");
1988 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
1991 SDL_EnableUNICODE(1);
1997 SDL_InitSubSystem(SDL_INIT_TIMER);
2019 Py_BEGIN_ALLOW_THREADS
2020 SDL_WaitEvent(&event);
2021 Py_END_ALLOW_THREADS
2028 extern int isMainWindowActive();
2031 if (!isMainWindowActive())
2037 case SDL_ACTIVEEVENT:
2038 if (event.active.state & SDL_APPINPUTFOCUS)
2040 if (event.active.gain)
2048 SDL_WM_GrabInput(SDL_GRAB_OFF);
2054 mhKeyDown(event.key.keysym.sym, event.key.keysym.unicode, event.key.keysym.mod);
2057 if (event.key.keysym.sym == SDLK_F11 || (event.key.keysym.sym == SDLK_RETURN && event.key.keysym.mod & KMOD_ALT))
2060 mhKeyUp(event.key.keysym.sym, event.key.keysym.unicode, event.key.keysym.mod);
2062 case SDL_MOUSEMOTION:
2064 #if defined(WIN32) || defined(__APPLE__)
2065 mhMouseMotion(event.motion.state, event.motion.x, event.motion.y, event.motion.xrel, event.motion.yrel);
2068 SDL_GetMouseState(&x, &y);
2069 if (x == event.motion.x && y == event.motion.y)
2070 mhMouseMotion(event.motion.state, event.motion.x, event.motion.y, event.motion.xrel, event.motion.yrel);
2074 case SDL_MOUSEBUTTONDOWN:
2077 case SDL_MOUSEBUTTONUP:
2081 switch (event.user.code)
2084 if (!PyObject_CallFunction((PyObject*)event.user.data1,
""))
2088 if (!PyObject_CallFunction((PyObject*)event.user.data1,
""))
2090 Py_DECREF((PyObject*)event.user.data1);
2094 case SDL_VIDEORESIZE:
2097 g_screen = SDL_SetVideoMode(
G.windowWidth,
G.windowHeight, 24, SDL_OPENGL | (
G.fullscreen ? SDL_FULLSCREEN : 0) | SDL_RESIZABLE);
2099 mhReshape(event.resize.w, event.resize.h);
2100 callResize(event.resize.w, event.resize.h,
G.fullscreen);
2103 case SDL_VIDEOEXPOSE:
2105 G.pendingUpdate = 0;
void mhCameraPosition(Camera *camera, int eye)
Set the camera zoom, position and orientation.
static int g_desktopHeight
void mhGetPickedColor(int x, int y)
Retrieve the 'selected' color index for the specified coordinates.
PyObject_HEAD GLuint textureId
void RegisterCamera(PyObject *module)
Registers the Camera object in the Python environment.
static PyObject * Camera_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Takes care of the initialization of the Camera object members.
void mhCreateWindow(int useTimer)
Create SDL window.
GLuint mhLoadTexture(const char *fname, GLuint texture, int *width, int *height)
Load a texture from a file and bind it into the textures array.
void callResize(int w, int h, int fullscreen)
void mhShutDown(void)
Shutdown the MakeHuman Application.
static void mhFlipSurface(SDL_Surface *surface)
Flip an SDL surface from top to bottom.
static unsigned char * pickingBuffer
void callMouseButtonUp(int b, int x, int y)
Invokes the Python mouseButtonUp function.
static SDL_Surface * g_screen
PyObject_HEAD float fovAngle
GLuint mhCreateShader(GLuint vertexShader, GLuint fragmentShader)
GLuint mhCreateFragmentShader(const char *source)
void mhDrawMeshes(int pickMode, int cameraType)
Draw all of the 3D objects held in the G.world array matching the 'pickMode' setting.
PyObject * Camera_convertToWorld2D(Camera *camera, PyObject *args)
Convert 2D (x, y) screen coordinates to OpenGL world coordinates.
static void Texture_dealloc(Texture *self)
Takes care of the deallocation of the OpenGL texture.
static PyMethodDef Texture_methods[]
void mhKeyUp(int key, unsigned short character, int modifiers)
static int pickingBufferSize
void mhKeyDown(int key, unsigned short character, int modifiers)
Pass a keydown event up to Python.
static int longCopyEndianSafe(uint32_t *destPtr, const uint32_t *srcPtr, size_t inLongs)
Copy one Array of long values (32 bits) to another location in memory by considering the endian corre...
PyObject * Camera_convertToScreen(Camera *camera, PyObject *args)
Convert 3D OpenGL world coordinates to screen coordinates.
void mhMouseMotion(int s, int x, int y, int xrel, int yrel)
Pass a mouse motion event up to Python and adjust current camera view.
SDL_Surface *(* PFN_IMG_LOAD)(const char *)
void mhDrawBegin(void)
Initialise the drawing space.
static PyMethodDef Camera_methods[]
static PyObject * Texture_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
Takes care of the initialization of the Texture object members.
void callKeyUp(int key, unsigned short character, int modifiers)
void mhMouseButtonUp(int b, int x, int y)
Pass a mouse button up event up to Python.
PyObject * Camera_convertToWorld3D(Camera *camera, PyObject *args)
Convert 3D (x, y, depth) screen coordinates to 3D OpenGL world coordinates.
static int Texture_init(Texture *self, PyObject *args, PyObject *kwds)
The constructor of the Texture object.
static void * g_sdlImageHandle
void OnInit(void)
Initialize lights and materials/textures.
void mhSetFullscreen(int fullscreen)
Set fullscreen mode.
static PFN_IMG_LOAD IMG_Load
void mhDraw(void)
Draw all visible 3D objects.
static int g_windowHeight
GLuint mhCreateVertexShader(const char *source)
void RegisterTexture(PyObject *module)
Registers the Texture object in the Python environment.
static PyMemberDef Texture_members[]
static uint32_t swapLong(uint32_t inValue)
Perform a byte swapping of a long value by reversing all bytes (e.g. 0x12345678 becomes 0x78563412)...
static int g_desktopWidth
void mhMouseButtonDown(int b, int x, int y)
Pass a mouse button down event up to Python.
void OnExit(void)
Delete materials/textures when the event loop exits.
void mhQueueUpdate(void)
Queue an update.
void callKeyDown(int key, unsigned short character, int modifiers)
Invokes the Python keyDown function.
void mhDrawEnd(void)
Swap buffers following a redraw.
void callMouseButtonDown(int b, int x, int y)
Invokes the Python mouseButtonDown function.
static int Camera_init(Camera *self, PyObject *args, PyObject *kwds)
The constructor of the Texture object.
static PyObject * Texture_loadImage(Texture *texture, PyObject *path)
void callMouseMotion(int s, int x, int y, int xrel, int yrel)
Invokes the Python mouseMotion function.
void UpdatePickingBuffer(void)
void mhEventLoop(void)
Start the event loop to manage the MakeHuman GUI.
static PyMemberDef Camera_members[]
int mhGrabScreen(int x, int y, int width, int height, const char *filename)
Capture a rectangular area from the screen into an image file.
PyTypeObject Object3DType
void mhReshape(int w, int h)
Redraw the contents of the window when the user resizes the window.
unsigned int mhTimerFunc(unsigned int interval, void *param)
Pass a timer callback event up to Python.