void TextureManager::reset() { for (size_t i = 0; i < kTextureUnitCount; i++) { activeTexture(i); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_CUBE_MAP); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_R); } activeTexture(0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); }
void GLRender::cleanup(GLint index) { for (GLint i = 0; i < index; i++) { activeTexture(i); glBindTexture(GL_TEXTURE_2D, 0); } glUseProgram(0); }
void Texture2D::loadImage(const char * path, GLint index) { assert(index >= 0 && index <= 31); int channel; activeTexture(index); bind(index); unsigned char * image = SOIL_load_image(path, &width[index], &height[index], &channel, SOIL_LOAD_RGBA); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width[index], height[index], 0, GL_RGBA, GL_UNSIGNED_BYTE, image); generateMipmap(index); SOIL_free_image_data(image); unbind(); }
void bindTextureN(GLuint textureUnit, GLuint textureId, GLuint textureType/* = GL_TEXTURE_2D*/) { #if CC_ENABLE_GL_STATE_CACHE CCASSERT(textureUnit < MAX_ACTIVE_TEXTURE, "textureUnit is too big"); if (s_currentBoundTexture[textureUnit] != textureId) { s_currentBoundTexture[textureUnit] = textureId; activeTexture(GL_TEXTURE0 + textureUnit); glBindTexture(textureType, textureId); } #else glActiveTexture(GL_TEXTURE0 + textureUnit); glBindTexture(textureType, textureId); #endif }
void StateManagerGL::deleteTexture(GLuint texture) { if (texture != 0) { for (const auto &textureTypeIter : mTextures) { const std::vector<GLuint> &textureVector = textureTypeIter.second; for (size_t textureUnitIndex = 0; textureUnitIndex < textureVector.size(); textureUnitIndex++) { if (textureVector[textureUnitIndex] == texture) { activeTexture(textureUnitIndex); bindTexture(textureTypeIter.first, 0); } } } mFunctions->deleteTextures(1, &texture); } }
void TextureManager::reset() { activeTexture(0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); }
gl::Error StateManagerGL::setGenericDrawState(const gl::Data &data) { const gl::State &state = *data.state; // If the context has changed, pause the previous context's transform feedback and queries if (data.context != mPrevDrawContext) { if (mPrevDrawTransformFeedback != nullptr) { mPrevDrawTransformFeedback->syncPausedState(true); } for (QueryGL *prevQuery : mPrevDrawQueries) { prevQuery->pause(); } } mPrevDrawTransformFeedback = nullptr; mPrevDrawQueries.clear(); mPrevDrawContext = data.context; // Sync the current program state const gl::Program *program = state.getProgram(); const ProgramGL *programGL = GetImplAs<ProgramGL>(program); useProgram(programGL->getProgramID()); for (size_t uniformBlockIndex = 0; uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++) { GLuint binding = program->getUniformBlockBinding(static_cast<GLuint>(uniformBlockIndex)); const OffsetBindingPointer<gl::Buffer> &uniformBuffer = data.state->getIndexedUniformBuffer(binding); if (uniformBuffer.get() != nullptr) { BufferGL *bufferGL = GetImplAs<BufferGL>(uniformBuffer.get()); if (uniformBuffer.getSize() == 0) { bindBufferBase(GL_UNIFORM_BUFFER, binding, bufferGL->getBufferID()); } else { bindBufferRange(GL_UNIFORM_BUFFER, binding, bufferGL->getBufferID(), uniformBuffer.getOffset(), uniformBuffer.getSize()); } } } const std::vector<SamplerBindingGL> &appliedSamplerUniforms = programGL->getAppliedSamplerUniforms(); for (const SamplerBindingGL &samplerUniform : appliedSamplerUniforms) { GLenum textureType = samplerUniform.textureType; for (GLuint textureUnitIndex : samplerUniform.boundTextureUnits) { const gl::Texture *texture = state.getSamplerTexture(textureUnitIndex, textureType); if (texture != nullptr) { const TextureGL *textureGL = GetImplAs<TextureGL>(texture); if (mTextures[textureType][textureUnitIndex] != textureGL->getTextureID()) { activeTexture(textureUnitIndex); bindTexture(textureType, textureGL->getTextureID()); } textureGL->syncState(textureUnitIndex, texture->getTextureState()); } else { if (mTextures[textureType][textureUnitIndex] != 0) { activeTexture(textureUnitIndex); bindTexture(textureType, 0); } } const gl::Sampler *sampler = state.getSampler(textureUnitIndex); if (sampler != nullptr) { const SamplerGL *samplerGL = GetImplAs<SamplerGL>(sampler); samplerGL->syncState(sampler->getSamplerState()); bindSampler(textureUnitIndex, samplerGL->getSamplerID()); } else { bindSampler(textureUnitIndex, 0); } } } const gl::Framebuffer *framebuffer = state.getDrawFramebuffer(); const FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer); bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferGL->getFramebufferID()); framebufferGL->syncDrawState(); // Seamless cubemaps are required for ES3 and higher contexts. setTextureCubemapSeamlessEnabled(data.clientVersion >= 3); // Set the current transform feedback state gl::TransformFeedback *transformFeedback = state.getCurrentTransformFeedback(); if (transformFeedback) { TransformFeedbackGL *transformFeedbackGL = GetImplAs<TransformFeedbackGL>(transformFeedback); bindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbackGL->getTransformFeedbackID()); transformFeedbackGL->syncActiveState(transformFeedback->isActive(), transformFeedback->getPrimitiveMode()); transformFeedbackGL->syncPausedState(transformFeedback->isPaused()); mPrevDrawTransformFeedback = transformFeedbackGL; } else { bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); mPrevDrawTransformFeedback = nullptr; } // Set the current query state for (GLenum queryType : QueryTypes) { gl::Query *query = state.getActiveQuery(queryType); if (query != nullptr) { QueryGL *queryGL = GetImplAs<QueryGL>(query); queryGL->resume(); mPrevDrawQueries.insert(queryGL); } } return gl::Error(GL_NO_ERROR); }
void BufferTexture::unbindTexture( uint8_t textureUnit ) { ScopedActiveTexture activeTexture( textureUnit ); gl::context()->bindTexture( mTarget, 0 ); }
gl::Error StateManagerGL::setGenericDrawState(const gl::Data &data) { const gl::State &state = *data.state; const gl::Caps &caps = *data.caps; const gl::Program *program = state.getProgram(); const ProgramGL *programGL = GetImplAs<ProgramGL>(program); useProgram(programGL->getProgramID()); // TODO: Only apply textures referenced by the program. for (auto textureTypeIter = mTextures.begin(); textureTypeIter != mTextures.end(); textureTypeIter++) { GLenum textureType = textureTypeIter->first; // Determine if this texture type can exist in the source context bool validTextureType = (textureType == GL_TEXTURE_2D || textureType == GL_TEXTURE_CUBE_MAP || (textureType == GL_TEXTURE_2D_ARRAY && data.clientVersion >= 3) || (textureType == GL_TEXTURE_3D && data.clientVersion >= 3)); const std::vector<GLuint> &textureVector = textureTypeIter->second; for (size_t textureUnitIndex = 0; textureUnitIndex < textureVector.size(); textureUnitIndex++) { const gl::Texture *texture = nullptr; bool validTextureUnit = textureUnitIndex < caps.maxCombinedTextureImageUnits; if (validTextureType && validTextureUnit) { texture = state.getSamplerTexture(textureUnitIndex, textureType); } if (texture != nullptr) { const TextureGL *textureGL = GetImplAs<TextureGL>(texture); textureGL->syncSamplerState(texture->getSamplerState()); if (mTextures[textureType][textureUnitIndex] != textureGL->getTextureID()) { activeTexture(textureUnitIndex); bindTexture(textureType, textureGL->getTextureID()); } // TODO: apply sampler object if one is bound } else { if (mTextures[textureType][textureUnitIndex] != 0) { activeTexture(textureUnitIndex); bindTexture(textureType, 0); } } } } const gl::Framebuffer *framebuffer = state.getDrawFramebuffer(); const FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer); bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferGL->getFramebufferID()); setScissor(state.getScissor()); setViewport(state.getViewport()); const gl::BlendState &blendState = state.getBlendState(); setColorMask(blendState.colorMaskRed, blendState.colorMaskGreen, blendState.colorMaskBlue, blendState.colorMaskAlpha); const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); setDepthMask(depthStencilState.depthMask); setStencilMask(depthStencilState.stencilMask); return gl::Error(GL_NO_ERROR); }
void djvOpenGlImage::draw( const djvPixelData & data, const djvOpenGlImageOptions & options, djvOpenGlImageState * state) throw (djvError) { //DJV_DEBUG("djvOpenGlImage::draw"); //DJV_DEBUG_PRINT("data = " << data); //DJV_DEBUG_PRINT("color profile = " << options.colorProfile); RestoreState restoreState; djvOpenGlImageState defaultState; if (! state) { state = &defaultState; } const djvPixelDataInfo & info = data.info(); const int proxyScale = options.proxyScale ? djvPixelDataUtil::proxyScale(info.proxy) : 1; const djvVector2i scale = djvVectorUtil::ceil<double, int>( options.xform.scale * djvVector2f(info.size * proxyScale)); const djvVector2i scaleTmp(scale.x, data.h()); //DJV_DEBUG_PRINT("scale = " << scale); //DJV_DEBUG_PRINT("scale tmp = " << scaleTmp); // Initialize. const djvOpenGlImageFilter::FILTER filter = info.size == scale ? djvOpenGlImageFilter::NEAREST : (djvVectorUtil::area(scale) < djvVectorUtil::area(info.size) ? options.filter.min : options.filter.mag); //DJV_DEBUG_PRINT("filter min = " << options.filter.min); //DJV_DEBUG_PRINT("filter mag = " << options.filter.mag); //DJV_DEBUG_PRINT("filter = " << filter); if (! state->_init || state->_info != info || state->_options != options) { switch (filter) { case djvOpenGlImageFilter::NEAREST: case djvOpenGlImageFilter::LINEAR: { //DJV_DEBUG_PRINT("init single pass"); state->_texture->init( data.info(), djvOpenGlImageFilter::toGl(filter), djvOpenGlImageFilter::toGl(filter)); state->_shader->init( sourceVertex, sourceFragment( options.colorProfile.type, options.displayProfile, options.channel, false, 0, false)); } break; case djvOpenGlImageFilter::BOX: case djvOpenGlImageFilter::TRIANGLE: case djvOpenGlImageFilter::BELL: case djvOpenGlImageFilter::BSPLINE: case djvOpenGlImageFilter::LANCZOS3: case djvOpenGlImageFilter::CUBIC: case djvOpenGlImageFilter::MITCHELL: { //DJV_DEBUG_PRINT("init two pass"); state->_texture->init( data.info(), GL_NEAREST, GL_NEAREST); // Initialize horizontal pass. djvPixelData contrib; scaleContrib( data.w(), scale.x, filter, contrib); state->_scaleXContrib->init( contrib, GL_NEAREST, GL_NEAREST); state->_scaleXShader->init( sourceVertex, sourceFragment( options.colorProfile.type, djvOpenGlImageDisplayProfile(), static_cast<djvOpenGlImageOptions::CHANNEL>(0), true, contrib.h(), true)); // Initialize vertical pass. scaleContrib( data.h(), scale.y, filter, contrib); state->_scaleYContrib->init( contrib, GL_NEAREST, GL_NEAREST); state->_scaleYShader->init( sourceVertex, sourceFragment( static_cast<djvColorProfile::PROFILE>(0), options.displayProfile, options.channel, true, contrib.h(), false)); } break; default: break; } state->_init = true; state->_info = info; state->_options = options; } // Render. const djvPixelDataInfo::Mirror mirror( info.mirror.x ? (! options.xform.mirror.x) : options.xform.mirror.x, info.mirror.y ? (! options.xform.mirror.y) : options.xform.mirror.y); //DJV_DEBUG_PRINT("mirror = " << mirror.x << " " << mirror.y); switch (filter) { case djvOpenGlImageFilter::NEAREST: case djvOpenGlImageFilter::LINEAR: { //DJV_DEBUG_PRINT("draw single pass"); state->_shader->bind(); // Initialize color and display profiles. colorProfileInit( options, state->_shader->program(), *state->_lutColorProfile); displayProfileInit( options, state->_shader->program(), *state->_lutDisplayProfile); // Draw. activeTexture(GL_TEXTURE0); uniform1i(state->_shader->program(), "inTexture", 0); state->_texture->copy(data); state->_texture->bind(); DJV_DEBUG_OPEN_GL(glPushMatrix()); const djvMatrix3f m = djvOpenGlImageXform::xformMatrix(options.xform); //DJV_DEBUG_PRINT("m = " << m); DJV_DEBUG_OPEN_GL(glLoadMatrixd(djvMatrixUtil::matrix4(m).e)); quad(info.size, mirror, proxyScale); DJV_DEBUG_OPEN_GL(glPopMatrix()); } break; case djvOpenGlImageFilter::BOX: case djvOpenGlImageFilter::TRIANGLE: case djvOpenGlImageFilter::BELL: case djvOpenGlImageFilter::BSPLINE: case djvOpenGlImageFilter::LANCZOS3: case djvOpenGlImageFilter::CUBIC: case djvOpenGlImageFilter::MITCHELL: { //DJV_DEBUG_PRINT("draw two pass"); // Horizontal pass. djvOpenGlOffscreenBuffer buffer( djvPixelDataInfo(scaleTmp, data.pixel())); { djvOpenGlOffscreenBufferScope bufferScope(&buffer); state->_scaleXShader->bind(); colorProfileInit( options, state->_scaleXShader->program(), *state->_lutColorProfile); activeTexture(GL_TEXTURE0); uniform1i(state->_scaleXShader->program(), "inTexture", 0); state->_texture->copy(data); state->_texture->bind(); activeTexture(GL_TEXTURE1); uniform1i( state->_scaleXShader->program(), "inScaleContrib", 1); state->_scaleXContrib->bind(); glPushAttrib(GL_TRANSFORM_BIT | GL_VIEWPORT_BIT); glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); djvOpenGlUtil::ortho(scaleTmp); glViewport(0, 0, scaleTmp.x, scaleTmp.y); quad(scaleTmp, mirror); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glPopAttrib(); } // Vertical pass. state->_scaleYShader->bind(); displayProfileInit( options, state->_scaleYShader->program(), *state->_lutDisplayProfile); activeTexture(GL_TEXTURE0); uniform1i(state->_scaleYShader->program(), "inTexture", 0); DJV_DEBUG_OPEN_GL(glBindTexture(GL_TEXTURE_2D, buffer.texture())); activeTexture(GL_TEXTURE1); uniform1i(state->_scaleYShader->program(), "inScaleContrib", 1); state->_scaleYContrib->bind(); djvOpenGlImageXform xform = options.xform; xform.scale = djvVector2f(1.0); const djvMatrix3f m = djvOpenGlImageXform::xformMatrix(xform); DJV_DEBUG_OPEN_GL(glPushMatrix()); DJV_DEBUG_OPEN_GL(glLoadMatrixd(djvMatrixUtil::matrix4(m).e)); quad(scale); DJV_DEBUG_OPEN_GL(glPopMatrix()); } break; default: break; } }
void bindTexture(TextureUnitId aTextureUnit, TextureTarget aTextureTarget, TextureId aTexture) { activeTexture(aTextureUnit); bindTexture(aTextureTarget, aTexture); }