Example #1
0
void TextureBuilder::PrepareSurface()
{
	if (m_prepared) return;

	if (!m_surface && m_filename.length() > 0)
		LoadSurface();

	TextureFormat targetTextureFormat;
	SDL_PixelFormat *targetPixelFormat;
	bool needConvert = !GetTargetFormat(m_surface->format, &targetTextureFormat, &targetPixelFormat, m_forceRGBA);

	if (needConvert) {
		SDL_Surface *s = SDL_ConvertSurface(m_surface, targetPixelFormat, SDL_SWSURFACE);
		SDL_FreeSurface(m_surface);
		m_surface = s;
	}

	unsigned int virtualWidth, actualWidth, virtualHeight, actualHeight;
	virtualWidth = actualWidth = m_surface->w;
	virtualHeight = actualHeight = m_surface->h;

	if (m_potExtend) {
		// extend to power-of-two if necessary
		actualWidth = ceil_pow2(m_surface->w);
		actualHeight = ceil_pow2(m_surface->h);
		if (actualWidth != virtualWidth || actualHeight != virtualHeight) {
			SDL_Surface *s = SDL_CreateRGBSurface(SDL_SWSURFACE, actualWidth, actualHeight, targetPixelFormat->BitsPerPixel,
				targetPixelFormat->Rmask, targetPixelFormat->Gmask, targetPixelFormat->Bmask, targetPixelFormat->Amask);

			SDL_SetAlpha(m_surface, 0, 0);
			SDL_SetAlpha(s, 0, 0);
			SDL_BlitSurface(m_surface, 0, s, 0);

			SDL_FreeSurface(m_surface);
			m_surface = s;
		}
	}

	else if (m_filename.length() > 0) {
		// power-of-to check
		unsigned long width = ceil_pow2(m_surface->w);
		unsigned long height = ceil_pow2(m_surface->h);

		if (width != virtualWidth || height != virtualHeight)
			fprintf(stderr, "WARNING: texture '%s' is not power-of-two and may not display correctly\n", m_filename.c_str());
	}

	m_descriptor = TextureDescriptor(
		targetTextureFormat,
		vector2f(actualWidth,actualHeight),
		vector2f(float(virtualWidth)/float(actualWidth),float(virtualHeight)/float(actualHeight)),
		m_sampleMode, m_generateMipmaps);
	
	m_prepared = true;
}
Example #2
0
Mesh item3DImage(TextureDescriptor td, float thickness)
{
    assert(td);
    assert(td.maxU <= 1 && td.minU >= 0 && td.maxV <= 1 && td.minV >= 0);
    Image image = td.image;
    unsigned iw = image.width();
    unsigned ih = image.height();
    float fMinX = iw * td.minU;
    float fMaxX = iw * td.maxU;
    float fMinY = ih * (1 - td.maxV);
    float fMaxY = ih * (1 - td.minV);
    int minX = ifloor(1e-5f + fMinX);
    int maxX = ifloor(-1e-5f + fMaxX);
    int minY = ifloor(1e-5f + fMinY);
    int maxY = ifloor(-1e-5f + fMaxY);
    assert(minX <= maxX && minY <= maxY);
    float scale = std::min<float>(1.0f / (1 + maxX - minX), 1.0f / (1 + maxY - minY));
    if(thickness <= 0)
        thickness = scale;
    TextureDescriptor backTD = td;
    backTD.maxU = td.minU;
    backTD.minU = td.maxU;
    float faceMinX = scale * (fMinX - minX);
    float faceMinY = scale * (maxY - fMaxY + 1);
    float faceMaxX = faceMinX + scale * (fMaxX - fMinX);
    float faceMaxY = faceMinY + scale * (fMaxY - fMinY);
    Mesh retval = transform(Matrix::translate(faceMinX, faceMinY, -0.5f).concat(Matrix::scale(faceMaxX - faceMinX, faceMaxY - faceMinY, thickness)), unitBox(TextureDescriptor(), TextureDescriptor(), TextureDescriptor(), TextureDescriptor(), backTD, td));
    for(int iy = minY; iy <= maxY; iy++)
    {
        for(int ix = minX; ix <= maxX; ix++)
        {
            bool transparent = isPixelTransparent(image.getPixel(ix, iy));
            if(transparent)
                continue;
            bool transparentNIX = true, transparentPIX = true, transparentNIY = true, transparentPIY = true; // image transparent for negative and positive image coordinates
            if(ix > minX)
                transparentNIX = isPixelTransparent(image.getPixel(ix - 1, iy));
            if(ix < maxX)
                transparentPIX = isPixelTransparent(image.getPixel(ix + 1, iy));
            if(iy > minY)
                transparentNIY = isPixelTransparent(image.getPixel(ix, iy - 1));
            if(iy < maxY)
                transparentPIY = isPixelTransparent(image.getPixel(ix, iy + 1));
            float pixelU = (ix + 0.5f) / iw;
            float pixelV = 1.0f - (iy + 0.5f) / ih;
            TextureDescriptor pixelTD = TextureDescriptor(image, pixelU, pixelU, pixelV, pixelV);
            TextureDescriptor nx, px, ny, py;
            if(transparentNIX)
                nx = pixelTD;
            if(transparentPIX)
                px = pixelTD;
            if(transparentNIY)
                py = pixelTD;
            if(transparentPIY)
                ny = pixelTD;
            Matrix tform = Matrix::translate(static_cast<float>(ix - minX), static_cast<float>(maxY - iy), -0.5f).concat(Matrix::scale(scale, scale, thickness));
            retval.append(transform(tform, unitBox(nx, px, ny, py, TextureDescriptor(), TextureDescriptor())));
        }
    }
    return std::move(retval);
}
Example #3
0
void TextureBuilder::PrepareSurface()
{
	if (m_prepared) return;

	if (!m_surface && !m_filename.empty()) {
		std::string filename = m_filename;
		std::transform(filename.begin(), filename.end(), filename.begin(), ::tolower);
		if (ends_with_ci(filename, ".dds")) {
			LoadDDS();
		} else {
			LoadSurface();
		}
	}

	TextureFormat targetTextureFormat;
	unsigned int virtualWidth, actualWidth, virtualHeight, actualHeight, numberOfMipMaps = 0, numberOfImages = 1;
	if( m_surface ) {
		SDL_PixelFormat *targetPixelFormat;
		bool needConvert = !GetTargetFormat(m_surface->format, &targetTextureFormat, &targetPixelFormat, m_forceRGBA);

		if (needConvert) {
			if(m_textureType == TEXTURE_2D) {
				SDL_Surface *s = SDL_ConvertSurface(m_surface.Get(), targetPixelFormat, SDL_SWSURFACE);
				m_surface = SDLSurfacePtr::WrapNew(s);
			} else if(m_textureType == TEXTURE_CUBE_MAP) {
				assert(m_cubemap.size() == 6);
				for(unsigned int i = 0; i < 6; ++i) {
					SDL_Surface *s = SDL_ConvertSurface(m_cubemap[i].Get(), targetPixelFormat, SDL_SWSURFACE);
					m_cubemap[i] = SDLSurfacePtr::WrapNew(s);
				}
			} else {
				// Unknown texture type
				assert(0);
			}
		}

		virtualWidth = actualWidth = m_surface->w;
		virtualHeight = actualHeight = m_surface->h;

		if (m_potExtend) {
			// extend to power-of-two if necessary
			actualWidth = ceil_pow2(m_surface->w);
			actualHeight = ceil_pow2(m_surface->h);
			if (actualWidth != virtualWidth || actualHeight != virtualHeight) {
				if(m_textureType == TEXTURE_2D) {
					SDL_Surface *s = SDL_CreateRGBSurface(SDL_SWSURFACE, actualWidth, actualHeight, targetPixelFormat->BitsPerPixel,
						targetPixelFormat->Rmask, targetPixelFormat->Gmask, targetPixelFormat->Bmask, targetPixelFormat->Amask);
					SDL_SetSurfaceBlendMode(m_surface.Get(), SDL_BLENDMODE_NONE);
					SDL_BlitSurface(m_surface.Get(), 0, s, 0);

					m_surface = SDLSurfacePtr::WrapNew(s);
				} else if(m_textureType == TEXTURE_CUBE_MAP) {
					assert(m_cubemap.size() == 6);
					for(unsigned int i = 0; i < 6; ++i) {
						SDL_Surface *s = SDL_CreateRGBSurface(SDL_SWSURFACE, actualWidth, actualHeight, targetPixelFormat->BitsPerPixel,
							targetPixelFormat->Rmask, targetPixelFormat->Gmask, targetPixelFormat->Bmask, targetPixelFormat->Amask);
						SDL_SetSurfaceBlendMode(m_cubemap[i].Get(), SDL_BLENDMODE_NONE);
						SDL_BlitSurface(m_cubemap[i].Get(), 0, s, 0);
						m_cubemap[i] = SDLSurfacePtr::WrapNew(s);
					}
				} else {
					assert(0);
				}
			}
		}
		else if (! m_filename.empty()) {
			// power-of-two check
			unsigned long width = ceil_pow2(m_surface->w);
			unsigned long height = ceil_pow2(m_surface->h);

			if (width != virtualWidth || height != virtualHeight)
				Output("WARNING: texture '%s' is not power-of-two and may not display correctly\n", m_filename.c_str());
		}
	} else {
		switch(m_dds.GetTextureFormat()) {
		case PicoDDS::FORMAT_DXT1: targetTextureFormat = TEXTURE_DXT1; break;
		case PicoDDS::FORMAT_DXT5: targetTextureFormat = TEXTURE_DXT5; break;
		default:
			Output("ERROR: DDS texture with invalid format '%s' (only DXT1 and DXT5 are supported)\n", m_filename.c_str());
			assert(false);
			return;
		}

		virtualWidth = actualWidth = m_dds.imgdata_.width;
		virtualHeight = actualHeight = m_dds.imgdata_.height;
		numberOfMipMaps = m_dds.imgdata_.numMipMaps;
		numberOfImages = m_dds.imgdata_.numImages;
		if(m_textureType == TEXTURE_CUBE_MAP) {
			// Cube map must be fully defined (6 images) to be used correctly
			assert(numberOfImages == 6);
		}
	}

	m_descriptor = TextureDescriptor(
		targetTextureFormat,
		vector2f(actualWidth,actualHeight),
		vector2f(float(virtualWidth)/float(actualWidth),float(virtualHeight)/float(actualHeight)),
		m_sampleMode, m_generateMipmaps, m_compressTextures, numberOfMipMaps, m_textureType);

	m_prepared = true;
}