inline void VL_glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data)
 {
   if (glCompressedTexImage3D)
     glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data);
   else
     VL_UNSUPPORTED_FUNC();
 }
Example #2
0
void Texture3D::init(int w, int h, int d, TextureInternalFormat tf, TextureFormat f, PixelType t,
    const Parameters &params, const Buffer::Parameters &s, const Buffer &pixels)
{
    Texture::init(tf, params);
    this->w = w;
    this->h = h;
    this->d = d;

    bindToTextureUnit();

    pixels.bind(GL_PIXEL_UNPACK_BUFFER);
    if (isCompressed() && s.compressedSize() > 0) {
        glCompressedTexImage3D(GL_TEXTURE_3D, 0, getTextureInternalFormat(internalFormat), w, h, d, 0, s.compressedSize(), pixels.data(0));
    } else {
        s.set();
        glTexImage3D(GL_TEXTURE_3D, 0, getTextureInternalFormat(internalFormat), w, h, d, 0, getTextureFormat(f), getPixelType(t), pixels.data(0));
        s.unset();
    }
    pixels.unbind(GL_PIXEL_UNPACK_BUFFER);

    generateMipMap();

    if (FrameBuffer::getError() != 0) {
        throw exception();
    }
}
	bool initTexture()
	{
		gli::texture2D Texture(gli::load_dds((getDataDirectory() + TEXTURE_DIFFUSE).c_str()));

		glGenTextures(1, &TextureName);

		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D_ARRAY, TextureName);
		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, static_cast<GLint>(Texture.levels() - 1));
		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_R, GL_RED);
		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);

		for(std::size_t Level = 0; Level < Texture.levels(); ++Level)
		{
			glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY,
				GLint(Level),
				GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
				GLsizei(Texture[Level].dimensions().x),
				GLsizei(Texture[Level].dimensions().y),
				GLsizei(1),
				0, 
				GLsizei(Texture[Level].size()), 
				Texture[Level].data());
		}

		return this->checkError("initTexture");
	}
void APIENTRY FWGLExtension::initCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data)
{
	spCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3D)FW_GETGLPROC("glCompressedTexImage3D");
	if(!spCompressedTexImage3D)
		reportError("glCompressedTexImage3D");
	glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data);
}
EXTERN_C_ENTER

JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL13_nglCompressedTexImage3D(JNIEnv *__env, jclass clazz, jint target, jint level, jint internalformat, jint width, jint height, jint depth, jint border, jint imageSize, jlong dataAddress, jlong __functionAddress) {
	const GLvoid *data = (const GLvoid *)(intptr_t)dataAddress;
	glCompressedTexImage3DPROC glCompressedTexImage3D = (glCompressedTexImage3DPROC)(intptr_t)__functionAddress;
	UNUSED_PARAMS(__env, clazz)
	glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data);
}
void QOpenGLTextureHelper::qt_CompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits)
{
    GLint oldTexture;
    glGetIntegerv(bindingTarget, &oldTexture);
    glBindTexture(target, texture);
    glCompressedTexImage3D(target, level, internalFormat, width, height, depth, border, imageSize, bits);
    glBindTexture(target, oldTexture);
}
Example #7
0
void RenderDevice::uploadTextureData( uint32 texObj, int slice, int mipLevel, const void *pixels )
{
	const RDITexture &tex = _textures.getRef( texObj );
	TextureFormats::List format = tex.format;

	glActiveTexture( GL_TEXTURE15 );
	glBindTexture( tex.type, tex.glObj );
	
	int inputFormat = GL_BGRA, inputType = GL_UNSIGNED_BYTE;
	bool compressed = (format == TextureFormats::DXT1) || (format == TextureFormats::DXT3) ||
	                  (format == TextureFormats::DXT5);
	
	switch( format )
	{
	case TextureFormats::RGBA16F:
		inputFormat = GL_RGBA;
		inputType = GL_FLOAT;
		break;
	case TextureFormats::RGBA32F:
		inputFormat = GL_RGBA;
		inputType = GL_FLOAT;
		break;
	case TextureFormats::DEPTH:
		inputFormat = GL_DEPTH_COMPONENT;
		inputType = GL_FLOAT;
	};
	
	// Calculate size of next mipmap using "floor" convention
	int width = std::max( tex.width >> mipLevel, 1 ), height = std::max( tex.height >> mipLevel, 1 );
	
	if( tex.type == TextureTypes::Tex2D || tex.type == TextureTypes::TexCube )
	{
		int target = (tex.type == TextureTypes::Tex2D) ?
			GL_TEXTURE_2D : (GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice);
		
		if( compressed )
			glCompressedTexImage2D( target, mipLevel, tex.glFmt, width, height, 0,
			                        calcTextureSize( format, width, height, 1 ), pixels );	
		else
			glTexImage2D( target, mipLevel, tex.glFmt, width, height, 0, inputFormat, inputType, pixels );
	}
	else if( tex.type == TextureTypes::Tex3D )
	{
		int depth = std::max( tex.depth >> mipLevel, 1 );
		
		if( compressed )
			glCompressedTexImage3D( GL_TEXTURE_3D, mipLevel, tex.glFmt, width, height, depth, 0,
			                        calcTextureSize( format, width, height, depth ), pixels );	
		else
			glTexImage3D( GL_TEXTURE_3D, mipLevel, tex.glFmt, width, height, depth, 0,
			              inputFormat, inputType, pixels );
	}
Example #8
0
PIGLIT_GL_TEST_CONFIG_END


static bool
test_getsubimage(GLenum target,
		 GLsizei width, GLsizei height, GLsizei numSlices,
		 GLenum intFormat)
{
	const GLint bufSize = width * height * 4 * sizeof(GLubyte);
	GLubyte *texData;
	GLubyte *refData = malloc(6 * bufSize); /* 6 for cubemaps */
	GLubyte *testData = malloc(6 * bufSize); /* 6 for cubemaps */
	GLuint tex;
	int i, slice, compressedSize, compSize;
	int blockWidth, blockHeight, blockSize;
	bool pass = true;
	const int level = 0;
	int x0, y0, x1, y1, w0, h0, w1, h1;

	printf("Testing %s %s %d x %d\n",
	       piglit_get_gl_enum_name(target),
	       piglit_get_gl_enum_name(intFormat),
	       width, height);

	/* For all S3TC formats */
	blockWidth = blockHeight = 4;
	if (intFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
	    intFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) {
		blockSize = 8;
	}
	else {
		assert(intFormat == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
		       intFormat == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
		blockSize = 16;
	}

	/* Size must be multiple of block dims */
	assert(width % blockWidth == 0);
	assert(height % blockHeight == 0);

	compressedSize = (width / blockWidth) * (height / blockHeight)
		* blockSize;
	if (0) {
		printf("byte per block row: %d\n",
		       (width / blockWidth) * blockSize);
		printf("compressed image size = %d\n", compressedSize);
	}

	/* initial texture data */
	texData = malloc(compressedSize);
	for (i = 0; i < compressedSize; i++) {
		texData[i] = (i+10) & 0xff;
	}

	glGenTextures(1, &tex);
	glBindTexture(target, tex);

	/* Define texture image */
	if (target == GL_TEXTURE_CUBE_MAP) {
		for (slice = 0; slice < 6; slice++) {
			glCompressedTexImage2D(
				GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice,
				level, intFormat, width, height, 0,
				compressedSize, texData);
		}
		glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level,
					 GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
					 &compSize);
		assert(numSlices == 6);
	}
	else if (target == GL_TEXTURE_CUBE_MAP_ARRAY) {
		assert(numSlices % 6 == 0);
		glCompressedTexImage3D(target, level, intFormat,
				       width, height, numSlices, 0,
				       compressedSize * numSlices, NULL);
		for (slice = 0; slice < numSlices; slice++) {
			glCompressedTexSubImage3D(target, level,
						  0, 0, slice,
						  width, height, 1,
						  intFormat,
						  compressedSize, texData);
		}
		glGetTexLevelParameteriv(target, level,
					 GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
					 &compSize);
		compSize /= numSlices;
	}
	else if (target == GL_TEXTURE_2D_ARRAY) {
		glCompressedTexImage3D(target, level, intFormat,
				       width, height, numSlices, 0,
				       compressedSize * numSlices, NULL);
		for (slice = 0; slice < numSlices; slice++) {
			glCompressedTexSubImage3D(target, level,
						  0, 0, slice,
						  width, height, 1,
						  intFormat,
						  compressedSize, texData);
		}
		glGetTexLevelParameteriv(target, level,
					 GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
					 &compSize);
		compSize /= numSlices;
	}
	else {
		assert(target == GL_TEXTURE_2D);
		glCompressedTexImage2D(target, level, intFormat,
				       width, height, 0,
				       compressedSize, texData);
		glGetTexLevelParameteriv(target, level,
					 GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
					 &compSize);
		assert(numSlices == 1);
	}

	assert(compSize == compressedSize);

	/* Should be no GL errors */
	if (!piglit_check_gl_error(GL_NO_ERROR)) {
		pass = false;
	}

	refData = calloc(1, numSlices * compressedSize);
	testData = calloc(1, numSlices * compressedSize);

	/* compute pos/size of sub-regions */
	x0 = 0;
	y0 = 0;
	x1 = width / 4;  /* quarter width */
	y1 = height / 2;  /* half height */

	/* Position must be multiple of block dims */
	assert(x1 % blockWidth == 0);
	assert(y1 % blockHeight == 0);

	w0 = x1 - x0;
	w1 = width - x1;
	h0 = y1 - y0;
	h1 = height - y1;

	/* Sizes must be multiple of block dims */
	assert(w0 % blockWidth == 0);
	assert(w1 % blockWidth == 0);
	assert(h0 % blockHeight == 0);
	assert(h1 % blockHeight == 0);

	glPixelStorei(GL_PACK_ALIGNMENT, 1);
	glPixelStorei(GL_PACK_ROW_LENGTH, width);
	glPixelStorei(GL_PACK_IMAGE_HEIGHT, height);
	glPixelStorei(GL_PACK_COMPRESSED_BLOCK_WIDTH, blockWidth);
	glPixelStorei(GL_PACK_COMPRESSED_BLOCK_HEIGHT, blockHeight);
	glPixelStorei(GL_PACK_COMPRESSED_BLOCK_SIZE, blockSize);

	/* Should be no GL errors */
	if (!piglit_check_gl_error(GL_NO_ERROR)) {
		pass = false;
	}

	/*
	 * Get whole compressed image (the reference)
	 */
	if (target == GL_TEXTURE_CUBE_MAP) {
		for (slice = 0; slice < 6; slice++) {
			glGetCompressedTexImage(
				GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice,
				level,
				refData + slice * compressedSize);
		}
	}
	else {
		glGetCompressedTexImage(target, level, refData);
	}

	if (!piglit_check_gl_error(GL_NO_ERROR)) {
		pass = false;
	}

	/*
	 * Now get four sub-regions which should be equivalent
	 * to the whole reference image.
	 */

	/* lower-left */
	glPixelStorei(GL_PACK_SKIP_PIXELS, x0);
	glPixelStorei(GL_PACK_SKIP_ROWS, y0);
	glGetCompressedTextureSubImage(tex, level,
				       x0, y0, 0, w0, h0, numSlices,
				       numSlices * compressedSize, testData);

	/* lower-right */
	glPixelStorei(GL_PACK_SKIP_PIXELS, x1);
	glPixelStorei(GL_PACK_SKIP_ROWS, y0);
	glGetCompressedTextureSubImage(tex, level,
				       x1, y0, 0, w1, h0, numSlices,
				       numSlices * compressedSize, testData);

	/* upper-left */
	glPixelStorei(GL_PACK_SKIP_PIXELS, x0);
	glPixelStorei(GL_PACK_SKIP_ROWS, y1);
	glGetCompressedTextureSubImage(tex, level,
				       x0, y1, 0, w0, h1, numSlices,
				       numSlices * compressedSize, testData);

	/* upper-right */
	glPixelStorei(GL_PACK_SKIP_PIXELS, x1);
	glPixelStorei(GL_PACK_SKIP_ROWS, y1);
	glGetCompressedTextureSubImage(tex, level,
				       x1, y1, 0, w1, h1, numSlices,
				       numSlices * compressedSize, testData);

	/* defaults */
	glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
	glPixelStorei(GL_PACK_SKIP_ROWS, 0);

	/* Should be no GL errors */
	if (!piglit_check_gl_error(GL_NO_ERROR)) {
		pass = false;
	}

	/* now compare the images */
	for (slice = 0; slice < numSlices; slice++) {
		int sliceStart = slice * compressedSize;
		if (memcmp(refData + sliceStart,
			   testData + sliceStart,
			   compressedSize)) {
			int i;
			for (i = 0; i < compressedSize; i++) {
				if (refData[sliceStart + i] !=
				    testData[sliceStart + i]) {
					printf("fail in slice/face %d at offset %d\n",
					       slice, i);
					printf("expected %d, found %d\n",
					       refData[sliceStart + i],
					       testData[sliceStart + i]);
					break;
				}
			}
			printf("Failure for %s %s\n",
			       piglit_get_gl_enum_name(target),
			       piglit_get_gl_enum_name(intFormat));
			pass = false;
		}
	}

	free(texData);
	free(refData);
	free(testData);

	glDeleteTextures(1, &tex);

	return pass;
}
Example #9
0
bool Texture2DArray::SetData(unsigned layer, unsigned level, int x, int y, int width, int height, const void* data)
{
    URHO3D_PROFILE(SetTextureData);

    if (!object_.name_ || !graphics_)
    {
        URHO3D_LOGERROR("Texture array not created, can not set data");
        return false;
    }

    if (!data)
    {
        URHO3D_LOGERROR("Null source for setting data");
        return false;
    }

    if (layer >= layers_)
    {
        URHO3D_LOGERROR("Illegal layer for setting data");
        return false;
    }

    if (level >= levels_)
    {
        URHO3D_LOGERROR("Illegal mip level for setting data");
        return false;
    }

    if (graphics_->IsDeviceLost())
    {
        URHO3D_LOGWARNING("Texture array data assignment while device is lost");
        dataPending_ = true;
        return true;
    }

    if (IsCompressed())
    {
        x &= ~3;
        y &= ~3;
    }

    int levelWidth = GetLevelWidth(level);
    int levelHeight = GetLevelHeight(level);
    if (x < 0 || x + width > levelWidth || y < 0 || y + height > levelHeight || width <= 0 || height <= 0)
    {
        URHO3D_LOGERROR("Illegal dimensions for setting data");
        return false;
    }

    graphics_->SetTextureForUpdate(this);

#ifndef GL_ES_VERSION_2_0
    bool wholeLevel = x == 0 && y == 0 && width == levelWidth && height == levelHeight && layer == 0;
    unsigned format = GetSRGB() ? GetSRGBFormat(format_) : format_;

    if (!IsCompressed())
    {
        if (wholeLevel)
            glTexImage3D(target_, level, format, width, height, layers_, 0, GetExternalFormat(format_),
                GetDataType(format_), 0);
        glTexSubImage3D(target_, level, x, y, layer, width, height, 1, GetExternalFormat(format_),
            GetDataType(format_), data);
    }
    else
    {
        if (wholeLevel)
            glCompressedTexImage3D(target_, level, format, width, height, layers_, 0,
                GetDataSize(width, height, layers_), 0);
        glCompressedTexSubImage3D(target_, level, x, y, layer, width, height, 1, format,
            GetDataSize(width, height), data);
    }
#endif

    graphics_->SetTexture(0, 0);
    return true;
}
Example #10
0
	void OGLESTextureCube::CreateHWResource(ElementInitData const * init_data)
	{
		uint32_t texel_size = NumFormatBytes(format_);

		GLint glinternalFormat;
		GLenum glformat;
		GLenum gltype;
		OGLESMapping::MappingFormat(glinternalFormat, glformat, gltype, format_);

		glBindTexture(target_type_, texture_);
		for (uint32_t array_index = 0; array_index < array_size_; ++ array_index)
		{
			for (int face = 0; face < 6; ++ face)
			{
				for (uint32_t level = 0; level < num_mip_maps_; ++ level)
				{
					uint32_t const s = this->Width(level);

					if (IsCompressedFormat(format_))
					{
						uint32_t const block_size = NumFormatBytes(format_) * 4;
						GLsizei const image_size = ((s + 3) / 4) * ((s + 3) / 4) * block_size;

						void* ptr;
						if (nullptr == init_data)
						{
							tex_data_[(array_index * 6 + face) * num_mip_maps_ + level].resize(image_size, 0);
							ptr = nullptr;
						}
						else
						{
							tex_data_[(array_index * 6 + face) * num_mip_maps_ + level].resize(image_size);
							std::memcpy(&tex_data_[(array_index * 6 + face) * num_mip_maps_ + level][0],
								init_data[(array_index * 6 + face) * num_mip_maps_ + level].data, image_size);
							ptr = &tex_data_[(array_index * 6 + face) * num_mip_maps_ + level][0];
						}

						if (array_size_ > 1)
						{
							if (0 == array_index)
							{
								glCompressedTexImage3D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, glinternalFormat,
									s, s, array_size_, 0, image_size * array_size_, nullptr);
							}

							if (init_data != nullptr)
							{
								glCompressedTexSubImage3D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, 0, 0, array_index, s, s, 1,
									glformat, image_size, init_data[(array_index * 6 + face) * num_mip_maps_ + level].data);
							}
						}
						else
						{
							glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, glinternalFormat,
								s, s, 0, image_size, ptr);
						}
					}
					else
					{
						GLsizei const image_size = s * s * texel_size;

						void* ptr;
						if (nullptr == init_data)
						{
							tex_data_[(array_index * 6 + face) * num_mip_maps_ + level].resize(image_size, 0);
							ptr = nullptr;
						}
						else
						{
							tex_data_[(array_index * 6 + face) * num_mip_maps_ + level].resize(image_size);
							std::memcpy(&tex_data_[(array_index * 6 + face) * num_mip_maps_ + level][0],
								init_data[face * num_mip_maps_ + level].data, image_size);
							ptr = &tex_data_[(array_index * 6 + face) * num_mip_maps_ + level][0];
						}

						if (array_size_ > 1)
						{
							if (0 == array_index)
							{
								glTexImage3D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, glinternalFormat, s, s, array_size_, 0, glformat, gltype, nullptr);
							}

							if (init_data != nullptr)
							{
								glTexSubImage3D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, 0, 0, array_index, s, s, 1,
									glformat, gltype, init_data[array_index * num_mip_maps_ + level].data);
							}
						}
						else
						{
							glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, glinternalFormat,
								s, s, 0, glformat, gltype, ptr);
						}
					}
				}
			}
		}

		hw_res_ready_ = true;
	}
Example #11
0
    void GLES2Texture::_createGLTexResource()
    {
        if(!Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_NON_POWER_OF_2_TEXTURES) ||
           (Root::getSingleton().getRenderSystem()->getCapabilities()->getNonPOW2TexturesLimited() && mNumRequestedMipmaps > 0))
        {
            // Convert to nearest power-of-two size if required
            mWidth = GLES2PixelUtil::optionalPO2(mWidth);
            mHeight = GLES2PixelUtil::optionalPO2(mHeight);
            mDepth = GLES2PixelUtil::optionalPO2(mDepth);
        }

        // Adjust format if required
        mFormat = TextureManager::getSingleton().getNativeFormat(mTextureType, mFormat, mUsage);
        GLenum texTarget = getGLES2TextureTarget();

        // Check requested number of mipmaps
        size_t maxMips = GLES2PixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat);
        
        if(PixelUtil::isCompressed(mFormat) && (mNumMipmaps == 0))
            mNumRequestedMipmaps = 0;
        
        mNumMipmaps = mNumRequestedMipmaps;
        if (mNumMipmaps > maxMips)
            mNumMipmaps = maxMips;

        // Generate texture name
        OGRE_CHECK_GL_ERROR(glGenTextures(1, &mTextureID));
           
        // Set texture type
        mGLSupport.getStateCacheManager()->bindGLTexture(texTarget, mTextureID);
        
        // If we can do automip generation and the user desires this, do so
        mMipmapsHardwareGenerated =
            Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_AUTOMIPMAP) && !PixelUtil::isCompressed(mFormat);

        if(!Bitwise::isPO2(mWidth) || !Bitwise::isPO2(mHeight))
            mMipmapsHardwareGenerated = false;

        // glGenerateMipmap require all mip levels to be prepared. So override how many this texture has.
        if((mUsage & TU_AUTOMIPMAP) && mMipmapsHardwareGenerated && mNumRequestedMipmaps)
            mNumMipmaps = maxMips;

        if(getGLES2SupportRef()->checkExtension("GL_APPLE_texture_max_level") || gleswIsSupported(3, 0))
            mGLSupport.getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_MAX_LEVEL_APPLE, mNumRequestedMipmaps ? mNumMipmaps + 1 : 0);

        // Set some misc default parameters, these can of course be changed later
        mGLSupport.getStateCacheManager()->setTexParameteri(texTarget,
                                                            GL_TEXTURE_MIN_FILTER, ((mUsage & TU_AUTOMIPMAP) && mNumRequestedMipmaps) ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST);
        mGLSupport.getStateCacheManager()->setTexParameteri(texTarget,
                                                            GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        mGLSupport.getStateCacheManager()->setTexParameteri(texTarget,
                                                            GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        mGLSupport.getStateCacheManager()->setTexParameteri(texTarget,
                                                            GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        // Set up texture swizzling
#if OGRE_NO_GLES3_SUPPORT == 0
        if(gleswIsSupported(3, 0))
        {
            OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED));
            OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_GREEN));
            OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_BLUE));
            OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_ALPHA));

            if(mFormat == PF_L8 || mFormat == PF_L16)
            {
                OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED));
                OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_RED));
                OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_RED));
                OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_RED));
            }
        }
#endif

        // Allocate internal buffer so that glTexSubImageXD can be used
        // Internal format
        GLenum format = GLES2PixelUtil::getGLOriginFormat(mFormat);
        GLenum internalformat = GLES2PixelUtil::getClosestGLInternalFormat(mFormat, mHwGamma);
        uint32 width = mWidth;
        uint32 height = mHeight;
        uint32 depth = mDepth;
        
        if (PixelUtil::isCompressed(mFormat))
        {
            // Compressed formats
            GLsizei size = static_cast<GLsizei>(PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat));
            
            // Provide temporary buffer filled with zeroes as glCompressedTexImageXD does not
            // accept a 0 pointer like normal glTexImageXD
            // Run through this process for every mipmap to pregenerate mipmap pyramid
            
            uint8* tmpdata = new uint8[size];
            memset(tmpdata, 0, size);
            for (GLint mip = 0; mip <= mNumMipmaps; mip++)
            {
#if OGRE_DEBUG_MODE
                LogManager::getSingleton().logMessage("GLES2Texture::create - Mip: " + StringConverter::toString(mip) +
                                                      " Width: " + StringConverter::toString(width) +
                                                      " Height: " + StringConverter::toString(height) +
                                                      " Internal Format: " + StringConverter::toString(internalformat, 0, ' ', std::ios::hex) +
                                                      " Format: " + StringConverter::toString(format, 0, ' ', std::ios::hex)
                                                      );
#endif
                size = static_cast<GLsizei>(PixelUtil::getMemorySize(width, height, depth, mFormat));
                
                switch(mTextureType)
                {
                    case TEX_TYPE_1D:
                    case TEX_TYPE_2D:
                        OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_2D,
                                               mip,
                                               internalformat,
                                               width, height,
                                               0,
                                               size,
                                               tmpdata));
                        break;
                    case TEX_TYPE_CUBE_MAP:
                        for(int face = 0; face < 6; face++) {
                            OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, internalformat,
                                width, height, 0, 
                                size, tmpdata));
                        }
                        break;
#if OGRE_NO_GLES3_SUPPORT == 0
                    case TEX_TYPE_2D_ARRAY:
                    case TEX_TYPE_3D:
                        glCompressedTexImage3D(getGLES2TextureTarget(), mip, format,
                            width, height, depth, 0, 
                            size, tmpdata);
                        break;
#endif
                    default:
                        break;
                };
                
                if(width > 1)
                {
                    width = width / 2;
                }
                if(height > 1)
                {
                    height = height / 2;
                }
                if(depth > 1 && mTextureType != TEX_TYPE_2D_ARRAY)
                {
                    depth = depth / 2;
                }
            }
            delete [] tmpdata;
        }
        else
        {
#if OGRE_NO_GLES3_SUPPORT == 0
#if OGRE_DEBUG_MODE
            LogManager::getSingleton().logMessage("GLES2Texture::create - Name: " + mName +
                                                      " ID: " + StringConverter::toString(mTextureID) +
                                                      " Width: " + StringConverter::toString(width) +
                                                      " Height: " + StringConverter::toString(height) +
                                                      " Internal Format: " + StringConverter::toString(internalformat, 0, ' ', std::ios::hex));
#endif
            switch(mTextureType)
            {
                case TEX_TYPE_1D:
                case TEX_TYPE_2D:
                case TEX_TYPE_2D_RECT:
                    OGRE_CHECK_GL_ERROR(glTexStorage2D(GL_TEXTURE_2D, GLsizei(mNumMipmaps+1), internalformat, GLsizei(width), GLsizei(height)));
                    break;
                case TEX_TYPE_CUBE_MAP:
                    OGRE_CHECK_GL_ERROR(glTexStorage2D(GL_TEXTURE_CUBE_MAP, GLsizei(mNumMipmaps+1), internalformat, GLsizei(width), GLsizei(height)));
                    break;
                case TEX_TYPE_2D_ARRAY:
                    OGRE_CHECK_GL_ERROR(glTexStorage3D(GL_TEXTURE_2D_ARRAY, GLsizei(mNumMipmaps+1), internalformat, GLsizei(width), GLsizei(height), GLsizei(depth)));
                    break;
                case TEX_TYPE_3D:
                    OGRE_CHECK_GL_ERROR(glTexStorage3D(GL_TEXTURE_3D, GLsizei(mNumMipmaps+1), internalformat, GLsizei(width), GLsizei(height), GLsizei(depth)));
                    break;
            }
#else
            GLenum datatype = GLES2PixelUtil::getGLOriginDataType(mFormat);

            // Run through this process to pregenerate mipmap pyramid
            for(GLint mip = 0; mip <= mNumMipmaps; mip++)
            {
#if OGRE_DEBUG_MODE
                LogManager::getSingleton().logMessage("GLES2Texture::create - Mip: " + StringConverter::toString(mip) +
                                                      " Name: " + mName +
                                                      " ID: " + StringConverter::toString(mTextureID) +
                                                      " Width: " + StringConverter::toString(width) +
                                                      " Height: " + StringConverter::toString(height) +
                                                      " Internal Format: " + StringConverter::toString(internalformat, 0, ' ', std::ios::hex) +
                                                      " Format: " + StringConverter::toString(format, 0, ' ', std::ios::hex) +
                                                      " Datatype: " + StringConverter::toString(datatype, 0, ' ', std::ios::hex)
                                                      );
#endif
                // Normal formats
                switch(mTextureType)
                {
                    case TEX_TYPE_1D:
                    case TEX_TYPE_2D:
#if OGRE_PLATFORM == OGRE_PLATFORM_NACL
                        if(internalformat != format)
                        {
                            LogManager::getSingleton().logMessage("glTexImage2D: format != internalFormat, "
                                "format=" + StringConverter::toString(format) + 
                                ", internalFormat=" + StringConverter::toString(internalformat));
                        }
#endif
                        OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_2D,
                                     mip,
                                     internalformat,
                                     width, height,
                                     0,
                                     format,
                                     datatype, 0));
                        break;
                    case TEX_TYPE_CUBE_MAP:
                        for(int face = 0; face < 6; face++) {
                            OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, internalformat,
                                width, height, 0, 
                                format, datatype, 0));
                        }
                        break;
                    default:
                        break;
                };
                
                if (width > 1)
                {
                    width = Bitwise::firstPO2From(width / 2);
                }
                if (height > 1)
                {
                    height = Bitwise::firstPO2From(height / 2);
                }
            }
#endif
        }
    }
Example #12
0
bool Texture3D::SetData(unsigned level, int x, int y, int z, int width, int height, int depth, const void* data)
{
    if (!object_ || !graphics_)
    {
        LOGERROR("No texture created, can not set data");
        return false;
    }
    
    if (!data)
    {
        LOGERROR("Null source for setting data");
        return false;
    }
    
    if (level >= levels_)
    {
        LOGERROR("Illegal mip level for setting data");
        return false;
    }
    
    if (graphics_->IsDeviceLost())
    {
        LOGWARNING("Texture data assignment while device is lost");
        dataPending_ = true;
        return true;
    }
    
    if (IsCompressed())
    {
        x &= ~3;
        y &= ~3;
    }
    
    int levelWidth = GetLevelWidth(level);
    int levelHeight = GetLevelHeight(level);
    int levelDepth = GetLevelDepth(level);
    if (x < 0 || x + width > levelWidth || y < 0 || y + height > levelHeight || z < 0 || z + depth > levelDepth || width <= 0 || height <= 0 || depth <= 0)
    {
        LOGERROR("Illegal dimensions for setting data");
        return false;
    }
    
    graphics_->SetTextureForUpdate(this);
    
    bool wholeLevel = x == 0 && y == 0 && z == 0 && width == levelWidth && height == levelHeight && depth == levelDepth;
    unsigned format = GetSRGB() ? GetSRGBFormat(format_) : format_;
    
    #ifndef GL_ES_VERSION_2_0
    if (!IsCompressed())
    {
        if (wholeLevel)
            glTexImage3D(target_, level, format, width, height, depth, 0, GetExternalFormat(format_), GetDataType(format_), data);
        else
            glTexSubImage3D(target_, level, x, y, z, width, height, depth, GetExternalFormat(format_), GetDataType(format_), data);
    }
    else
    {
        if (wholeLevel)
            glCompressedTexImage3D(target_, level, format, width, height, depth, 0, GetDataSize(width, height, depth), data);
        else
            glCompressedTexSubImage3D(target_, level, x, y, z, width, height, depth, format, GetDataSize(width, height, depth), data);
    }
    #endif
    
    graphics_->SetTexture(0, 0);
    return true;
}
Example #13
0
/*
 * @~English
 * @brief Load a GL texture object from a ktxStream.
 *
 * This function will unpack compressed GL_ETC1_RGB8_OES and GL_ETC2_* format
 * textures in software when the format is not supported by the GL context,
 * provided the library has been compiled with SUPPORT_SOFTWARE_ETC_UNPACK
 * defined as 1.
 * 
 * It will also convert textures with legacy formats to their modern equivalents
 * when the format is not supported by the GL context, provided that the library
 * has been compiled with SUPPORT_LEGACY_FORMAT_CONVERSION defined as 1. 
 *
 * @param [in] stream		pointer to the ktxStream from which to load.
 * @param [in,out] pTexture	name of the GL texture to load. If NULL or if
 *                          <tt>*pTexture == 0</tt> the function will generate
 *                          a texture name. The function binds either the
 *                          generated name or the name given in @p *pTexture
 * 						    to the texture target returned in @p *pTarget,
 * 						    before loading the texture data. If @p pTexture
 *                          is not NULL and a name was generated, the generated
 *                          name will be returned in *pTexture.
 * @param [out] pTarget 	@p *pTarget is set to the texture target used. The
 * 						    target is chosen based on the file contents.
 * @param [out] pDimensions	If @p pDimensions is not NULL, the width, height and
 *							depth of the texture's base level are returned in the
 *                          fields of the KTX_dimensions structure to which it points.
 * @param [out] pIsMipmapped
 *	                        If @p pIsMipmapped is not NULL, @p *pIsMipmapped is set
 *                          to GL_TRUE if the KTX texture is mipmapped, GL_FALSE
 *                          otherwise.
 * @param [out] pGlerror    @p *pGlerror is set to the value returned by
 *                          glGetError when this function returns the error
 *                          KTX_GL_ERROR. glerror can be NULL.
 * @param [in,out] pKvdLen	If not NULL, @p *pKvdLen is set to the number of bytes
 *                          of key-value data pointed at by @p *ppKvd. Must not be
 *                          NULL, if @p ppKvd is not NULL.                     
 * @param [in,out] ppKvd	If not NULL, @p *ppKvd is set to the point to a block of
 *                          memory containing key-value data read from the file.
 *                          The application is responsible for freeing the memory.
 *
 *
 * @return	KTX_SUCCESS on success, other KTX_* enum values on error.
 *
 * @exception KTX_INVALID_VALUE @p target is @c NULL or the size of a mip
 * 							    level is greater than the size of the
 * 							    preceding level.
 * @exception KTX_INVALID_OPERATION @p ppKvd is not NULL but pKvdLen is NULL.
 * @exception KTX_UNEXPECTED_END_OF_FILE the file does not contain the
 * 										 expected amount of data.
 * @exception KTX_OUT_OF_MEMORY Sufficient memory could not be allocated to store
 *                              the requested key-value data.
 * @exception KTX_GL_ERROR      A GL error was raised by glBindTexture,
 * 								glGenTextures or gl*TexImage*. The GL error
 *                              will be returned in @p *glerror, if glerror
 *                              is not @c NULL.
 */
static
KTX_error_code
ktxLoadTextureS(struct ktxStream* stream, GLuint* pTexture, GLenum* pTarget,
				KTX_dimensions* pDimensions, GLboolean* pIsMipmapped,
				GLenum* pGlerror,
				unsigned int* pKvdLen, unsigned char** ppKvd)
{
	GLint				previousUnpackAlignment;
	KTX_header			header;
	KTX_texinfo			texinfo;
	void*				data = NULL;
	khronos_uint32_t	dataSize = 0;
	GLuint				texname;
	int					texnameUser;
	khronos_uint32_t    faceLodSize;
	khronos_uint32_t    faceLodSizeRounded;
	khronos_uint32_t	level;
	khronos_uint32_t	face;
	GLenum				glFormat, glInternalFormat;
	KTX_error_code		errorCode = KTX_SUCCESS;
	GLenum				errorTmp;

	if (pGlerror)
		*pGlerror = GL_NO_ERROR;

	if (ppKvd) {
		*ppKvd = NULL;
    }

	if (!stream || !stream->read || !stream->skip) {
		return KTX_INVALID_VALUE;
	}

	if (!pTarget) {
		return KTX_INVALID_VALUE;
	}

	if (!stream->read(&header, KTX_HEADER_SIZE, stream->src)) {
		return KTX_UNEXPECTED_END_OF_FILE;
	}

	errorCode = _ktxCheckHeader(&header, &texinfo);
	if (errorCode != KTX_SUCCESS) {
		return errorCode;
	}

	if (ppKvd) {
		if (pKvdLen == NULL)
			return KTX_INVALID_OPERATION;
		*pKvdLen = header.bytesOfKeyValueData;
		if (*pKvdLen) {
			*ppKvd = (unsigned char*)malloc(*pKvdLen);
			if (*ppKvd == NULL)
				return KTX_OUT_OF_MEMORY;
			if (!stream->read(*ppKvd, *pKvdLen, stream->src))
			{
				free(*ppKvd);
				*ppKvd = NULL;

				return KTX_UNEXPECTED_END_OF_FILE;
			}
		}
	} else {
		/* skip key/value metadata */
		if (!stream->skip((long)header.bytesOfKeyValueData, stream->src)) {
			return KTX_UNEXPECTED_END_OF_FILE;
		}
	}

	if (contextProfile == 0)
		discoverContextCapabilities();

	/* KTX files require an unpack alignment of 4 */
	glGetIntegerv(GL_UNPACK_ALIGNMENT, &previousUnpackAlignment);
	if (previousUnpackAlignment != KTX_GL_UNPACK_ALIGNMENT) {
		glPixelStorei(GL_UNPACK_ALIGNMENT, KTX_GL_UNPACK_ALIGNMENT);
	}

	texnameUser = pTexture && *pTexture;
	if (texnameUser) {
		texname = *pTexture;
	} else {
		glGenTextures(1, &texname);
	}
	glBindTexture(texinfo.glTarget, texname);

	// Prefer glGenerateMipmaps over GL_GENERATE_MIPMAP
	if (texinfo.generateMipmaps && (glGenerateMipmap == NULL)) {
		glTexParameteri(texinfo.glTarget, GL_GENERATE_MIPMAP, GL_TRUE);
	}

	if (texinfo.glTarget == GL_TEXTURE_CUBE_MAP) {
		texinfo.glTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
	}

	glInternalFormat = header.glInternalFormat;
	glFormat = header.glFormat;
	if (!texinfo.compressed) {
#if SUPPORT_LEGACY_FORMAT_CONVERSION
		// If sized legacy formats are supported there is no need to convert.
		// If only unsized formats are supported, there is no point in converting
		// as the modern formats aren't supported either.
		if (sizedFormats == _NON_LEGACY_FORMATS && supportsSwizzle) {
			convertFormat(texinfo.glTarget, &glFormat, &glInternalFormat);
			errorTmp = glGetError();
		} else if (sizedFormats == _NO_SIZED_FORMATS)
			glInternalFormat = header.glBaseInternalFormat;
#else
		// When no sized formats are supported, or legacy sized formats are not
		// supported, must change internal format.
		if (sizedFormats == _NO_SIZED_FORMATS
			|| (!(sizedFormats & _LEGACY_FORMATS) &&
				(header.glBaseInternalFormat == GL_ALPHA	
				|| header.glBaseInternalFormat == GL_LUMINANCE
				|| header.glBaseInternalFormat == GL_LUMINANCE_ALPHA
				|| header.glBaseInternalFormat == GL_INTENSITY))) {
			glInternalFormat = header.glBaseInternalFormat;
		}
#endif
	}

	for (level = 0; level < header.numberOfMipmapLevels; ++level)
	{
		GLsizei pixelWidth  = MAX(1, header.pixelWidth  >> level);
		GLsizei pixelHeight = MAX(1, header.pixelHeight >> level);
		GLsizei pixelDepth  = MAX(1, header.pixelDepth  >> level);

		if (!stream->read(&faceLodSize, sizeof(khronos_uint32_t), stream->src)) {
			errorCode = KTX_UNEXPECTED_END_OF_FILE;
			goto cleanup;
		}
		if (header.endianness == KTX_ENDIAN_REF_REV) {
			_ktxSwapEndian32(&faceLodSize, 1);
		}
		faceLodSizeRounded = (faceLodSize + 3) & ~(khronos_uint32_t)3;
		if (!data) {
			/* allocate memory sufficient for the first level */
			data = malloc(faceLodSizeRounded);
			if (!data) {
				errorCode = KTX_OUT_OF_MEMORY;
				goto cleanup;
			}
			dataSize = faceLodSizeRounded;
		}
		else if (dataSize < faceLodSizeRounded) {
			/* subsequent levels cannot be larger than the first level */
			errorCode = KTX_INVALID_VALUE;
			goto cleanup;
		}

		for (face = 0; face < header.numberOfFaces; ++face)
		{
			if (!stream->read(data, faceLodSizeRounded, stream->src)) {
				errorCode = KTX_UNEXPECTED_END_OF_FILE;
				goto cleanup;
			}

			/* Perform endianness conversion on texture data */
			if (header.endianness == KTX_ENDIAN_REF_REV && header.glTypeSize == 2) {
				_ktxSwapEndian16((khronos_uint16_t*)data, faceLodSize / 2);
			}
			else if (header.endianness == KTX_ENDIAN_REF_REV && header.glTypeSize == 4) {
				_ktxSwapEndian32((khronos_uint32_t*)data, faceLodSize / 4);
			}

			if (texinfo.textureDimensions == 1) {
				if (texinfo.compressed) {
					glCompressedTexImage1D(texinfo.glTarget + face, level, 
						glInternalFormat, pixelWidth, 0,
						faceLodSize, data);
				} else {
					glTexImage1D(texinfo.glTarget + face, level, 
						glInternalFormat, pixelWidth, 0, 
						glFormat, header.glType, data);
				}
			} else if (texinfo.textureDimensions == 2) {
				if (header.numberOfArrayElements) {
					pixelHeight = header.numberOfArrayElements;
				}
				if (texinfo.compressed) {
				    // It is simpler to just attempt to load the format, rather than divine which
					// formats are supported by the implementation. In the event of an error,
					// software unpacking can be attempted.
					glCompressedTexImage2D(texinfo.glTarget + face, level, 
						glInternalFormat, pixelWidth, pixelHeight, 0,
						faceLodSize, data);
				} else {
					glTexImage2D(texinfo.glTarget + face, level, 
						glInternalFormat, pixelWidth, pixelHeight, 0, 
						glFormat, header.glType, data);
				}
			} else if (texinfo.textureDimensions == 3) {
				if (header.numberOfArrayElements) {
					pixelDepth = header.numberOfArrayElements;
				}
				if (texinfo.compressed) {
					glCompressedTexImage3D(texinfo.glTarget + face, level, 
						glInternalFormat, pixelWidth, pixelHeight, pixelDepth, 0,
						faceLodSize, data);
				} else {
					glTexImage3D(texinfo.glTarget + face, level, 
						glInternalFormat, pixelWidth, pixelHeight, pixelDepth, 0, 
						glFormat, header.glType, data);
				}
			}

			errorTmp = glGetError();
#if SUPPORT_SOFTWARE_ETC_UNPACK
			// Renderion is returning INVALID_VALUE. Oops!!
			if ((errorTmp == GL_INVALID_ENUM || errorTmp == GL_INVALID_VALUE)
				&& texinfo.compressed
				&& texinfo.textureDimensions == 2
				&& (glInternalFormat == GL_ETC1_RGB8_OES || (glInternalFormat >= GL_COMPRESSED_R11_EAC && glInternalFormat <= GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC)))
			    {
				GLubyte* unpacked;
				GLenum format, internalFormat, type;

				errorCode = _ktxUnpackETC((GLubyte*)data, glInternalFormat, pixelWidth, pixelHeight,
					                      &unpacked, &format, &internalFormat, &type,
										  R16Formats, supportsSRGB);
				if (errorCode != KTX_SUCCESS) {
					goto cleanup;
				}
				if (!sizedFormats & _NON_LEGACY_FORMATS) {
					if (internalFormat == GL_RGB8)
						internalFormat = GL_RGB;
					else if (internalFormat == GL_RGBA8)
						internalFormat = GL_RGBA;
				}
				glTexImage2D(texinfo.glTarget + face, level, 
							 internalFormat, pixelWidth, pixelHeight, 0, 
							 format, type, unpacked);

				free(unpacked);
				errorTmp = glGetError();
			}
#endif
			if (errorTmp != GL_NO_ERROR) {
				if (pGlerror)
					*pGlerror = errorTmp;
				errorCode = KTX_GL_ERROR;
				goto cleanup;
			}
		}
	}

cleanup:
	free(data);

	/* restore previous GL state */
	if (previousUnpackAlignment != KTX_GL_UNPACK_ALIGNMENT) {
		glPixelStorei(GL_UNPACK_ALIGNMENT, previousUnpackAlignment);
	}

	if (errorCode == KTX_SUCCESS)
	{
		if (texinfo.generateMipmaps && glGenerateMipmap) {
			glGenerateMipmap(texinfo.glTarget);
		}
		*pTarget = texinfo.glTarget;
		if (pTexture) {
			*pTexture = texname;
		}
		if (pDimensions) {
			pDimensions->width = header.pixelWidth;
			pDimensions->height = header.pixelHeight;
			pDimensions->depth = header.pixelDepth;
		}
		if (pIsMipmapped) {
			if (texinfo.generateMipmaps || header.numberOfMipmapLevels > 1)
				*pIsMipmapped = GL_TRUE;
			else
				*pIsMipmapped = GL_FALSE;
		}
	} else {
		if (ppKvd && *ppKvd)
		{
			free(*ppKvd);
			*ppKvd = NULL;
		}

		if (!texnameUser) {
			glDeleteTextures(1, &texname);
		}
	}
	return errorCode;
}
Example #14
0
	void OGLESTexture2D::CreateHWResource(ElementInitData const * init_data)
	{
		uint32_t texel_size = NumFormatBytes(format_);

		GLint glinternalFormat;
		GLenum glformat;
		GLenum gltype;
		OGLESMapping::MappingFormat(glinternalFormat, glformat, gltype, format_);

		glBindTexture(target_type_, texture_);
		for (uint32_t array_index = 0; array_index < array_size_; ++ array_index)
		{
			for (uint32_t level = 0; level < num_mip_maps_; ++ level)
			{
				uint32_t const w = this->Width(level);
				uint32_t const h = this->Height(level);

				if (IsCompressedFormat(format_))
				{
					uint32_t const block_size = NumFormatBytes(format_) * 4;
					GLsizei const image_size = ((w + 3) / 4) * ((h + 3) / 4) * block_size;

					void* ptr;
					if (nullptr == init_data)
					{
						tex_data_[array_index * num_mip_maps_ + level].resize(image_size, 0);
						ptr = nullptr;
					}
					else
					{
						tex_data_[array_index * num_mip_maps_ + level].resize(image_size);
						std::memcpy(&tex_data_[array_index * num_mip_maps_ + level][0],
							init_data[array_index * num_mip_maps_ + level].data, image_size);
						ptr = &tex_data_[array_index * num_mip_maps_ + level][0];
					}

					if (array_size_ > 1)
					{
						if (0 == array_index)
						{
							glCompressedTexImage3D(target_type_, level, glinternalFormat,
								w, h, array_size_, 0, image_size * array_size_, nullptr);
						}

						if (init_data != nullptr)
						{
							glCompressedTexSubImage3D(target_type_, level, 0, 0, array_index, w, h, 1,
								glformat, image_size, init_data[array_index * num_mip_maps_ + level].data);
						}
					}
					else
					{
						glCompressedTexImage2D(target_type_, level, glinternalFormat,
							w, h, 0, image_size, ptr);
					}
				}
				else
				{
					GLsizei const image_size = w * h * texel_size;

					void* ptr;
					if (nullptr == init_data)
					{
						tex_data_[array_index * num_mip_maps_ + level].resize(image_size, 0);
						ptr = nullptr;
					}
					else
					{
						tex_data_[array_index * num_mip_maps_ + level].resize(image_size);
						std::memcpy(&tex_data_[array_index * num_mip_maps_ + level][0],
							init_data[array_index * num_mip_maps_ + level].data, image_size);
						ptr = &tex_data_[array_index * num_mip_maps_ + level][0];
					}

					if (array_size_ > 1)
					{
						if (0 == array_index)
						{
							glTexImage3D(target_type_, level, glinternalFormat, w, h, array_size_, 0, glformat, gltype, nullptr);
						}

						if (init_data != nullptr)
						{
							glTexSubImage3D(target_type_, level, 0, 0, array_index, w, h, 1,
								glformat, gltype, init_data[array_index * num_mip_maps_ + level].data);
						}
					}
					else
					{
						glTexImage2D(target_type_, level, glinternalFormat, w, h, 0, glformat, gltype, ptr);
					}
				}
			}
		}

		hw_res_ready_ = true;
	}
Example #15
0
void RenderDevice::uploadTextureData( uint32 texObj, int slice, int mipLevel, const void *pixels )
{
	const RDITexture &tex = _textures.getRef( texObj );
	TextureFormats::List format = tex.format;

    glActiveTexture( GL_TEXTURE0 );
	glBindTexture( tex.type, tex.glObj );
	
#ifdef PLATFORM_ES2
	int inputFormat = GL_RGBA, inputType = GL_UNSIGNED_BYTE;
#else
	int inputFormat = GL_BGRA, inputType = GL_UNSIGNED_BYTE;
#endif
	bool compressed = (format == TextureFormats::DXT1) || (format == TextureFormats::DXT3) || (format == TextureFormats::DXT5) || 
                        (format == TextureFormats::PVRTC2) || (format == TextureFormats::PVRTCA2) ||
                        (format == TextureFormats::PVRTC4) || (format == TextureFormats::PVRTCA4);
	
	switch( format )
	{
	case TextureFormats::RGBA16F:
		inputFormat = GL_RGBA;
#ifdef PLATFORM_ES2
        // GL_HALF_FLOAT_OES seems not to work on 3GS, 4G and iPad1
        // http://stackoverflow.com/questions/3850569/render-to-floating-point-texture-under-ios
        inputType = glExt::OES_texture_half_float ? GL_HALF_FLOAT_OES : GL_RGBA ;
#else
		inputType = GL_FLOAT;
#endif
		break;
	case TextureFormats::RGBA32F:
		inputFormat = GL_RGBA;
		inputType = GL_FLOAT;
		break;
	case TextureFormats::DEPTH:
		inputFormat = GL_DEPTH_COMPONENT;
#ifdef PLATFORM_ES2
		inputType = GL_UNSIGNED_SHORT;
#else
		inputType = GL_FLOAT;
#endif
    default:
        break;
	};
	
	// Calculate size of next mipmap using "floor" convention
	int width = std::max( tex.width >> mipLevel, 1 ), height = std::max( tex.height >> mipLevel, 1 );
	
	if ( (tex.type == TextureTypes::Tex2D && (width>_maxTextureSize || height>_maxTextureSize)) || 
		 (tex.type == TextureTypes::TexCube && (width>_maxCubeTextureSize || height>_maxCubeTextureSize)))
        goto UPLOADE_TEXUTURE_EXIT;//return;

	if( tex.type == TextureTypes::Tex2D || tex.type == TextureTypes::TexCube )
	{
		int target = (tex.type == TextureTypes::Tex2D) ? GL_TEXTURE_2D : (GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice);
		
		if( compressed )
			glCompressedTexImage2D( target, mipLevel, tex.glFmt, width, height, 0,
			                        calcTextureSize( format, width, height, 1 ), pixels );	
		else
			glTexImage2D( target, mipLevel, tex.glFmt, width, height, 0, inputFormat, inputType, pixels );
	}
	else if( tex.type == TextureTypes::Tex3D )
	{
#if !defined(PLATFORM_ES2)
		int depth = std::max( tex.depth >> mipLevel, 1 );
		
		if( compressed )
			glCompressedTexImage3D( GL_TEXTURE_3D, mipLevel, tex.glFmt, width, height, depth, 0,
			                        calcTextureSize( format, width, height, depth ), pixels );	
		else
			glTexImage3D( GL_TEXTURE_3D, mipLevel, tex.glFmt, width, height, depth, 0,
			              inputFormat, inputType, pixels );
#endif
	}
Example #16
0
	void OGLESTexture3D::CreateHWResource(ElementInitData const * init_data)
	{
		uint32_t texel_size = NumFormatBytes(format_);

		GLint glinternalFormat;
		GLenum glformat;
		GLenum gltype;
		OGLESMapping::MappingFormat(glinternalFormat, glformat, gltype, format_);

		glBindTexture(target_type_, texture_);
		for (uint32_t level = 0; level < num_mip_maps_; ++ level)
		{
			uint32_t const w = this->Width(level);
			uint32_t const h = this->Height(level);
			uint32_t const d = this->Depth(level);

			if (IsCompressedFormat(format_))
			{
				uint32_t const block_size = NumFormatBytes(format_) * 4;
				GLsizei const image_size = ((w + 3) / 4) * ((h + 3) / 4) * d * block_size;

				void* ptr;
				if (nullptr == init_data)
				{
					tex_data_[level].resize(image_size, 0);
					ptr = nullptr;
				}
				else
				{
					tex_data_[level].resize(image_size);
					std::memcpy(&tex_data_[level][0], init_data[level].data, image_size);
					ptr = &tex_data_[level][0];
				}
				if (glloader_GLES_VERSION_3_0())
				{
					glCompressedTexImage3D(target_type_, level, glinternalFormat,
						w, h, d, 0, image_size, ptr);
				}
				else
				{
					glCompressedTexImage3DOES(target_type_, level, glinternalFormat,
						w, h, d, 0, image_size, ptr);
				}
			}
			else
			{
				GLsizei const image_size = w * h * d * texel_size;

				void* ptr;
				if (nullptr == init_data)
				{
					tex_data_[level].resize(image_size, 0);
					ptr = nullptr;
				}
				else
				{
					tex_data_[level].resize(image_size);
					std::memcpy(&tex_data_[level][0], init_data[level].data, image_size);
					ptr = &tex_data_[level][0];
				}
				if (glloader_GLES_VERSION_3_0())
				{
					glTexImage3D(target_type_, level, glinternalFormat, w, h, d, 0, glformat, gltype, ptr);
				}
				else
				{
					glTexImage3DOES(target_type_, level, glinternalFormat, w, h, d, 0, glformat, gltype, ptr);
				}
			}
		}

		hw_res_ready_ = true;
	}
Example #17
0
// Compressed texture
void gl4es_glCompressedMultiTexImage3D(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) {
    text(glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data));
}
Example #18
0
	void GLTextureBuffer::upload(const PixelData &data, const PixelVolume &dest)
	{
		if((mUsage & TU_RENDERTARGET) != 0)
			BS_EXCEPT(NotImplementedException, "Writing to render texture from CPU not supported.");

		if ((mUsage & TU_DEPTHSTENCIL) != 0)
			BS_EXCEPT(NotImplementedException, "Writing to depth stencil texture from CPU not supported.");

		glBindTexture( mTarget, mTextureID );
		if(PixelUtil::isCompressed(data.getFormat()))
		{
			if(data.getFormat() != mFormat || !data.isConsecutive())
				BS_EXCEPT(InvalidParametersException, 
				"Compressed images must be consecutive, in the source format");

			GLenum format = GLPixelUtil::getClosestGLInternalFormat(mFormat);
			switch(mTarget) {
				case GL_TEXTURE_1D:
					if (dest.left == 0)
					{
						glCompressedTexImage1D(GL_TEXTURE_1D, mLevel,
							format,
							dest.getWidth(),
							0,
							data.getConsecutiveSize(),
							data.getData());
					}
					else
					{
						glCompressedTexSubImage1D(GL_TEXTURE_1D, mLevel, 
							dest.left,
							dest.getWidth(),
							format, data.getConsecutiveSize(),
							data.getData());
					}
					break;
				case GL_TEXTURE_2D:
				case GL_TEXTURE_CUBE_MAP:
					if (dest.left == 0 && dest.top == 0)
					{
						glCompressedTexImage2D(mFaceTarget, mLevel,
							format,
							dest.getWidth(),
							dest.getHeight(),
							0,
							data.getConsecutiveSize(),
							data.getData());
					}
					else
					{
						glCompressedTexSubImage2D(mFaceTarget, mLevel, 
							dest.left, dest.top, 
							dest.getWidth(), dest.getHeight(),
							format, data.getConsecutiveSize(),
							data.getData());
					}
					break;
				case GL_TEXTURE_3D:
					if (dest.left == 0 && dest.top == 0 && dest.front == 0)
					{
						glCompressedTexImage3D(GL_TEXTURE_3D, mLevel,
							format,
							dest.getWidth(),
							dest.getHeight(),
							dest.getDepth(),
							0,
							data.getConsecutiveSize(),
							data.getData());
					}
					else
					{			
						glCompressedTexSubImage3D(GL_TEXTURE_3D, mLevel, 
							dest.left, dest.top, dest.front,
							dest.getWidth(), dest.getHeight(), dest.getDepth(),
							format, data.getConsecutiveSize(),
							data.getData());
					}
					break;
			}
		
		} 
		else
		{
			if(data.getWidth() != data.getRowPitch())
				glPixelStorei(GL_UNPACK_ROW_LENGTH, data.getRowPitch());

			if(data.getHeight()*data.getWidth() != data.getSlicePitch())
				glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (data.getSlicePitch()/data.getWidth()));

			if(data.getLeft() > 0 || data.getTop() > 0 || data.getFront() > 0)
				glPixelStorei(GL_UNPACK_SKIP_PIXELS, data.getLeft() + data.getRowPitch() * data.getTop() + data.getSlicePitch() * data.getFront());

			if((data.getWidth()*PixelUtil::getNumElemBytes(data.getFormat())) & 3)
				glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

			switch(mTarget) {
				case GL_TEXTURE_1D:
					glTexSubImage1D(GL_TEXTURE_1D, mLevel, 
						dest.left,
						dest.getWidth(),
						GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()),
						data.getData());
					break;
				case GL_TEXTURE_2D:
				case GL_TEXTURE_CUBE_MAP:
					glTexSubImage2D(mFaceTarget, mLevel, 
						dest.left, dest.top, 
						dest.getWidth(), dest.getHeight(),
						GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()),
						data.getData());
					break;
				case GL_TEXTURE_3D:
					glTexSubImage3D(
						GL_TEXTURE_3D, mLevel, 
						dest.left, dest.top, dest.front,
						dest.getWidth(), dest.getHeight(), dest.getDepth(),
						GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()),
						data.getData());
					break;
			}	
		}

		// Restore defaults
		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
		glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

		BS_INC_RENDER_STAT_CAT(ResWrite, RenderStatObject_Texture);
	}
Example #19
0
    // Creation / loading methods
    void GL3PlusTexture::createInternalResourcesImpl(void)
    {
        // set HardwareBuffer::Usage for TU_RENDERTARGET if nothing else specified
        if((mUsage & TU_RENDERTARGET) && (mUsage & ~TU_RENDERTARGET) == 0)
            mUsage |= HardwareBuffer::HBU_DYNAMIC;

        // Adjust format if required.
        mFormat = TextureManager::getSingleton().getNativeFormat(mTextureType, mFormat, mUsage);

        // Check requested number of mipmaps.
        uint32 maxMips = getMaxMipmaps();

        if (PixelUtil::isCompressed(mFormat) && (mNumMipmaps == 0))
            mNumRequestedMipmaps = 0;

        mNumMipmaps = mNumRequestedMipmaps;
        if (mNumMipmaps > maxMips)
            mNumMipmaps = maxMips;

        // Create a texture object and identify its GL type.
        OGRE_CHECK_GL_ERROR(glGenTextures(1, &mTextureID));
        GLenum texTarget = getGL3PlusTextureTarget();

        // Calculate size for all mip levels of the texture.
        uint32 width, height, depth;

        if ((mWidth * PixelUtil::getNumElemBytes(mFormat)) & 3) {
            // Standard alignment of 4 is not right for some formats.
            OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
        }

        // Bind texture object to its type, making it the active texture object
        // for that type.
        mRenderSystem->_getStateCacheManager()->bindGLTexture( texTarget, mTextureID );

        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_BASE_LEVEL, 0);
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_MAX_LEVEL, mNumMipmaps);

        // Set some misc default parameters, these can of course be changed later.
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget,
                                            GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget,
                                            GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget,
                                            GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget,
                                            GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        // Set up texture swizzling.
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED);
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
	
        if (PixelUtil::isLuminance(mFormat) && (mRenderSystem->hasMinGLVersion(3, 3) || mRenderSystem->checkExtension("GL_ARB_texture_swizzle")))
        {
            if (PixelUtil::getComponentCount(mFormat) == 2)
            {
                mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED);
                mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_RED);
                mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_RED);
                mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_GREEN);
            }
            else
            {
                mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED);
                mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_RED);
                mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_RED);
                mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_ONE);
            }
        }

        GLenum format = GL3PlusPixelUtil::getGLInternalFormat(mFormat, mHwGamma);
        GLenum datatype = GL3PlusPixelUtil::getGLOriginDataType(mFormat);
        width = mWidth;
        height = mHeight;
        depth = mDepth;

        // Allocate texture storage so that glTexSubImageXD can be
        // used to upload the texture.
        if (PixelUtil::isCompressed(mFormat))
        {
            // Compressed formats
            GLsizei size;

            for (uint32 mip = 0; mip <= mNumMipmaps; mip++)
            {
                size = static_cast<GLsizei>(PixelUtil::getMemorySize(width, height, depth, mFormat));
                // std::stringstream str;
                // str << "GL3PlusTexture::create - " << StringConverter::toString(mTextureID)
                // << " bytes: " << StringConverter::toString(PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat))
                // << " Mip: " + StringConverter::toString(mip)
                // << " Width: " << StringConverter::toString(width)
                // << " Height: " << StringConverter::toString(height)
                // << " Format " << PixelUtil::getFormatName(mFormat)
                // << " Internal Format: 0x" << std::hex << format
                // << " Origin Format: 0x" << std::hex << GL3PlusPixelUtil::getGLOriginFormat(mFormat)
                // << " Data type: 0x" << std::hex << datatype;
                // LogManager::getSingleton().logMessage(LML_NORMAL, str.str());

                switch(mTextureType)
                {
                case TEX_TYPE_1D:
                    OGRE_CHECK_GL_ERROR(glCompressedTexImage1D(GL_TEXTURE_1D, mip, format,
                                                               width, 0,
                                                               size, NULL));
                    break;
                case TEX_TYPE_2D:
                    OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_2D,
                                                               mip,
                                                               format,
                                                               width, height,
                                                               0,
                                                               size,
                                                               NULL));
                    break;
                case TEX_TYPE_2D_RECT:
                    OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_RECTANGLE,
                                                               mip,
                                                               format,
                                                               width, height,
                                                               0,
                                                               size,
                                                               NULL));
                    break;
                case TEX_TYPE_2D_ARRAY:
                case TEX_TYPE_3D:
                    OGRE_CHECK_GL_ERROR(glCompressedTexImage3D(texTarget, mip, format,
                                                               width, height, depth, 0,
                                                               size, NULL));
                    break;
                case TEX_TYPE_CUBE_MAP:
                    for(int face = 0; face < 6; face++) {
                        OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format,
                                                                   width, height, 0,
                                                                   size, NULL));
                    }
                    break;
                default:
                    break;
                };

                if (width > 1)
                {
                    width = width / 2;
                }
                if (height > 1)
                {
                    height = height / 2;
                }
                if (depth > 1 && mTextureType != TEX_TYPE_2D_ARRAY)
                {
                    depth = depth / 2;
                }
            }
        }
        else
        {
            if (mRenderSystem->hasMinGLVersion(4, 2) || mRenderSystem->checkExtension("GL_ARB_texture_storage"))
            {
                switch(mTextureType)
                {
                case TEX_TYPE_1D:
                    OGRE_CHECK_GL_ERROR(glTexStorage1D(GL_TEXTURE_1D, GLsizei(mNumMipmaps+1), format, GLsizei(width)));
                    break;
                case TEX_TYPE_2D:
                case TEX_TYPE_2D_RECT:
                    OGRE_CHECK_GL_ERROR(glTexStorage2D(GL_TEXTURE_2D, GLsizei(mNumMipmaps+1), format, GLsizei(width), GLsizei(height)));
                    break;
                case TEX_TYPE_CUBE_MAP:
                    OGRE_CHECK_GL_ERROR(glTexStorage2D(GL_TEXTURE_CUBE_MAP, GLsizei(mNumMipmaps+1), format, GLsizei(width), GLsizei(height)));
                    break;
                case TEX_TYPE_2D_ARRAY:
                    OGRE_CHECK_GL_ERROR(glTexStorage3D(GL_TEXTURE_2D_ARRAY, GLsizei(mNumMipmaps+1), format, GLsizei(width), GLsizei(height), GLsizei(depth)));
                    break;
                case TEX_TYPE_3D:
                    OGRE_CHECK_GL_ERROR(glTexStorage3D(GL_TEXTURE_3D, GLsizei(mNumMipmaps+1), format, GLsizei(width), GLsizei(height), GLsizei(depth)));
                    break;
                }
            }
            else
            {
                GLenum originFormat = GL3PlusPixelUtil::getGLOriginFormat(mFormat);

                // Run through this process to pregenerate mipmap pyramid
                for(uint32 mip = 0; mip <= mNumMipmaps; mip++)
                {
                    //                    std::stringstream str;
                    //                    str << "GL3PlusTexture::create - " << StringConverter::toString(mTextureID)
                    //                    << " bytes: " << StringConverter::toString(PixelUtil::getMemorySize(width, height, depth, mFormat))
                    //                    << " Mip: " + StringConverter::toString(mip)
                    //                    << " Width: " << StringConverter::toString(width)
                    //                    << " Height: " << StringConverter::toString(height)
                    //                    << " Format " << PixelUtil::getFormatName(mFormat)
                    //                    << " Internal Format: 0x" << std::hex << format
                    //                    << " Origin Format: 0x" << std::hex << GL3PlusPixelUtil::getGLOriginFormat(mFormat)
                    //                    << " Data type: 0x" << std::hex << datatype;
                    //                    LogManager::getSingleton().logMessage(LML_NORMAL, str.str());

                    // Normal formats
                    switch(mTextureType)
                    {
                    case TEX_TYPE_1D:
                        OGRE_CHECK_GL_ERROR(glTexImage1D(GL_TEXTURE_1D, mip, format,
                                                         width, 0,
                                                         originFormat, datatype, NULL));
                        break;
                    case TEX_TYPE_2D:
                        OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_2D,
                                                         mip,
                                                         format,
                                                         width, height,
                                                         0,
                                                         originFormat,
                                                         datatype, NULL));
                        break;
                    case TEX_TYPE_2D_RECT:
                        OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_RECTANGLE,
                                                         mip,
                                                         format,
                                                         width, height,
                                                         0,
                                                         originFormat,
                                                         datatype, NULL));
                        break;
                    case TEX_TYPE_3D:
                    case TEX_TYPE_2D_ARRAY:
                        OGRE_CHECK_GL_ERROR(glTexImage3D(texTarget, mip, format,
                                                         width, height, depth, 0,
                                                         originFormat, datatype, NULL));
                        break;
                    case TEX_TYPE_CUBE_MAP:
                        for(int face = 0; face < 6; face++) {
                            OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format,
                                                             width, height, 0,
                                                             originFormat, datatype, NULL));
                        }
                        break;
                    default:
                        break;
                    };

                    if (width > 1)
                    {
                        width = width / 2;
                    }
                    if (height > 1)
                    {
                        height = height / 2;
                    }
                    if (depth > 1 && mTextureType != TEX_TYPE_2D_ARRAY)
                    {
                        depth = depth / 2;
                    }
                }
            }
        }

        // Reset unpack alignment to defaults
        OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_ALIGNMENT, 4));

        _createSurfaceList();

        // Generate mipmaps after all texture levels have been loaded
        // This is required for compressed formats such as DXT
        if (PixelUtil::isCompressed(mFormat) && mUsage & TU_AUTOMIPMAP)
        {
            OGRE_CHECK_GL_ERROR(glGenerateMipmap(getGL3PlusTextureTarget()));
        }

        // Get final internal format.
        mFormat = getBuffer(0,0)->getFormat();
    }
Example #20
0
    // Creation / loading methods
    void GL3PlusTexture::createInternalResourcesImpl(void)
    {
		// Adjust format if required
        mFormat = TextureManager::getSingleton().getNativeFormat(mTextureType, mFormat, mUsage);

		// Check requested number of mipmaps
        size_t maxMips = GL3PlusPixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat);

        if(PixelUtil::isCompressed(mFormat) && (mNumMipmaps == 0))
            mNumRequestedMipmaps = 0;

        mNumMipmaps = mNumRequestedMipmaps;
        if (mNumMipmaps > maxMips)
            mNumMipmaps = maxMips;

		// Generate texture name
        OGRE_CHECK_GL_ERROR(glGenTextures(1, &mTextureID));
        GLenum texTarget = getGL3PlusTextureTarget();

		// Set texture type
        OGRE_CHECK_GL_ERROR(glBindTexture(texTarget, mTextureID));

        OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_BASE_LEVEL, 0));
        OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_MAX_LEVEL, (mMipmapsHardwareGenerated && (mUsage & TU_AUTOMIPMAP)) ? maxMips : mNumMipmaps ));
        // Set some misc default parameters, these can of course be changed later
        OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget,
                                            GL_TEXTURE_MIN_FILTER, GL_NEAREST));
        OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget,
                                            GL_TEXTURE_MAG_FILTER, GL_NEAREST));
        OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget,
                                            GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
        OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget,
                                            GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));

        // Set up texture swizzling
        if(mGLSupport.checkExtension("GL_ARB_texture_swizzle") || gl3wIsSupported(3, 3))
        {
            OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED));
            OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_GREEN));
            OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_BLUE));
            OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_ALPHA));

            if(mFormat == PF_BYTE_LA)
            {
                OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED));
                OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_RED));
                OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_RED));
                OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_GREEN));
            }
            else if(mFormat == PF_L8 || mFormat == PF_L16)
            {
                OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED));
                OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_RED));
                OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_RED));
                OGRE_CHECK_GL_ERROR(glTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_RED));
            }
        }

		// If we can do automip generation and the user desires this, do so
        mMipmapsHardwareGenerated =
            Root::getSingleton().getRenderSystem()->getCapabilities()->hasCapability(RSC_AUTOMIPMAP);

        // Allocate internal buffer so that glTexSubImageXD can be used
        // Internal format
        GLenum format = GL3PlusPixelUtil::getClosestGLInternalFormat(mFormat, mHwGamma);
        GLenum datatype = GL3PlusPixelUtil::getGLOriginDataType(mFormat);
        size_t width = mWidth;
        size_t height = mHeight;
        size_t depth = mDepth;

        if (PixelUtil::isCompressed(mFormat))
        {
            // Compressed formats
            size_t size = PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);

            // Provide temporary buffer filled with zeroes as glCompressedTexImageXD does not
            // accept a 0 pointer like normal glTexImageXD
            // Run through this process for every mipmap to pregenerate mipmap pyramid

            uint8* tmpdata = new uint8[size];
            memset(tmpdata, 0, size);
            for (size_t mip = 0; mip <= mNumMipmaps; mip++)
            {
                size = PixelUtil::getMemorySize(width, height, depth, mFormat);

				switch(mTextureType)
				{
					case TEX_TYPE_1D:
						OGRE_CHECK_GL_ERROR(glCompressedTexImage1D(GL_TEXTURE_1D, mip, format, 
							width, 0, 
							size, tmpdata));
						break;
					case TEX_TYPE_2D:
                        OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_2D,
                                               mip,
                                               format,
                                               width, height,
                                               0,
                                               size,
                                               tmpdata));
                        break;
					case TEX_TYPE_2D_RECT:
                        OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_RECTANGLE,
                                               mip,
                                               format,
                                               width, height,
                                               0,
                                               size,
                                               tmpdata));
                        break;
					case TEX_TYPE_2D_ARRAY:
					case TEX_TYPE_3D:
						OGRE_CHECK_GL_ERROR(glCompressedTexImage3D(texTarget, mip, format,
							width, height, depth, 0, 
							size, tmpdata));
						break;
					case TEX_TYPE_CUBE_MAP:
						for(int face = 0; face < 6; face++) {
							OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format,
								width, height, 0, 
								size, tmpdata));
						}
						break;
                    default:
                        break;
                };
//                LogManager::getSingleton().logMessage("GL3PlusTexture::create - " + StringConverter::toString(mTextureID) +
//                                                      " Mip: " + StringConverter::toString(mip) +
//                                                      " Width: " + StringConverter::toString(width) +
//                                                      " Height: " + StringConverter::toString(height) +
//                                                      " Internal Format: " + StringConverter::toString(format)
//                                                      );

                if(width > 1)
                {
                    width = width / 2;
                }
                if(height > 1)
                {
                    height = height / 2;
                }
                if(depth > 1)
                {
                    depth = depth / 2;
                }
            }
            delete [] tmpdata;
        }
        else
        {
            if((mGLSupport.checkExtension("GL_ARB_texture_storage") || gl3wIsSupported(4, 2)) && mTextureType == TEX_TYPE_2D)
            {
                OGRE_CHECK_GL_ERROR(glTexStorage2D(GL_TEXTURE_2D, GLint(mNumMipmaps+1), format, GLsizei(width), GLsizei(height)));
            }
            else
            {
                // Run through this process to pregenerate mipmap pyramid
                for(size_t mip = 0; mip <= mNumMipmaps; mip++)
                {
                    // Normal formats
                    switch(mTextureType)
                    {
                        case TEX_TYPE_1D:
                            OGRE_CHECK_GL_ERROR(glTexImage1D(GL_TEXTURE_1D, mip, format,
                                width, 0, 
                                GL_RGBA, datatype, 0));
                            break;
                        case TEX_TYPE_2D:
                            OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_2D,
                                         mip,
                                         format,
                                         width, height,
                                         0,
                                         GL3PlusPixelUtil::getGLOriginFormat(mFormat),
                                         datatype, 0));
                            break;
                        case TEX_TYPE_2D_RECT:
                            OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_RECTANGLE,
                                         mip,
                                         format,
                                         width, height,
                                         0,
                                         GL3PlusPixelUtil::getGLOriginFormat(mFormat),
                                         datatype, 0));
                            break;
                        case TEX_TYPE_3D:
                        case TEX_TYPE_2D_ARRAY:
                            OGRE_CHECK_GL_ERROR(glTexImage3D(texTarget, mip, format,
                                width, height, depth, 0, 
                                GL_RGBA, datatype, 0));
                            break;
                        case TEX_TYPE_CUBE_MAP:
                            for(int face = 0; face < 6; face++) {
                                OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format,
                                    width, height, 0, 
                                     GL3PlusPixelUtil::getGLOriginFormat(mFormat), datatype, 0));
                            }
                            break;
                        default:
                            break;
                    };

                    if (width > 1)
                    {
                        width = width / 2;
                    }
                    if (height > 1)
                    {
                        height = height / 2;
                    }
                    if (depth > 1)
                    {
                        depth = depth / 2;
                    }
                }
            }
        }

        _createSurfaceList();

        // Get final internal format
        mFormat = getBuffer(0,0)->getFormat();
    }
Example #21
0
void Texture::update()
{
    io::Image::TextureType textureType = image->getTextureType();
    target = targetTable[textureType];
    unsigned format = formatTable[image->getChannelFormat()];
    unsigned type = typeTable[image->getDataType()];
    unsigned mipmaps = image->getMipmapCount();
    unsigned internalFormat = internalFormatTable[image->getDataType()][image->getChannelFormat()];

    if (srgbColorspace)
    {
        unsigned internalFormatSRGB = internalFormatTableSRGB[image->getDataType()][image->getChannelFormat()];
        if (internalFormatSRGB)
        {
#if defined(SOFA_HAVE_GLEW) && defined(GLEW_EXT_texture_sRGB) && defined(GLEW_ARB_framebuffer_sRGB)
            if (GLEW_EXT_texture_sRGB && GLEW_ARB_framebuffer_sRGB)
                internalFormat = internalFormatSRGB;
            else
#endif
            {
                msg_error("Texture")
                        << "SRGB colorspace is unsupported, GLEW_EXT_texture_srgb or GLEW_ARB_framebuffer_sRGB is missing." ;
            }
        }
        else
        {
             msg_error("Texture")
                     << "SRGB colorspace isn't supported with the given texture format." ;
        }
    }

    glBindTexture(target, id);
    glPixelStorei(GL_PACK_ALIGNMENT,1);
    switch (textureType)
    {
    case io::Image::TEXTURE_2D:
#if defined(SOFA_HAVE_GLEW) && defined(GLEW_VERSION_1_3)
        if (image->getDataType() == io::Image::UCOMPRESSED)
            for (unsigned i = 0; i < mipmaps; i++)
                glCompressedTexImage2D(target, i, internalFormat, image->getWidth(i), image->getHeight(i), 0,
                        image->getMipmapSize(i), image->getMipmapPixels(i));
        else
#endif
            for (unsigned i = 0; i < mipmaps; i++)
                glTexImage2D(target, i, internalFormat, image->getWidth(i), image->getHeight(i), 0,
                        format, type, image->getMipmapPixels(i));
        break;

    case io::Image::TEXTURE_3D:
#if defined(SOFA_HAVE_GLEW) && defined(GLEW_VERSION_1_2)
#if defined(SOFA_HAVE_GLEW) && defined(GLEW_VERSION_1_3)
        if (image->getDataType() == io::Image::UCOMPRESSED)
            for (unsigned i = 0; i < mipmaps; i++)
                glCompressedTexImage3D(target, i, internalFormat, image->getWidth(i), image->getHeight(i),
                        image->getDepth(i), 0, image->getMipmapSize(i), image->getMipmapPixels(i));
        else
#endif
            for (unsigned i = 0; i < mipmaps; i++)
                glTexImage3D(target, i, internalFormat, image->getWidth(i), image->getHeight(i),
                        image->getDepth(i), 0, format, type, image->getMipmapPixels(i));
#endif
        break;

    case io::Image::TEXTURE_CUBE:
#if defined(SOFA_HAVE_GLEW) && defined(GLEW_VERSION_1_3)
        if (image->getDataType() == io::Image::UCOMPRESSED)
            for (unsigned j = 0; j < 6; j++)
                for (unsigned i = 0; i < mipmaps; i++)
                    glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, i, internalFormat,
                            image->getWidth(i), image->getHeight(i), 0, image->getMipmapSize(i) / 6,
                            (image->getPixels())? image->getCubeMipmapPixels(j, i) : 0);
        else
            for (unsigned j = 0; j < 6; j++)
                for (unsigned i = 0; i < mipmaps; i++)
                    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, i, internalFormat,
                            image->getWidth(i), image->getHeight(i), 0, format, type,
                            (image->getPixels())? image->getCubeMipmapPixels(j, i) : 0);
#endif
        break;

    default:;
    }
    glPixelStorei(GL_PACK_ALIGNMENT, 4);

}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL13_nglCompressedTexImage3DBO(JNIEnv *env, jclass clazz, jint target, jint level, jint internalformat, jint width, jint height, jint depth, jint border, jint imageSize, jlong data_buffer_offset, jlong function_pointer) {
	const GLvoid *data_address = (const GLvoid *)(intptr_t)offsetToPointer(data_buffer_offset);
	glCompressedTexImage3DPROC glCompressedTexImage3D = (glCompressedTexImage3DPROC)((intptr_t)function_pointer);
	glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data_address);
}
Example #23
0
bool	Texture :: load3D ( const char * fileName )
{
	TexImage * image = loadTexImage ( fileName );
	
	if ( image == NULL )
		return false;
		
	if ( image -> getImageType () != TexImage :: image3D )
	{
		delete image;
		
		return false;
	}
	
	setParamsFromTexImage ( image, GL_TEXTURE_3D );
	
	glGenTextures   ( 1, &id );
    glBindTexture   ( target, id );
    glPixelStorei   ( GL_UNPACK_ALIGNMENT, 1 );                         // set 1-byte alignment
    glTexParameteri ( target, GL_TEXTURE_WRAP_S, GL_REPEAT );    // set default params for texture
    glTexParameteri ( target, GL_TEXTURE_WRAP_T, GL_REPEAT );
    glTexParameteri ( target, GL_TEXTURE_WRAP_R, GL_REPEAT );

	if ( !image -> isCompressed () )			// not compressed image
	{
		glTexImage3D ( target, 0, getFormat ().getInternalFormat (), width, height, depth, 0, getFormat ().getFormat (), image -> getGlType (), image -> imageData () );	

		if ( autoMipmaps )
			glGenerateMipmap ( target );
	}
	else
	{
		int	mipmaps = image -> getNumLevels ();
		int	w       = width;
		int	h       = height;
		int	d       = depth;
		byte * ptr  = image -> imageData ( 0,  0 );
		
//		glTexParameteri  ( target, GL_TEXTURE_MAX_LEVEL, mipmaps - 1 );
		
		for ( int i = 0; i < mipmaps; i++ )
		{
			int	size = image -> imageDataSize ( 0, i );
			
			glCompressedTexImage3D ( target, i, getFormat ().getInternalFormat (), w, h, d, 0, size, ptr );

			if ( ( w = w / 2 ) < 1 )
				w = 1;
			
			if ( ( h = h / 2 ) < 1 )
				h = 1;
				
			if ( ( d = d / 2 ) < 1 )
				d = 1;
				
			ptr += size;
		}
	}
	
    if ( autoMipmaps )
    {
        glTexParameteri ( target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
        glTexParameteri ( target, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    }
    else
    {
        glTexParameteri ( target, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        glTexParameteri ( target, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    }
	
    glBindTexture  ( target, 0 );

	delete image;
	
	return true;
}