Texture* Texture::create(TextureHandle handle, int width, int height, Format format) { GP_ASSERT( handle ); Texture* texture = new Texture(); if (glIsTexture(handle)) { // There is no real way to query for texture type, but an error will be returned if a cube texture is bound to a 2D texture... so check for that glBindTexture(GL_TEXTURE_CUBE_MAP, handle); if (glGetError() == GL_NO_ERROR) { texture->_type = TEXTURE_CUBE; } else { // For now, it's either or. But if 3D textures and others are added, it might be useful to simply test a bunch of bindings and seeing which one doesn't error out texture->_type = TEXTURE_2D; } // Restore the texture id GL_ASSERT( glBindTexture((GLenum)__currentTextureType, __currentTextureId) ); } texture->_handle = handle; texture->_format = format; texture->_width = width; texture->_height = height; texture->_internalFormat = getFormatInternal(format); texture->_texelType = getFormatTexel(format); texture->_bpp = getFormatBPP(format); return texture; }
void FFStream::seekImpl(double position) throw(Exception) { if (position < 0) position = 0; // Translate float time to frametime uint64_t targetSample = uint64_t(position * getFormat().sampleFrequency); if ( (targetSample >= ffData->sampleBufferStart) && (targetSample < ffData->sampleBufferStart + ffData->sampleBufferSize) ) { // just skip data int advance = int(targetSample - ffData->sampleBufferStart); (char*&)ffData->sampleBuffer += ffData->sampleSize * advance; ffData->sampleBufferStart += advance; ffData->sampleBufferSize -= advance; } else { if (ffData->saneTimeStamps()) { // rough seek avcodec_flush_buffers(ffData->pCodecCtx); av_seek_frame(ffData->pFormatCtx, ffData->streamIndex, ffData->timeToPts(position), (targetSample < ffData->sampleBufferStart + ffData->sampleBufferSize) ? AVSEEK_FLAG_BACKWARD : 0); ffData->syncPts(); } else if (targetSample < ffData->sampleBufferStart) { // cannot seek but have to seek backwards, so... // ...close the file and reopen (yack) std::string path = ffData->filepath; VSFileSystem::VSFileType type = ffData->filetype; int streamIndex = ffData->audioStreamIndex; delete ffData; ffData = new __impl::FFData(path, type, getFormatInternal(), streamIndex); } // just skip data (big steps) do { nextBufferImpl(); } while (targetSample >= ffData->sampleBufferStart + ffData->sampleBufferSize); // just skip data (small steps) int advance = int(targetSample - ffData->sampleBufferStart); (char*&)ffData->sampleBuffer += ffData->sampleSize * advance; ffData->sampleBufferStart += advance; ffData->sampleBufferSize -= advance; } }
FFStream::FFStream(const std::string& path, int streamIndex, VSFileSystem::VSFileType type) throw(Exception) : Stream(path) { ffData = new __impl::FFData(path, type, getFormatInternal(), streamIndex); }
Texture* Texture::create(Format format, unsigned int width, unsigned int height, const unsigned char* data, bool generateMipmaps, Texture::Type type) { GP_ASSERT( type == Texture::TEXTURE_2D || type == Texture::TEXTURE_CUBE ); GLenum target = (GLenum)type; GLint internalFormat = getFormatInternal(format); GP_ASSERT( internalFormat != 0 ); GLenum texelType = getFormatTexel(format); GP_ASSERT( texelType != 0 ); // Create the texture. GLuint textureId; GL_ASSERT( glGenTextures(1, &textureId) ); GL_ASSERT( glBindTexture(target, textureId) ); GL_ASSERT( glPixelStorei(GL_UNPACK_ALIGNMENT, 1) ); #ifndef OPENGL_ES // glGenerateMipmap is new in OpenGL 3.0. For OpenGL 2.0 we must fallback to use glTexParameteri // with GL_GENERATE_MIPMAP prior to actual texture creation (glTexImage2D) if ( generateMipmaps && !std::addressof(glGenerateMipmap) ) GL_ASSERT( glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE) ); #endif // Load the texture size_t bpp = getFormatBPP(format); if (type == Texture::TEXTURE_2D) { GLenum f = (format == Texture::DEPTH) ? GL_DEPTH_COMPONENT : internalFormat; GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, f, texelType, data) ); } else { // Get texture size unsigned int textureSize = width * height; if (bpp == 0) { glDeleteTextures(1, &textureId); GP_ERROR("Failed to determine texture size because format is UNKNOWN."); return NULL; } textureSize *= bpp; // Texture Cube for (unsigned int i = 0; i < 6; i++) { const unsigned char* texturePtr = (data == NULL) ? NULL : &data[i * textureSize]; GL_ASSERT( glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internalFormat, width, height, 0, internalFormat, texelType, texturePtr) ); } } // Set initial minification filter based on whether or not mipmaping was enabled. Filter minFilter; if (format == Texture::DEPTH) { minFilter = NEAREST; GL_ASSERT( glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST) ); GL_ASSERT( glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST) ); GL_ASSERT( glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) ); GL_ASSERT( glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) ); #if !defined(OPENGL_ES) || defined(GL_ES_VERSION_3_0) && GL_ES_VERSION_3_0 GL_ASSERT( glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_NONE) ); #endif } else { minFilter = generateMipmaps ? NEAREST_MIPMAP_LINEAR : LINEAR; GL_ASSERT( glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilter) ); } Texture* texture = new Texture(); texture->_handle = textureId; texture->_format = format; texture->_type = type; texture->_width = width; texture->_height = height; texture->_minFilter = minFilter; texture->_internalFormat = internalFormat; texture->_texelType = texelType; texture->_bpp = bpp; if (generateMipmaps) texture->generateMipmaps(); // Restore the texture id GL_ASSERT( glBindTexture((GLenum)__currentTextureType, __currentTextureId) ); return texture; }