GLuint ShaderProgramBuilder::loadShaderProgram(GLenum shaderType, const char * pSource) { GLuint shader = glCreateShader(shaderType); GL_ERROR_CHECK("ShaderProgramBuilder:Create Shader"); if (shader) { glShaderSource(shader, 1, &pSource, NULL); glCompileShader(shader); GLint compiled = 0; glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); if (!compiled) { GLint infoLen = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen) { GL_ERROR_CHECK("ShaderProgramBuilder:Failed on Compile Shader"); char* buf = new char[infoLen]; if (buf) { glGetShaderInfoLog(shader, infoLen, NULL, buf); LOG_ERROR("Could not compile shader %d:\n%s\n", shaderType, buf); delete buf; } glDeleteShader(shader); shader = 0; } } } else { LOG_ERROR("Create shader error!\n"); } return shader; }
static PyObject* opengl_startdraw( PyObject* self, PyObject* args ) { PyObject* clear_color; query_object = NULL; GL_ERROR_CHECK( "top of opengl_startdraw" ); if ( !PyArg_ParseTuple( args, "O|O", &clear_color, &query_object ) ) return NULL; if ( query_object ) { if ( !PyTuple_Check( query_object ) || PyTuple_GET_SIZE(query_object) % 2 != 0 ) { PyErr_SetString( PyExc_ValueError, "bad query object" ); return NULL; } } if ( PyTuple_Check( clear_color ) && PyTuple_Size( clear_color ) == 4 ) { glClearColor( (float)PyFloat_AsDouble( PyTuple_GetItem( clear_color, 0 ) ), (float)PyFloat_AsDouble( PyTuple_GetItem( clear_color, 1 ) ), (float)PyFloat_AsDouble( PyTuple_GetItem( clear_color, 2 ) ), 0.0 ); } else glClearColor( 1.0, 1.0, 1.0, 0.0 ); glClearStencil( 0 ); glDisable( GL_STENCIL_TEST ); glClearDepth( 0.0 ); glDepthMask( GL_TRUE ); glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); glColor4d( 0.0, 0.0, 0.0, 1.0 ); glLineWidth( 1.0 ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); /* left, right, bottom, top, zNear, zFar (in distance from eye) */ glOrtho( -window_aspect, window_aspect, -1.0, 1.0, 0.0, 1.0 ); glPushMatrix(); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glReadBuffer( GL_BACK ); GL_ERROR_CHECK( "after opengl_redraw setup" ); Py_INCREF( Py_None ); return Py_None; }
static void free_old_textures( void ) { GL_ERROR_CHECK( "top of free_old" ); if ( old_textures_used > 0 ) { glDeleteTextures( old_textures_used, old_textures ); old_textures_used = 0; } GL_ERROR_CHECK( "bottom of free_old" ); }
static int make_texture( ImageObject* obj ) { int bound = 0; free_old_textures(); if ( obj->has_texture == 0 ) { GLuint t; glGenTextures( 1, &t ); glBindTexture( GL_TEXTURE_2D, t ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexImage2D( GL_TEXTURE_2D, 0, obj->has_alpha ? GL_RGBA : GL_RGB, obj->tw, obj->th, 0, obj->has_alpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, obj->data ); GL_ERROR_CHECK( "draw_image - created texture" ); obj->texture = t; obj->has_texture = 1; bound = 1; free( obj->data ); obj->data = NULL; } return bound; }
void UBOShaderInterface::Create(const std::string &uniformBlockName, Shader* shader, const char** uniformNames, GLsizei numUniformNames) { m_pShader = shader; m_blockIndex = glGetUniformBlockIndex(m_pShader->GetProgID(), uniformBlockName.c_str()); assert(m_blockIndex != GL_INVALID_INDEX); glGetActiveUniformBlockiv(m_pShader->GetProgID(), m_blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &m_blockSize); GLuint* indices = new GLuint[numUniformNames]; glGetUniformIndices(m_pShader->GetProgID(), numUniformNames, uniformNames, indices); // Query offsets and associate names to the offsets int* offsets = new int[numUniformNames]; glGetActiveUniformsiv(m_pShader->GetProgID(), numUniformNames, indices, GL_UNIFORM_OFFSET, offsets); delete[] indices; for(size_t i = 0; i < numUniformNames; i++) m_uniformNameToOffset[uniformNames[i]] = offsets[i]; delete[] offsets; GL_ERROR_CHECK(); }
void NormalWrapper::setup() { shaderProgram = loadShaderProgram("assets/shaders/normal.vert", "assets/shaders/normal.frag", { "in_pos", "in_color" }); float posColorVertices[]{ -0.25f, -0.25f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.25f, -0.25f, 0.f, 0.f, 0.f, 1.f, 1.f, -0.25f, 0.25f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.25f, 0.25f, 0.f, 0.f, 0.f, 1.f, 1.f }; constexpr size_t vertexSize = sizeof(float) * 7; constexpr uint8_t vertexCount = 4; mesh.renderMode = GL_TRIANGLE_STRIP; glGenVertexArrays(1, &mesh.vao); glBindVertexArray(mesh.vao); glGenBuffers(1, &mesh.vbo); glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo); glBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, &posColorVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertexSize, 0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, vertexSize, reinterpret_cast<const void*>(12)); mesh.vertexCount = vertexCount; glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); GL_ERROR_CHECK(); }
void CreateRenderTarget(int width, int height) { printf("Render Target size %d x %d\n", width, height); // create a fbo glGenFramebuffers(1, &s_fbo); GL_ERROR_CHECK("RenderTargetInit1"); // create a depth buffer glGenRenderbuffers(1, &s_fboDepth); GL_ERROR_CHECK("RenderTargetInit2"); // bind fbo glBindFramebuffer(GL_FRAMEBUFFER, s_fbo); GL_ERROR_CHECK("RenderTargetInit3"); glGenTextures(1, &s_fboTex); glBindTexture(GL_TEXTURE_2D, s_fboTex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); // attach texture to fbo glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, s_fboTex, 0); // init depth buffer glBindRenderbuffer(GL_RENDERBUFFER, s_fboDepth); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, s_fboDepth); // check status assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); GL_ERROR_CHECK("RenderTargetInit"); }
GLuint ShaderProgramBuilder::buildShaderProgram(const char * pVertexSource, const char * pFragmentSource) { GLuint vertexShader = loadShaderProgram(VERTEX_SHADER, pVertexSource); if (!vertexShader) return false; LOG_INFO("Render=> Pass Build Vertex Shader\n"); GLuint pixelShader = loadShaderProgram(FRAGMENT_SHADER, pFragmentSource); if (!pixelShader) return false; LOG_INFO("Render=> Pass Build Fragment Shader\n"); GLuint program = glCreateProgram(); GL_ERROR_CHECK("ShaderProgramBuilder:Create Program"); if (program) { glAttachShader(program, vertexShader); glAttachShader(program, pixelShader); GL_ERROR_CHECK("ShaderProgramBuilder:Attach Program"); glLinkProgram(program); GL_ERROR_CHECK("ShaderProgramBuilder:Link Program"); GLint linkStatus = GL_FALSE; glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); if (linkStatus != GL_TRUE) { GLint bufLength = 0; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); if (bufLength) { char* buf = new char[bufLength]; if (buf) { glGetProgramInfoLog(program, bufLength, NULL, buf); LOG_ERROR("Could not link program:\n%s\n", buf); delete buf; } } glDeleteProgram(program); program = 0; } } return program; }
void VertexArrayObject::disableVertexAttribArray(GLuint index) { glDisableVertexAttribArray(index); std::vector<GLuint>::iterator ind = std::find( mImpl->vertexArrays.begin(), mImpl->vertexArrays.end(), index); mImpl->vertexArrays.erase(ind); GL_ERROR_CHECK(); }
void VertexArrayObject::enableVertexAttribArray(GLuint index) { std::vector<GLuint>::iterator ind = std::find( mImpl->vertexArrays.begin(), mImpl->vertexArrays.end(), index); if (ind != mImpl->vertexArrays.end()) { WARN_LOG("The vertex attribute array at index " + std::to_string(index) + " has already been bound"); return; } glEnableVertexAttribArray(index); mImpl->vertexArrays.push_back(index); GL_ERROR_CHECK(); }
static PyObject* opengl_reshape( PyObject* self, PyObject* args ) { if ( !PyArg_ParseTuple( args, "ii", &window_width, &window_height ) ) return NULL; window_aspect = window_width / (double)window_height; glViewport( 0, 0, window_width, window_height ); GL_ERROR_CHECK( "glViewport" ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); Py_INCREF( Py_None ); return Py_None; }
void InstanceWrapper::setup() { shaderProgram = loadShaderProgram("assets/shaders/instanced.vert", "assets/shaders/instanced.frag", { "in_sPos", "in_pos" }); float posVertices[]{ -0.25f, -0.25f, 0.f, 0.25f, -0.25f, 0.f, -0.25f, 0.25f, 0.f, 0.25f, 0.25f, 0.f }; constexpr size_t vertexSize = sizeof(float) * 3; constexpr uint8_t vertexCount = 4; mesh.renderMode = GL_TRIANGLE_STRIP; glGenVertexArrays(1, &mesh.vao); glBindVertexArray(mesh.vao); // Instanced constexpr size_t instanceSize = sizeof(float) * 3; glGenBuffers(1, &mesh.instanceVBO); glBindBuffer(GL_ARRAY_BUFFER, mesh.instanceVBO); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, instanceSize, 0); glVertexAttribDivisor(0, 1); // Normal glGenBuffers(1, &mesh.vbo); glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo); glBufferData(GL_ARRAY_BUFFER, vertexCount * vertexSize, &posVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertexSize, 0); mesh.vertexCount = vertexCount; glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); GL_ERROR_CHECK(); }
GLuint loadShaderProgram(const std::string& vsPath, const std::string& fsPath, const std::vector<std::string>& attributes) { GLuint vsID = glCreateShader(GL_VERTEX_SHADER); GLuint fsID = glCreateShader(GL_FRAGMENT_SHADER); // Compile Vertex Shader std::string source = readAsString(vsPath); char const* vsSource = source.c_str(); glShaderSource(vsID, 1, &vsSource, nullptr); glCompileShader(vsID); Logger::shaderErrorCheck(vsID, vsPath); // Compile Fragment Shader source = readAsString(fsPath); char const* fsSource = source.c_str(); glShaderSource(fsID, 1, &fsSource, nullptr); glCompileShader(fsID); Logger::shaderErrorCheck(fsID, fsPath); GLuint programID = glCreateProgram(); glAttachShader(programID, vsID); glAttachShader(programID, fsID); GLuint index = 0; for (auto& attribute : attributes) glBindAttribLocation(programID, index++, attribute.c_str()); glLinkProgram(programID); Logger::programErrorCheck(programID, vsPath, fsPath); glDeleteShader(vsID); glDeleteShader(fsID); GL_ERROR_CHECK(); return programID; }
static void draw_image( ImageObject* obj, double x, double y, double w, double h, double ax, double ay ) { GL_ERROR_CHECK( "top of draw_image" ); // would like to save GL_TEXTURE_BIT as well, but it tweaks a bug in // ATI's radeon 7500 drivers. glPushAttrib( GL_ENABLE_BIT | GL_TRANSFORM_BIT ); glEnable( GL_TEXTURE_2D ); if ( ! make_texture( obj ) ) glBindTexture( GL_TEXTURE_2D, obj->texture ); glMatrixMode( GL_MODELVIEW ); glPushMatrix(); glTranslated( x - w * ax, y - h * ay, 0 ); glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); glBegin( GL_QUADS ); glTexCoord2d( 0.0, obj->tbottom ); glVertex2d( 0, 0 ); glTexCoord2d( obj->tright, obj->tbottom ); glVertex2d( w, 0 ); glTexCoord2d( obj->tright, 0.0 ); glVertex2d( w, h ); glTexCoord2d( 0.0, 0.0 ); glVertex2d( 0, h ); glEnd(); glPopMatrix(); glPopAttrib(); }
void draw(Widget w) { GLfloat red, green, blue; int i; glClear(GL_DEPTH_BUFFER_BIT); /* paint black to blue smooth shaded polygon for background */ glDisable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); glBegin(GL_POLYGON); glColor3f(1.0, 1.0, 1.0); glVertex3f(-20, 20, -19); glVertex3f(20, 20, -19); glColor3f(0.0, 0.0, 1.0); glVertex3f(20, -20, -19); glVertex3f(-20, -20, -19); glEnd(); glEnable(GL_DEPTH_TEST); glShadeModel(GL_FLAT); glPushMatrix(); glTranslatef(0, 0, -distance); glRotatef(angle, 0, 0, 1); glRotatef(wobble_angle, 0, 1, 0); glCallList(base); glPopMatrix(); if (doubleBuffer) glXSwapBuffers(dpy, XtWindow(w)); if (!glXIsDirect(dpy, cx)) glFinish(); /* avoid indirect rendering latency from * queuing */ GL_ERROR_CHECK(); }
void VertexArrayObject::bindVertexArray() { glBindVertexArray(mImpl->handle); GL_ERROR_CHECK(); }
static PyObject* opengl_init( PyObject* self, PyObject* args ) { GL_ERROR_CHECK("top of opengl_init"); printf( " vendor : %s\n", glGetString( GL_VENDOR ) ); printf( " renderer : %s\n", glGetString( GL_RENDERER ) ); printf( " version : %s\n", glGetString( GL_VERSION ) ); printf( "glu version : %s\n", gluGetString( GLU_VERSION ) ); /*printf( "extensions : %s\n", glGetString( GL_EXTENSIONS ) );*/ glewExperimental=GL_TRUE; GLenum err = glewInit(); if (GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ printf("Error: %s\n", glewGetErrorString(err)); } printf("Status: Using GLEW %s\n", glewGetString(GLEW_VERSION)); if (glewIsSupported("GLX_SGI_swap_control")) { /* It is safe to use the ARB_vertex_program extension here. */ printf("GLX_SGI_swap_control supported!\n"); //glXSwapIntervalSGI(1); } else { printf("No GLX_SGI_swap_control support.\n"); } if (glewIsSupported("GLX_SGI_video_sync")) { /* It is safe to use the ARB_vertex_program extension here. */ printf("GLX_SGI_video_sync supported!\n"); //glXSwapIntervalSGI(1); int retraceCount; glXGetVideoSyncSGI(&retraceCount); glXWaitVideoSyncSGI(2, (retraceCount+1)%2, &retraceCount); } else { printf("GLX_SGI_video_sync support.\n"); int c; //__glewXWaitVideoSyncSGI(5,0,&c); } glEnable( GL_VERTEX_ARRAY ); /* on mac, we expect that to fail; must be enabled as client state instead, */ if(glGetError() != GL_NO_ERROR) { glEnableClientState( GL_VERTEX_ARRAY ); GL_ERROR_CHECK( "enable client gl_vertex_array" ); } glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glEnable( GL_DEPTH_TEST ); glDepthFunc( GL_ALWAYS ); glClearDepth( 0.0 ); GL_ERROR_CHECK( "end of opengl_init" ); //glEnable( GL_POLYGON_SMOOTH ); Py_INCREF( Py_None ); return Py_None; }
World::World() : m_created(false), m_lightVec(0.4f, -0.5f, -0.7f), m_ambient(0.1f), m_pPhysicsWorld(NULL), m_pathFindingThreadPool(8), m_AOSampleDistance(6.0f), m_AOSampleAngle(pif / s_numAOSamples) { m_lightVec = m_lightVec.Normalize(); // Generate normals m_normals[0] = Vec3f(1.0f, 0.0f, 0.0f); m_normals[1] = Vec3f(-1.0f, 0.0f, 0.0f); m_normals[2] = Vec3f(0.0f, 1.0f, 0.0f); m_normals[3] = Vec3f(0.0f, -1.0f, 0.0f); m_normals[4] = Vec3f(0.0f, 0.0f, 1.0f); m_normals[5] = Vec3f(0.0f, 0.0f, -1.0f); // Generate test offsets m_positionOffsets[0] = Point3i(1, 0, 0); m_positionOffsets[1] = Point3i(-1, 0, 0); m_positionOffsets[2] = Point3i(0, 1, 0); m_positionOffsets[3] = Point3i(0, -1, 0); m_positionOffsets[4] = Point3i(0, 0, 1); m_positionOffsets[5] = Point3i(0, 0, -1); // Generate corners float cornerDist = 0.5f; m_corners[0][0] = Vec3f(cornerDist, -cornerDist, cornerDist); m_corners[0][1] = Vec3f(cornerDist, -cornerDist, -cornerDist); m_corners[0][2] = Vec3f(cornerDist, cornerDist, -cornerDist); m_corners[0][3] = Vec3f(cornerDist, cornerDist, cornerDist); m_corners[1][0] = Vec3f(-cornerDist, -cornerDist, -cornerDist); m_corners[1][1] = Vec3f(-cornerDist, -cornerDist, cornerDist); m_corners[1][2] = Vec3f(-cornerDist, cornerDist, cornerDist); m_corners[1][3] = Vec3f(-cornerDist, cornerDist, -cornerDist); m_corners[2][0] = Vec3f(-cornerDist, cornerDist, -cornerDist); m_corners[2][1] = Vec3f(-cornerDist, cornerDist, cornerDist); m_corners[2][2] = Vec3f(cornerDist, cornerDist, cornerDist); m_corners[2][3] = Vec3f(cornerDist, cornerDist, -cornerDist); m_corners[3][0] = Vec3f(-cornerDist, -cornerDist, cornerDist); m_corners[3][1] = Vec3f(-cornerDist, -cornerDist, -cornerDist); m_corners[3][2] = Vec3f(cornerDist, -cornerDist, -cornerDist); m_corners[3][3] = Vec3f(cornerDist, -cornerDist, cornerDist); m_corners[4][0] = Vec3f(-cornerDist, -cornerDist, cornerDist); m_corners[4][1] = Vec3f(cornerDist, -cornerDist, cornerDist); m_corners[4][2] = Vec3f(cornerDist, cornerDist, cornerDist); m_corners[4][3] = Vec3f(-cornerDist, cornerDist, cornerDist); m_corners[5][0] = Vec3f(cornerDist, -cornerDist, -cornerDist); m_corners[5][1] = Vec3f(-cornerDist, -cornerDist, -cornerDist); m_corners[5][2] = Vec3f(-cornerDist, cornerDist, -cornerDist); m_corners[5][3] = Vec3f(cornerDist, cornerDist, -cornerDist); // Generate chunk occlusion query glGenQueriesARB(1, &m_chunkOcclusionQueryID); GL_ERROR_CHECK(); m_unmanagedName = "world"; GetSphereDistribution(m_sphereDistribution); }
static PyObject* opengl_enddraw( PyObject* self, PyObject* args ) { char* filename = NULL; if ( !PyArg_ParseTuple( args, "|s", &filename ) ) return NULL; GL_ERROR_CHECK( "top of opengl_enddraw" ); #if 0 { GLfloat d; glReadPixels( 400, 300, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &d ); printf( "-- enddraw %.16f\n", d ); } #endif glMatrixMode( GL_PROJECTION ); glPopMatrix(); if ( query_object ) { PyObject* result; int n = PyTuple_GET_SIZE( query_object ); int i, x, y; GLfloat d; GLint depth_bits; unsigned int id; glGetIntegerv( GL_DEPTH_BITS, &depth_bits ); result = PyTuple_New( n / 2 ); for( i = 0; i < n/2; ++i ) { x = PyInt_AsLong( PyTuple_GET_ITEM( query_object, i*2 ) ); y = PyInt_AsLong( PyTuple_GET_ITEM( query_object, i*2+1 ) ); glReadPixels( x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &d ); id = (unsigned int)(d * (1<<(depth_bits-2))); PyTuple_SET_ITEM( result, i, PyInt_FromLong(id) ); } GL_ERROR_CHECK( "another end to opengl_enddraw" ); return result; } SoggySwap(); if ( filename ) { static PyObject* module; PyObject* im; PyObject* ret; PyObject* data; fprintf( stderr, "saving to [%s]\n", filename ); if ( module == NULL ) { PyObject* name = PyString_FromString( "Image" ); module = PyImport_Import( name ); Py_DECREF( name ); if ( module == NULL ) { PyErr_SetString( PyExc_ImportError, "failed to find PIL module" ); return NULL; } } data = PyString_FromStringAndSize( NULL, window_width * window_height * 3 ); glPixelStorei( GL_PACK_ALIGNMENT, 1 ); glReadBuffer( GL_FRONT ); glReadPixels( 0, 0, window_width, window_height, GL_RGB, GL_UNSIGNED_BYTE, PyString_AsString( data ) ); GL_ERROR_CHECK( "after glReadPixels" ); im = PyObject_CallMethod( module, "fromstring", "s(ii)Ossii", "RGB", window_width, window_height, data, "raw", "RGB", 0, -1 ); ret = PyObject_CallMethod( im, "save", "s", filename ); Py_XDECREF( ret ); Py_XDECREF( im ); Py_XDECREF( data ); } GL_ERROR_CHECK( "an end to opengl_enddraw" ); Py_INCREF( Py_None ); return Py_None; }
void ShaderProgramBuilder::useShaderProgram(GLuint program) { LOG_INFO("Render=> Use GL program %d\n", program); glUseProgram( program); GL_ERROR_CHECK("ShaderProgramBuilder:use GL program"); }