Exemplo n.º 1
0
// split out of png_encode to simplify resource cleanup and avoid
// "dtor / setjmp interaction" warning.
static Status png_encode_impl(Tex* t, png_structp png_ptr, png_infop info_ptr, DynArray* da)
{
	const png_uint_32 w = (png_uint_32)t->w, h = (png_uint_32)t->h;
	const size_t pitch = w * t->bpp / 8;

	int colour_type;
	switch(t->flags & (TEX_GREY|TEX_ALPHA))
	{
	case TEX_GREY|TEX_ALPHA:
		colour_type = PNG_COLOR_TYPE_GRAY_ALPHA;
		break;
	case TEX_GREY:
		colour_type = PNG_COLOR_TYPE_GRAY;
		break;
	case TEX_ALPHA:
		colour_type = PNG_COLOR_TYPE_RGB_ALPHA;
		break;
	default:
		colour_type = PNG_COLOR_TYPE_RGB;
		break;
	}

	png_set_write_fn(png_ptr, da, io_write, io_flush);
	png_set_IHDR(png_ptr, info_ptr, w, h, 8, colour_type,
		PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

	u8* data = tex_get_data(t);
	std::vector<RowPtr> rows = tex_codec_alloc_rows(data, h, pitch, t->flags, TEX_TOP_DOWN);

	// PNG is native RGB.
	const int png_transforms = (t->flags & TEX_BGR)? PNG_TRANSFORM_BGR : PNG_TRANSFORM_IDENTITY;

	png_set_rows(png_ptr, info_ptr, (png_bytepp)&rows[0]);
	png_write_png(png_ptr, info_ptr, png_transforms, 0);

	return INFO::OK;
}
Exemplo n.º 2
0
///////////////////////////////////////////////////////////////////
// Load all sky textures
void SkyManager::LoadSkyTextures()
{
	for (size_t i = 0; i < ARRAY_SIZE(m_SkyTexture); ++i)
	{
		VfsPath path = VfsPath("art/textures/skies") / m_SkySet / (Path::String(s_imageNames[i])+L".dds");

		CTextureProperties textureProps(path);
		textureProps.SetWrap(GL_CLAMP_TO_EDGE);
		CTexturePtr texture = g_Renderer.GetTextureManager().CreateTexture(textureProps);
		texture->Prefetch();
		m_SkyTexture[i] = texture;
	}
	
	glGenTextures(1, &m_SkyCubeMap);
	glBindTexture(GL_TEXTURE_CUBE_MAP, m_SkyCubeMap);
	
	int types[] = {
		GL_TEXTURE_CUBE_MAP_POSITIVE_X,
		GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
		GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
		GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
		GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
		GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
	};
	
	const wchar_t* images[numTextures+1] = {
		L"front",
		L"back",
		L"right",
		L"left",
		L"top",
		L"top"
	};
	
	for (size_t i = 0; i < numTextures+1; ++i)
	{
		VfsPath path = VfsPath("art/textures/skies") / m_SkySet / (Path::String(images[i])+L".dds");
		
		shared_ptr<u8> file;
		size_t fileSize;
		g_VFS->LoadFile(path, file, fileSize);
		
		Tex tex;
		tex_decode(file, fileSize, &tex);
		
		tex_transform_to(&tex, (tex.flags | TEX_BOTTOM_UP | TEX_ALPHA) & ~(TEX_DXT | TEX_MIPMAPS));
		
		u8* data = tex_get_data(&tex);
		
		if (types[i] == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y || types[i] == GL_TEXTURE_CUBE_MAP_POSITIVE_Y)
		{
			std::vector<u8> rotated(tex.dataSize);
		
			for (size_t y = 0; y < tex.h; ++y)
			{
				for (size_t x = 0; x < tex.w; ++x)
				{
					size_t invx = y, invy = tex.w-x-1;
					
					rotated[(y*tex.w + x) * 4 + 0] = data[(invy*tex.w + invx) * 4 + 0];
					rotated[(y*tex.w + x) * 4 + 1] = data[(invy*tex.w + invx) * 4 + 1];
					rotated[(y*tex.w + x) * 4 + 2] = data[(invy*tex.w + invx) * 4 + 2];
					rotated[(y*tex.w + x) * 4 + 3] = data[(invy*tex.w + invx) * 4 + 3];
				}
			}
			
			glTexImage2D(types[i], 0, GL_RGB, tex.w, tex.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, &rotated[0]);
		}
		else
		{
			glTexImage2D(types[i], 0, GL_RGB, tex.w, tex.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
		}
		
		tex_free(&tex);
	}
	
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
	
	glBindTexture(GL_TEXTURE_2D, 0);
}