void djvOpenGlImageShader::init( const QString & vertex, const QString & fragment) throw (djvError) { if (vertex == _vertex && fragment == _fragment) return; //DJV_DEBUG("djvOpenGlImageShader::init"); //DJV_DEBUG_PRINT("fragment = " << fragment); del(); _vertex = vertex; _fragment = fragment; GLint error = GL_FALSE; _vertexId = shaderCreate(GL_VERTEX_SHADER); _fragmentId = shaderCreate(GL_FRAGMENT_SHADER); shaderCompile(_vertexId, _vertex); shaderCompile(_fragmentId, _fragment); DJV_DEBUG_OPEN_GL(_program = glCreateProgram()); if (! _program) { throw djvError( "djvOpenGlImageShader", djvOpenGlImage::errorLabels()[djvOpenGlImage::ERROR_CREATE_PROGRAM]); } DJV_DEBUG_OPEN_GL(glAttachShader(_program, _vertexId)); DJV_DEBUG_OPEN_GL(glAttachShader(_program, _fragmentId)); DJV_DEBUG_OPEN_GL(glLinkProgram (_program)); glGetProgramiv(_program, GL_LINK_STATUS, &error); char log [4096] = ""; GLsizei logSize = 0; glGetProgramInfoLog(_program, 4096, &logSize, log); //DJV_DEBUG_PRINT("log = " << QString(log)); if (error != GL_TRUE) { throw djvError( "djvOpenGlImageShader", djvOpenGlImage::errorLabels()[djvOpenGlImage::ERROR_CREATE_PROGRAM]. arg(log)); } }
void djvOpenGlImageTexture::copy(const djvVector2i & in) { //DJV_DEBUG("djvOpenGlImageTexture::copy"); //DJV_DEBUG_PRINT("in = " << in); DJV_DEBUG_OPEN_GL(glBindTexture(GL_TEXTURE_2D, _id)); DJV_DEBUG_OPEN_GL( glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, in.x, in.y)); }
void djvGlslTestAbstractOp::begin() { //DJV_DEBUG("djvGlslTestAbstractOp::begin"); DJV_DEBUG_OPEN_GL(glPushAttrib( GL_VIEWPORT_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TRANSFORM_BIT | GL_PIXEL_MODE_BIT | GL_TEXTURE_BIT)); }
void djvGlslTestOffscreen::init() throw (djvError) { if (_id) return; //DJV_DEBUG("djvGlslTestOffscreen::init"); DJV_DEBUG_OPEN_GL(glGenFramebuffers(1, &_id)); if (! _id) throw djvError("glGenFramebuffers"); }
void djvGlslTestOffscreen::set(const djvOpenGlTexture & in) { //DJV_DEBUG("djvGlslTestOffscreen::set"); fboCheck(); DJV_DEBUG_OPEN_GL(glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE, in.id(), 0)); }
void djvOpenGlImageTexture::copy(const djvPixelData & in) { //DJV_DEBUG("djvOpenGlImageTexture::copy"); //DJV_DEBUG_PRINT("in = " << in); DJV_DEBUG_OPEN_GL(glBindTexture(GL_TEXTURE_2D, _id)); const djvPixelDataInfo & info = in.info(); djvOpenGlImage::stateUnpack(in.info()); DJV_DEBUG_OPEN_GL( glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, info.size.x, info.size.y, djvOpenGlUtil::format(info.pixel, info.bgr), djvOpenGlUtil::type(info.pixel), in.data())); }
void djvOpenGlLut::init(const djvPixelDataInfo & info) throw (djvError) { if (info == _info) return; //DJV_DEBUG("djvOpenGlLut::init"); //DJV_DEBUG_PRINT("info = " << info); del(); _info = info; _size = djvMath::toPow2(_info.size.x); //DJV_DEBUG_PRINT("size = " << _size); DJV_DEBUG_OPEN_GL(glGenTextures(1, &_id)); if (! _id) { throw djvError( "djvOpenGlLut", qApp->translate("djvOpenGlLut", "Cannot create texture")); } DJV_DEBUG_OPEN_GL(glBindTexture(GL_TEXTURE_1D, _id)); DJV_DEBUG_OPEN_GL( glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); DJV_DEBUG_OPEN_GL( glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); DJV_DEBUG_OPEN_GL( glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); GLenum format = GL_RGBA; if (djvPixel::F16 == djvPixel::type(_info.pixel)) { format = GL_RGBA16F; } else if (djvPixel::F32 == djvPixel::type(_info.pixel)) { format = GL_RGBA32F; } DJV_DEBUG_OPEN_GL( glTexImage1D( GL_TEXTURE_1D, 0, format, _size, 0, djvOpenGlUtil::format(_info.pixel, _info.bgr), djvOpenGlUtil::type(_info.pixel), 0)); }
void djvGlslTestOffscreen::bind() { //DJV_DEBUG("djvGlslTestOffscreen::bind"); DJV_DEBUG_OPEN_GL(glBindFramebuffer(GL_FRAMEBUFFER, _id)); }
void djvOpenGlLut::bind() { //DJV_DEBUG("djvOpenGlLut::bind"); DJV_DEBUG_OPEN_GL(glBindTexture(GL_TEXTURE_1D, _id)); }
void djvOpenGlImageShader::bind() { //DJV_DEBUG("djvOpenGlImageShader::bind"); DJV_DEBUG_OPEN_GL(glUseProgram(_program)); }
void djvOpenGlImageTexture::bind() { //DJV_DEBUG("djvOpenGlImageTexture::bind"); DJV_DEBUG_OPEN_GL(glBindTexture(GL_TEXTURE_2D, _id)); }
void djvOpenGlImageTexture::init( const djvPixelDataInfo & info, GLenum min, GLenum mag) throw (djvError) { if (info == _info && min == _min && mag == _mag) return; del(); //DJV_DEBUG("djvOpenGlImageTexture::init"); //DJV_DEBUG_PRINT("info = " << info); _info = info; _min = min; _mag = mag; DJV_DEBUG_OPEN_GL(glGenTextures(1, &_id)); //DJV_DEBUG_PRINT("id = " << int(_id)); if (! _id) { throw djvError( "djvOpenGlImageTexture", djvOpenGlImage::errorLabels()[djvOpenGlImage::ERROR_CREATE_TEXTURE]); } DJV_DEBUG_OPEN_GL(glBindTexture(GL_TEXTURE_2D, _id)); DJV_DEBUG_OPEN_GL( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); DJV_DEBUG_OPEN_GL( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); DJV_DEBUG_OPEN_GL( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _min)); DJV_DEBUG_OPEN_GL( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _mag)); GLenum format = GL_RGBA; if (djvPixel::F16 == djvPixel::type(_info.pixel)) { format = GL_RGBA16F; } else if (djvPixel::F32 == djvPixel::type(_info.pixel)) { format = GL_RGBA32F; } glTexImage2D( GL_TEXTURE_2D, 0, format, _info.size.x, _info.size.y, 0, djvOpenGlUtil::format(_info.pixel, _info.bgr), djvOpenGlUtil::type(_info.pixel), 0); GLenum error = glGetError(); #if ! defined(DJV_OSX) //! \todo On OS X this error is triggered the first time djv_view is //! started, though it doesn't actually seem to be a problem? If we //! throw here the image is not displayed (start djv_view from the //! command line with an image), but if we igore the error the image is //! displayed OK? Is this related to the "invalid drawable" message we //! are also getting on start up? if (error != GL_NO_ERROR) { throw djvError( "djvOpenGlImageTexture", djvOpenGlImage::errorLabels()[djvOpenGlImage::ERROR_CREATE_TEXTURE2]. arg((char *)gluErrorString(error))); } #endif // DJV_OSX }
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; } }