GLSprite::GLSprite(const GLTexture &tex, int width, int height, float tx, float ty, float tw, float th) : tex(tex), width(width), height(height), data() { data[2] = width; data[3] = height; setTexCoords(tx, ty, tw, th); }
void CGLCG::Render(GLuint &origTex, xySize textureSize, xySize inputSize, xySize viewportSize, xySize windowSize) { GLenum error; frameCnt++; CGprofile vertexProfile, fragmentProfile; if(!shaderLoaded) return; vertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX); fragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT); cgGLEnableProfile(vertexProfile); cgGLEnableProfile(fragmentProfile); /* set up our dummy pass for easier loop code */ shaderPasses[0].tex = origTex; shaderPasses[0].outputSize = inputSize; shaderPasses[0].textureSize = textureSize; /* loop through all real passes */ for(int i=1;i<shaderPasses.size();i++) { switch(shaderPasses[i].scaleParams.scaleTypeX) { case CG_SCALE_ABSOLUTE: shaderPasses[i].outputSize.x = (double)shaderPasses[i].scaleParams.absX; break; case CG_SCALE_SOURCE: shaderPasses[i].outputSize.x = shaderPasses[i-1].outputSize.x * shaderPasses[i].scaleParams.scaleX; break; case CG_SCALE_VIEWPORT: shaderPasses[i].outputSize.x = viewportSize.x * shaderPasses[i].scaleParams.scaleX; break; default: shaderPasses[i].outputSize.x = viewportSize.x; } switch(shaderPasses[i].scaleParams.scaleTypeY) { case CG_SCALE_ABSOLUTE: shaderPasses[i].outputSize.y = (double)shaderPasses[i].scaleParams.absY; break; case CG_SCALE_SOURCE: shaderPasses[i].outputSize.y = shaderPasses[i-1].outputSize.y * shaderPasses[i].scaleParams.scaleY; break; case CG_SCALE_VIEWPORT: shaderPasses[i].outputSize.y = viewportSize.y * shaderPasses[i].scaleParams.scaleY; break; default: shaderPasses[i].outputSize.y = viewportSize.y; } /* use next power of two in both directions */ float texSize = npot(max(shaderPasses[i].outputSize.x,shaderPasses[i].outputSize.y)); shaderPasses[i].textureSize.x = shaderPasses[i].textureSize.y = texSize; /* set size of output texture */ glBindTexture(GL_TEXTURE_2D,shaderPasses[i].tex); glTexImage2D(GL_TEXTURE_2D,0,(shaderPasses[i].floatFbo?GL_RGBA32F:GL_RGBA),(unsigned int)shaderPasses[i].textureSize.x, (unsigned int)shaderPasses[i].textureSize.y,0,GL_RGBA,GL_UNSIGNED_INT_8_8_8_8,NULL); /* viewport determines the area we render into the output texture */ glViewport(0,0,shaderPasses[i].outputSize.x,shaderPasses[i].outputSize.y); /* set up framebuffer and attach output texture */ glBindFramebuffer(GL_FRAMEBUFFER,shaderPasses[i].fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, shaderPasses[i].tex, 0); /* set up input texture (output of previous pass) and apply filter settings */ glBindTexture(GL_TEXTURE_2D,shaderPasses[i-1].tex); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)shaderPasses[i-1].textureSize.x); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shaderPasses[i].linearFilter?GL_LINEAR:GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, shaderPasses[i].linearFilter?GL_LINEAR:GL_NEAREST); /* calculate tex coords first since we pass them to the shader */ setTexCoords(i,shaderPasses[i-1].outputSize,shaderPasses[i-1].textureSize); setShaderVars(i); cgGLBindProgram(shaderPasses[i].cgVertexProgram); cgGLBindProgram(shaderPasses[i].cgFragmentProgram); glClearColor(0.0f, 0.0f, 0.0f, 0.5f); glClear(GL_COLOR_BUFFER_BIT); glDrawArrays (GL_QUADS, 0, 4); /* reset client states enabled during setShaderVars */ resetAttribParams(); } /* disable framebuffer */ glBindFramebuffer(GL_FRAMEBUFFER,0); /* set last PREV texture as original, push current texture and sizes to the front of the PREV deque and make sure the new original texture has the same size as the old one */ origTex = prevPasses.back().tex; prevPasses.pop_back(); prevPass pass; pass.videoSize = inputSize; pass.textureSize = textureSize; pass.tex = shaderPasses[0].tex; memcpy(pass.texCoords,shaderPasses[1].texcoords,sizeof(pass.texCoords)); prevPasses.push_front(pass); glBindTexture(GL_TEXTURE_2D,origTex); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,textureSize.x,textureSize.y,0,GL_RGB,GL_UNSIGNED_SHORT_5_6_5,NULL); /* bind output of last pass to be rendered on the backbuffer */ glBindTexture(GL_TEXTURE_2D,shaderPasses.back().tex); glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)shaderPasses.back().textureSize.x); /* calculate and apply viewport and texture coordinates to that will be used in the main ogl code */ RECT displayRect=CalculateDisplayRect(shaderPasses.back().outputSize.x,shaderPasses.back().outputSize.y,windowSize.x,windowSize.y); glViewport(displayRect.left,windowSize.y-displayRect.bottom,displayRect.right-displayRect.left,displayRect.bottom-displayRect.top); setTexCoords(shaderPasses.size()-1,shaderPasses.back().outputSize,shaderPasses.back().textureSize,true); /* render to backbuffer without shaders */ cgGLDisableProfile(vertexProfile); cgGLDisableProfile(fragmentProfile); }
//////////////////////////////////////////////////////// // render // ///////////////////////////////////////////////////////// void pix_texture :: render(GemState *state) { m_didTexture=false; pushTexCoords(state); if(!m_textureOnOff)return; if(!state)return; bool upsidedown=false; bool normalized=true; int texType = m_textureType; int x_2=1, y_2=1; bool useExternalTexture=false; int do_rectangle = (m_rectangle)?m_canRectangle:0; int newfilm = 0; pixBlock*img=NULL; state->get(GemState::_PIX, img); if(img) newfilm = img->newfilm; if (!img || !img->image.data){ if(m_extTextureObj>0) { useExternalTexture= true; m_rebuildList = false; m_textureObj = m_extTextureObj; if(m_extType)m_textureType=m_extType; texType=m_textureType; upsidedown=m_extUpsidedown; m_xRatio=m_extWidth; m_yRatio=m_extHeight; m_upsidedown=upsidedown; } else /* neither do we have an image nor an external texture */ return; } tex2state(state, m_coords, 4); if(!useExternalTexture){ upsidedown = img->image.upsidedown; if (img->newimage) m_rebuildList = true; m_imagebuf.xsize =img->image.xsize; m_imagebuf.ysize =img->image.ysize; m_imagebuf.csize =img->image.csize; m_imagebuf.format=img->image.format; m_imagebuf.type =img->image.type; m_imagebuf.data =img->image.data; x_2 = powerOfTwo(m_imagebuf.xsize); y_2 = powerOfTwo(m_imagebuf.ysize); normalized = ((m_imagebuf.xsize==x_2) && (m_imagebuf.ysize==y_2)); debug("normalized=%d\t%d - %d\t%d - %d", normalized, m_imagebuf.xsize, x_2, m_imagebuf.ysize, y_2); switch(do_rectangle) { case 2: m_textureType = GL_TEXTURE_RECTANGLE_ARB; debug("using mode 1:GL_TEXTURE_RECTANGLE_ARB"); normalized = 0; break; case 1: m_textureType = GL_TEXTURE_RECTANGLE_EXT; debug("using mode 1:GL_TEXTURE_RECTANGLE_EXT"); normalized = 0; break; default: m_textureType = GL_TEXTURE_2D; debug("using mode 0:GL_TEXTURE_2D"); normalized = 0; break; } debug("normalized=%d", normalized); } if (m_textureType!=texType){ debug("texType != m_textureType"); stopRendering();startRendering(); } if(GLEW_VERSION_1_3) { glActiveTexture(GL_TEXTURE0_ARB + m_texunit); } glEnable(m_textureType); glBindTexture(m_textureType, m_textureObj); if(useExternalTexture) { glTexParameterf(m_textureType, GL_TEXTURE_MAG_FILTER, m_textureQuality); glTexParameterf(m_textureType, GL_TEXTURE_MIN_FILTER, m_textureQuality); } if ((!useExternalTexture)&&newfilm ){ // tigital: shouldn't we also allow TEXTURE_2D here? if(NULL!=glTextureRangeAPPLE) { if ( GLEW_APPLE_texture_range ){ if(glTextureRangeAPPLE == NULL) { glTextureRangeAPPLE( m_textureType, m_imagebuf.xsize * m_imagebuf.ysize * m_imagebuf.csize, m_imagebuf.data ); debug("using glTextureRangeAPPLE()"); }else{ glTextureRangeAPPLE( m_textureType, 0, NULL ); } } } /* hmm, GL_TEXTURE_STORAGE_HINT_APPLE throws a GL-error on linux (and probably on w32 too) * how to do a run-time check for it? * * according to http://developer.apple.com/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_texturedata/chapter_10_section_2.html * this seems to be a part of the texture_range extension, so we check for that! */ if(GLEW_APPLE_texture_range) glTexParameteri( m_textureType, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_SHARED_APPLE ); // GL_STORAGE_SHARED_APPLE - AGP texture path // GL_STORAGE_CACHED_APPLE - VRAM texture path // GL_STORAGE_PRIVATE_APPLE - normal texture path if(m_clientStorage) glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); } /* here comes the work: a new image has to be transfered from main memory to GPU and attached to a texture object */ if (m_rebuildList) { // if YUV is not supported on this platform, we have to convert it to RGB //(skip Alpha since it isnt used) const bool do_yuv = m_yuv && GLEW_APPLE_ycbcr_422; if (!do_yuv && m_imagebuf.format == GL_YUV422_GEM){ m_imagebuf.format=GL_RGB; m_imagebuf.csize=3; m_imagebuf.reallocate(); m_imagebuf.fromYUV422(img->image.data); } if (normalized) { m_buffer.xsize = m_imagebuf.xsize; m_buffer.ysize = m_imagebuf.ysize; m_buffer.csize = m_imagebuf.csize; m_buffer.format = m_imagebuf.format; m_buffer.type = m_imagebuf.type; m_buffer.reallocate(); m_xRatio=1.0; m_yRatio=1.0; m_upsidedown=upsidedown; tex2state(state, m_coords, 4); if (m_buffer.csize != m_dataSize[0] || m_buffer.xsize != m_dataSize[1] || m_buffer.ysize != m_dataSize[2]){ m_dataSize[0] = m_buffer.csize; m_dataSize[1] = m_buffer.xsize; m_dataSize[2] = m_buffer.ysize; } //if the texture is a power of two in size then there is no need to subtexture glTexImage2D(m_textureType, 0, m_imagebuf.csize, m_imagebuf.xsize, m_imagebuf.ysize, 0, m_imagebuf.format, m_imagebuf.type, m_imagebuf.data); } else { // !normalized m_xRatio = (float)m_imagebuf.xsize; m_yRatio = (float)m_imagebuf.ysize; if ( !do_rectangle ) { m_xRatio /= (float)x_2; m_yRatio /= (float)y_2; m_buffer.xsize = x_2; m_buffer.ysize = y_2; } else { m_buffer.xsize = m_imagebuf.xsize; m_buffer.ysize = m_imagebuf.ysize; } m_buffer.csize = m_imagebuf.csize; m_buffer.format = m_imagebuf.format; m_buffer.type = m_imagebuf.type; m_buffer.reallocate(); m_upsidedown=upsidedown; tex2state(state, m_coords, 4); if (m_buffer.csize != m_dataSize[0] || m_buffer.xsize != m_dataSize[1] || m_buffer.ysize != m_dataSize[2]){ newfilm = 1; } //end of loop if size has changed // okay, load in the actual pixel data //when doing rectangle textures the buffer changes after every film is loaded this call makes sure the //texturing is updated as well to prevent crashes if(newfilm) { m_dataSize[0] = m_buffer.csize; m_dataSize[1] = m_buffer.xsize; m_dataSize[2] = m_buffer.ysize; if (m_buffer.format == GL_YUV422_GEM && !m_rectangle)m_buffer.setBlack(); if(m_numPbo>0) { if(GLEW_ARB_pixel_buffer_object) { if(m_pbo) { delete[]m_pbo; m_pbo=NULL; } m_pbo=new GLuint[m_numPbo]; glGenBuffersARB(m_numPbo, m_pbo); int i=0; for(i=0; i<m_numPbo; i++) { glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_pbo[i]); glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_buffer.xsize*m_buffer.ysize*m_buffer.csize, 0, GL_STREAM_DRAW_ARB); } glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); } else { verbose(1, "PBOs not supported! disabling"); m_numPbo=0; } } //this is for dealing with power of 2 textures which need a buffer that's 2^n if ( !do_rectangle ) { glTexImage2D( m_textureType, 0, //m_buffer.csize, GL_RGBA, m_buffer.xsize, m_buffer.ysize, 0, m_buffer.format, m_buffer.type, m_buffer.data); debug("TexImage2D non rectangle"); } else {//this deals with rectangle textures that are h*w glTexImage2D(m_textureType, 0, // m_buffer.csize, GL_RGBA, m_imagebuf.xsize, m_imagebuf.ysize, 0, m_imagebuf.format, m_imagebuf.type, m_imagebuf.data); debug("TexImage2D rectangle"); } // just to make sure... img->newfilm = 0; } if(m_pbo) { m_curPbo=(m_curPbo+1)%m_numPbo; int index=m_curPbo; int nextIndex=(m_curPbo+1)%m_numPbo; glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_pbo[index]); glTexSubImage2D(m_textureType, 0, 0, 0, m_imagebuf.xsize, m_imagebuf.ysize, m_imagebuf.format, m_imagebuf.type, NULL); /* <-- that's the key */ glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_pbo[nextIndex]); glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, m_imagebuf.xsize * m_imagebuf.ysize * m_imagebuf.csize, 0, GL_STREAM_DRAW_ARB); GLubyte* ptr = (GLubyte*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB); if(ptr) { // update data off the mapped buffer memcpy(ptr, m_imagebuf.data, m_imagebuf.xsize * m_imagebuf.ysize * m_imagebuf.csize); glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); // release pointer to mapping buffer } /* unbind the current buffer */ glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); } else { glTexSubImage2D(m_textureType, 0, 0, 0, // position m_imagebuf.xsize, m_imagebuf.ysize, m_imagebuf.format, m_imagebuf.type, m_imagebuf.data); } } } // rebuildlist setTexCoords(m_coords, m_xRatio, m_yRatio, m_upsidedown); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, m_env); /* cleanup */ m_rebuildList = false; m_didTexture=true; state->set(GemState::_GL_TEX_UNITS, m_numTexUnits); // if we are using rectangle textures, this is a way to inform the downstream objects // (this is important for things like [pix_coordinate] // we don't use switch/case as _ARB and _EXT might be the same... if(m_textureType==GL_TEXTURE_RECTANGLE_ARB || m_textureType==GL_TEXTURE_RECTANGLE_EXT) { state->set(GemState::_GL_TEX_TYPE, 2); } else { state->set(GemState::_GL_TEX_TYPE, 1); } m_baseCoord.s=m_xRatio; m_baseCoord.t=m_yRatio; state->set(GemState::_GL_TEX_BASECOORD, m_baseCoord); state->set(GemState::_GL_TEX_ORIENTATION, upsidedown); sendExtTexture(m_textureObj, m_xRatio, m_yRatio, m_textureType, upsidedown); }
void SkeletonBlendedGeometry::changed(ConstFieldMaskArg whichField, UInt32 origin, BitVector details) { Inherited::changed(whichField, origin, details); //Do not respond to changes that have a Sync origin if(origin & ChangedOrigin::Sync) { return; } if((whichField & BaseGeometryFieldMask) && getBaseGeometry() != NULL) { if(getBaseGeometry()->getTypes() != NULL) { setTypes(getBaseGeometry()->getTypes()); } if(getBaseGeometry()->getLengths() != NULL) { setLengths(getBaseGeometry()->getLengths()); } if(getBaseGeometry()->getPositions() != NULL) { GeoPropertyUnrecPtr Pos(getBaseGeometry()->getPositions()->clone()); setPositions(dynamic_pointer_cast<GeoVectorProperty>(Pos)); } if(getBaseGeometry()->getNormals() != NULL) { GeoPropertyUnrecPtr Norm(getBaseGeometry()->getNormals()->clone()); setNormals(dynamic_pointer_cast<GeoVectorProperty>(Norm)); } if(getBaseGeometry()->getColors() != NULL) { setColors(getBaseGeometry()->getColors()); } if(getBaseGeometry()->getSecondaryColors() != NULL) { setSecondaryColors(getBaseGeometry()->getSecondaryColors()); } if(getBaseGeometry()->getTexCoords() != NULL) { setTexCoords(getBaseGeometry()->getTexCoords()); } if(getBaseGeometry()->getTexCoords1() != NULL) { setTexCoords1(getBaseGeometry()->getTexCoords1()); } if(getBaseGeometry()->getTexCoords2() != NULL) { setTexCoords2(getBaseGeometry()->getTexCoords2()); } if(getBaseGeometry()->getTexCoords3() != NULL) { setTexCoords3(getBaseGeometry()->getTexCoords3()); } if(getBaseGeometry()->getTexCoords4() != NULL) { setTexCoords4(getBaseGeometry()->getTexCoords4()); } if(getBaseGeometry()->getTexCoords5() != NULL) { setTexCoords5(getBaseGeometry()->getTexCoords5()); } if(getBaseGeometry()->getTexCoords6() != NULL) { setTexCoords6(getBaseGeometry()->getTexCoords6()); } if(getBaseGeometry()->getTexCoords7() != NULL) { setTexCoords7(getBaseGeometry()->getTexCoords7()); } if(getBaseGeometry()->getIndices() != NULL) { setIndices(getBaseGeometry()->getIndices()); } setMaterial(getBaseGeometry()->getMaterial()); } if(whichField & InternalJointsFieldMask) { _JointPoseTransforms.resize(getNumJoints()); } if( (whichField & BaseGeometryFieldMask) || (whichField & InternalJointsFieldMask) || (whichField & InternalWeightIndexesFieldMask) || (whichField & InternalWeightsFieldMask) || (whichField & BindTransformationFieldMask)) { if(getNumJoints() > 0) { _JointPoseTransforms.resize(getNumJoints()); calculatePositions(); } } }
void SkeletonBlendedGeometry::changed(ConstFieldMaskArg whichField, UInt32 origin, BitVector details) { Inherited::changed(whichField, origin, details); if((whichField & BaseGeometryFieldMask) && getBaseGeometry() != NULL) { if(getBaseGeometry()->getTypes() != NULL) { setTypes(getBaseGeometry()->getTypes()); } if(getBaseGeometry()->getLengths() != NULL) { setLengths(getBaseGeometry()->getLengths()); } if(getBaseGeometry()->getPositions() != NULL) { GeoPropertyUnrecPtr Pos(getBaseGeometry()->getPositions()->clone()); setPositions(dynamic_pointer_cast<GeoVectorProperty>(Pos)); } if(getBaseGeometry()->getNormals() != NULL) { GeoPropertyUnrecPtr Norm(getBaseGeometry()->getNormals()->clone()); setNormals(dynamic_pointer_cast<GeoVectorProperty>(Norm)); } if(getBaseGeometry()->getColors() != NULL) { setColors(getBaseGeometry()->getColors()); } if(getBaseGeometry()->getSecondaryColors() != NULL) { setSecondaryColors(getBaseGeometry()->getSecondaryColors()); } if(getBaseGeometry()->getTexCoords() != NULL) { setTexCoords(getBaseGeometry()->getTexCoords()); } if(getBaseGeometry()->getTexCoords1() != NULL) { setTexCoords1(getBaseGeometry()->getTexCoords1()); } if(getBaseGeometry()->getTexCoords2() != NULL) { setTexCoords2(getBaseGeometry()->getTexCoords2()); } if(getBaseGeometry()->getTexCoords3() != NULL) { setTexCoords3(getBaseGeometry()->getTexCoords3()); } if(getBaseGeometry()->getTexCoords4() != NULL) { setTexCoords4(getBaseGeometry()->getTexCoords4()); } if(getBaseGeometry()->getTexCoords5() != NULL) { setTexCoords5(getBaseGeometry()->getTexCoords5()); } if(getBaseGeometry()->getTexCoords6() != NULL) { setTexCoords6(getBaseGeometry()->getTexCoords6()); } if(getBaseGeometry()->getTexCoords7() != NULL) { setTexCoords7(getBaseGeometry()->getTexCoords7()); } if(getBaseGeometry()->getIndices() != NULL) { setIndices(getBaseGeometry()->getIndices()); } setMaterial(getBaseGeometry()->getMaterial()); } if((whichField & JointsFieldMask) || (whichField & PositionIndexesFieldMask) || (whichField & BlendAmountsFieldMask)) { calculatePositions(); } if(whichField & SkeletonsFieldMask) { for(std::vector<EventConnection>::iterator Itor(_SkeletonListenerConnections.begin()) ; Itor != _SkeletonListenerConnections.end() ; ++Itor) { Itor->disconnect(); } _SkeletonListenerConnections.clear(); for(UInt32 i(0) ; i<getMFSkeletons()->size() ; ++i) { _SkeletonListenerConnections.push_back(getSkeletons(i)->addSkeletonListener(this)); } } }
///////////////////////////////////////////////////////// // snapMess // ///////////////////////////////////////////////////////// void pix_snap2tex :: snapMess(void) { if(getState()==INIT) { verbose(0, "not initialized yet with a valid context"); return; } if(!GLEW_VERSION_1_1 && !GLEW_EXT_texture_object) return; int width = m_width; int height = m_height; GemMan::getDimen(((m_width >0)?NULL:&width ), ((m_height>0)?NULL:&height)); if (width <= 0 || height <= 0) { error("Illegal size %dx%d", width, height); return; } if(GLEW_VERSION_1_3) { glActiveTexture(GL_TEXTURE0_ARB + m_texUnit); } m_textureType = (m_rectangle?m_canRectangle:GL_TEXTURE_2D); glEnable(m_textureType); if(GLEW_VERSION_1_1) { glBindTexture(m_textureType, m_textureObj); } else { glBindTextureEXT(m_textureType, m_textureObj); } if (m_init) { m_init=false; // if the size changed, then reset the texture if(GL_TEXTURE_2D == m_textureType) { int x_2 = powerOfTwo(width); int y_2 = powerOfTwo(height); m_texWidth = x_2; m_texHeight = y_2; setTexCoords((float)width / (float)x_2, (float)height / (float)y_2); glCopyTexImage2D( m_textureType, 0, GL_RGBA16, m_x, m_y, m_texWidth, m_texHeight, 0); } else { setTexCoords(width, height); m_texWidth = width; m_texHeight = height; glCopyTexImage2D( m_textureType, 0, GL_RGBA16, m_x, m_y, m_texWidth, m_texHeight, 0); } } else { m_texHeight = height; m_texWidth = width; } glCopyTexSubImage2D(m_textureType, 0, 0, 0, m_x, m_y, // position m_texWidth, m_texHeight); glDisable(m_textureType); if(GLEW_VERSION_1_3) { glActiveTexture(GL_TEXTURE0_ARB); } }