CMemoryBuffer CHardwarePixelBuffer::LockSource(size_t offset, size_t length, THardwareBufferLock opt)
{
	if(mSize == 0)
		throw NOVA_EXP("CHardwarePixelBuffer::LockSource - \
		mSize == 0, null pixel box..", BAD_OPERATION);
	CMemoryBuffer data;
	GLuint face_target = 0;

	data.AllocBuffer(mSize);
	COpenGLFormats informat;
	informat.SetExFormat(mPixelFormat);

	glPixelStorei(GL_PACK_ALIGNMENT, 1);

	GLenum type = TextureTarget(mTarget);

	if(mTarget == USE_CUBEMAP_TEXTURE)
		face_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + mFace;
	else
		face_target = type;

	glBindTexture(type, mTargetId);

	glGetTexImage(face_target, mLevel, informat.GetFormat(),
		GL_UNSIGNED_BYTE, data.GetBegin());

	glPixelStorei(GL_PACK_ALIGNMENT, 4);

	int error = glGetError();
	if(error != GL_NO_ERROR)
	{
		nstringstream str;
		str << "CHardwarePixelBuffer::LockSource - \
		detecting OpenGL error with code " << error;
		throw NOVA_EXP(str.str().c_str(), BAD_OPERATION);
	}

	CMemoryBuffer result;
	result.AllocBuffer(mLockActSize);
	size_t line = mLockWidth * informat.GetInternalChannels();

	nova::byte * source = (nova::byte *)data.GetBegin() + offset;
	nova::byte * dest = (nova::byte *)result.GetBegin();
	for(nova::uint i = 0; i < mLockDepth; ++i)
	{
		for(nova::uint j = 0; j < mLockHeight; ++j)
		{
			memcpy(dest, source, line);
			source += mRowPitch * informat.GetInternalChannels();
			dest += line;
		}
		source += mSlicePitch * informat.GetInternalChannels();
	}

	data.FreeBuffer();

	return result;
}
void CMemoryBuffer::CopyTo(const CMemoryBuffer & buffer, size_t size, size_t off) const
{
	if(buffer.GetBufferSize() < size)
		NOVA_EXP("CMemoryBuffer::CopyTo: unput buffer too small...", MEM_ERROR);

	if((off + size) > mbSize)
		NOVA_EXP("CMemoryBuffer::CopyTo: offset param too large", MEM_ERROR);

	nova::nByte *p = (nova::nByte *)mBegin + off;
	memcpy(buffer.GetBegin(), p, size);
}
void CTextureSurfaceList::BuildSurfaceList(const CMemoryBuffer & data, size_t width, size_t height, size_t depth)
{
	if(!width || !height || !depth)
		throw NOVA_EXP("CTextureSurfaceList::BuildSurfaseList - incorrect input size param.", BAD_OPERATION);

	GLenum type = CHardwarePixelBuffer::TextureTarget(mType);
	bool mipmap_hardware_gen = CRenderSystem::GetSingelton().CheckCapabilities(TEXTURE_CATEGORY, CAP_AUTOMIPMAP);
	COpenGLFormats informat;
	informat.SetExFormat(mPixelFormat);
	mMaxMipmaps = GetMaxMipmaps(width, height, depth);

	glEnable(type);

	if(mType == CHardwarePixelBuffer::USE_CUBEMAP_TEXTURE && mFace > 0) {}
	else
		glGenTextures(1, &mTargetId);

	glBindTexture(type, mTargetId);

	if(mMipState == USE_HARDWARE_MIPMAPS)
	{
		if(!mipmap_hardware_gen)
			mMipState = USE_SOFTWARE_MIPMAPS;
	}

	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	if(mMipState == DO_NOT_USE_MIPMAPS)
	{
		glTexParameteri(type, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

		mMaxMipmaps = 1;

		switch(mType)
		{
		case CHardwarePixelBuffer::USE_TEXTURE_1D:
			glTexImage1D(GL_TEXTURE_1D, 0, informat.GetInternalChannels(),
				width, 0, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin());
			break;
		case CHardwarePixelBuffer::USE_TEXTURE_2D:
			glTexImage2D(GL_TEXTURE_2D, 0, informat.GetInternalChannels(),
				width, height, 0, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin());
			break;
		case CHardwarePixelBuffer::USE_TEXTURE_3D:
			glTexImage3D(GL_TEXTURE_3D, 0, informat.GetInternalChannels(),
				width, height, depth, 0, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin());
			break;
		case CHardwarePixelBuffer::USE_CUBEMAP_TEXTURE:
			glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + mFace, 0, informat.GetInternalChannels(),
				width, height, 0, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin());
			break;
		}
	}
	else if(mMipState == USE_SOFTWARE_MIPMAPS)
	{
		glTexParameteri(type, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
		glTexParameteri(type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

		switch(mType)
		{
		case CHardwarePixelBuffer::USE_TEXTURE_1D:
			gluBuild1DMipmaps(GL_TEXTURE_1D, informat.GetInternalChannels(),
				width, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin());
			break;
		case CHardwarePixelBuffer::USE_TEXTURE_2D:
			gluBuild2DMipmaps(GL_TEXTURE_2D, informat.GetInternalChannels(),
				width, height, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin());
			break;
		case CHardwarePixelBuffer::USE_CUBEMAP_TEXTURE:
			gluBuild2DMipmaps(GL_TEXTURE_CUBE_MAP_POSITIVE_X + mFace, informat.GetInternalChannels(),
				width, height, informat.GetFormat(), GL_UNSIGNED_BYTE, data.GetBegin());
			break;
		case CHardwarePixelBuffer::USE_TEXTURE_3D:
			throw NOVA_EXP("CTextureSurfaceList::BuildSurfaseList - \
				OpenGL can not support software 3D mipmaps", BAD_OPERATION);
			break;
		}
	}
void CHardwarePixelBuffer::UnlockSource(CMemoryBuffer & buf)
{
	if(mSize == 0)
		throw NOVA_EXP("CHardwarePixelBuffer::UnlockSource - \
		mSize == 0, null pixel box..", BAD_OPERATION);
	GLuint face_target = 0;
	void *ptr = buf.GetBegin();

	if(!ptr)
		throw NOVA_EXP("CHardwarePixelBuffer::LockSource - \
			ptr == NULL, bad ptr..", BAD_OPERATION);

	COpenGLFormats informat;
	informat.SetExFormat(mPixelFormat);

	glPixelStorei(GL_PACK_ALIGNMENT, 1);

	GLenum type = TextureTarget(mTarget);

	if(mTarget == USE_CUBEMAP_TEXTURE)
		face_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + mFace;
	else
		face_target = type;

	glBindTexture(type, mTargetId);

	size_t xoff, yoff, zoff;
	SizeToWHD(&xoff, &yoff, &zoff, mLockStart);

	nova::uint _width;
	nova::uint _height;
	nova::uint _depth;
	SizeToWHD(&_width, &_height, &_depth, mLockStart + mLockSize);

	_width -= (xoff-1);
	_height -= (yoff-1);
	_depth -= (zoff-1);

	switch(mTarget)
	{
	case USE_TEXTURE_1D:
		{
			glTexSubImage1D(GL_TEXTURE_1D, mLevel, xoff, _width, informat.GetFormat(),
				GL_UNSIGNED_BYTE, ptr);
		}
		break;
	case USE_TEXTURE_2D:
	case USE_CUBEMAP_TEXTURE:
		{
			glTexSubImage2D(face_target, mLevel, xoff, yoff, _width,
				_height, informat.GetFormat(), GL_UNSIGNED_BYTE, ptr);
		}
		break;
	case USE_TEXTURE_3D:
		{
			glTexSubImage3D(GL_TEXTURE_3D, mLevel, xoff, yoff, zoff, _width,
				_height, _depth, informat.GetFormat(), GL_UNSIGNED_BYTE, ptr);
		}
		break;
	}

	mLockWidth = 0;
	mLockHeight = 0;
	mLockDepth = 0;
	mLockActSize = 0;

	glPixelStorei(GL_PACK_ALIGNMENT, 4);

	buf.FreeBuffer();
}
Beispiel #5
0
void CFreeFont::MakeLetter(wchar_t code)
{
	// Первая вещь, которую нам надо сделать, это вывести наш символ
	// в растр. Это делается набором команд FreeType

	// Загрузить глифы для каждого символа.
	if(FT_Load_Glyph(face, FT_Get_Char_Index(face, code), FT_LOAD_DEFAULT))
		throw NOVA_EXP("CFreeFont::MakeLetter - FT_Load_Glyph failed", BAD_OPERATION);

	// Поместить глиф в объект.
	FT_Glyph glyph;
	if(FT_Get_Glyph(face->glyph, &glyph))
		throw NOVA_EXP("CFreeFont::MakeLetter - FT_Get_Glyph failed", BAD_OPERATION);

	// Конвертировать глиф в растр.
	FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
	FT_BitmapGlyph bitmap_glyph = reinterpret_cast<FT_BitmapGlyph>(glyph);

	// С помощью этой ссылки, получаем легкий доступ до растра.
	FT_Bitmap & bitmap = bitmap_glyph->bitmap;

    // Используем нашу вспомогательную функцию для вычисления ширины и высоты
	// текстуры для нашего растра.
	nInt32 bwidth = NextP2(bitmap.width);
	nInt32 bheight = NextP2(bitmap.rows);

	// Выделим память для данных текстуры.
	//nByte * expanded_data = NULL;
	//expanded_data = getmem<nByte>(expanded_data, 2 * bwidth * bheight);
	CMemoryBuffer mem;
	mem.AllocBuffer(2 * bwidth * bheight);
	nByte * expanded_data = (nova::nByte *)mem.GetBegin();

	// Поместим данные в расширенный растр.
	// Отмечу, что использован двухканальный растр (Один для
	// канала яркости и один для альфа), но мы будем назначать
	// обоим каналам одно и тоже значение, которое мы
	// получим из растра FreeType.
	// Мы используем оператор ?: для того чтобы поместить 0 в зону вне растра FreeType.
	for(nInt32 j = 0; j < bheight; ++j)
		for(nInt32 i = 0; i < bwidth; ++i)
			expanded_data[2*(i + j * bwidth)] = expanded_data[2*(i + j * bwidth)+1] =
				(i >= bitmap.width || j >= bitmap.rows) ? 0 : bitmap.buffer[i + bitmap.width*j];

/*	GLuint texture;
	glGenTextures(1, &texture);

	glBindTexture( GL_TEXTURE_2D, texture);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	// Здесь мы создаем текстуру
	// Помните, что используем GL_LUMINANCE_ALPHA, чтобы было два альфа канала данных
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bwidth, bheight, 0,
		GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data);
*/
	//nInt32 tid = CTextureManager::GetSingeltonPtr()->AddTexture(GL_TEXTURE_2D,
	//	expanded_data, bwidth, bheight, CImageFormats::NF_LUMINANCE_ALPHA);
/*	CTexturePtr ptex = CTextureManager::GetSingeltonPtr()->AddTexture(new CTexture(fname.c_str(), GL_TEXTURE_2D));
	ptex->SetEnvType(GL_MODULATE);
	ptex->CreateTexture(expanded_data, bwidth, bheight, CImageFormats::NF_LUMINANCE_ALPHA, GL_CLAMP);

	// После создания текстуры, мы больше не нуждаемся в промежуточных данных.
	freemems(expanded_data);

	CLetter letter(slot->metrics.horiBearingX >> 6, slot->metrics.horiBearingY >> 6,
		slot->metrics.horiAdvance >> 6, bwidth, bheight, bitmap.width, bitmap.rows,
		code, ptex);

*/
	nstring resnamet;
	nstring resnamei("TempFontImage");
	resnamet = mName + "_" + CStringUtils::IntTo16xString(static_cast<nInt32>(code));
// Создаем промежуточное изображение в памяти
	CImagePtr pImage = CImageManager::GetSingelton().CreateNewImage(resnamei, mName, mem,
		bwidth, bheight, 1, CImageFormats::NF_LUMINANCE_ALPHA, CResource::NV_FREE);
// На базе изображения создаем текстуру
	CTexturePtr texp = CTextureManager::GetSingelton().CreateNewTexture(resnamet, mName, pImage);

	// После создания текстуры, мы больше не нуждаемся в промежуточных данных.
	mem.FreeBuffer();

	CLetter letter(slot->metrics.horiBearingX >> 6, slot->metrics.horiBearingY >> 6,
		slot->metrics.horiAdvance >> 6, bwidth, bheight, bitmap.width, bitmap.rows,
		code, texp);
	mSize += texp->GetSize();

/// Создаем дисплейный список на букву ///////////////////////////////////////////////
	letter.GetDispList().CreateList();
	letter.GetDispList().BeginList();
/// //////////////////////////////////////////////////////////////////////////////////
	if(!texp.IsNull())
		texp->ApplyTexture();

// Вычислим какая часть нашей текстуры будет заполнена пустым пространством.
// Мы рисуем только ту часть текстуры, в которой находится символ, и сохраняем
// информацию в переменных x и y, затем, когда мы рисуем четырехугольник,
// мы будем только ссылаться на ту часть текстуры, в которой непосредственно
// содержится символ.
	nReal x = static_cast<nReal>(letter.GetBitmapw()) / static_cast<nReal>(letter.GetWidth()),
		y = static_cast<nReal>(letter.GetBitmapr()) / static_cast<nReal>(letter.GetHeight());

	//glBindTexture(GL_TEXTURE_2D, let.GetTex());

	glBegin(GL_QUADS);
		glTexCoord2f(0,0);
		glVertex2i(0,0);
		glTexCoord2f(0,y);
		glVertex2i(0,letter.GetBitmapr());
		glTexCoord2f(x,y);
		glVertex2i(letter.GetBitmapw(), letter.GetBitmapr());
		glTexCoord2f(x,0);
		glVertex2i(letter.GetBitmapw(), 0);
	glEnd();

/// Завершаем дисплейный список //////////////////////////////////////////////////
	letter.GetDispList().EndList();
/// //////////////////////////////////////////////////////////////////////////////

	letters_map[code] = letter;
}
void CDevILCodec::DecodeFromBuffer(const CMemoryBuffer & input, CImage *image,
		CImageFormats::NovaPixelFormats format, ESaveFormats ext)
{
	ILuint image_id;
	// Generate the main image name to use.
	ilGenImages(1, &image_id);

	// Bind this image name.
	ilBindImage(image_id);

	ILenum type = 0;
	switch(ext)
	{
	case SF_BMP:
		type = IL_BMP;
		break;
	case SF_ICO:
		type = IL_ICO;
		break;
	case SF_JPG:
		type = IL_JPG;
		break;
	case SF_PCX:
		type = IL_PCX;
		break;
	case SF_PIC:
		type = IL_PIC;
		break;
	case SF_PNG:
		type = IL_PNG;
		break;
	case SF_TGA:
		type = IL_TGA;
		break;
	case SF_TIF:
		type = IL_TIF;
		break;
	case SF_GIF:
		type = IL_GIF;
		break;
	case SF_DDS:
		type = IL_DDS;
		break;
	case SF_PIX:
		type = IL_PIX;
		break;
	case SF_HDR:
		type = IL_HDR;
		break;

	default:
		return;
	}

	if(!ilLoadL(type, input.GetBegin(), input.GetBufferSize()))
	{
		ILenum Error = 0;
		if((Error = ilGetError()) != NULL)
		{
			nstring str("CDevILCodec::DecodeFormStream: Can not load image lump - ");
			str.append(iluErrorString(Error));
			throw NOVA_EXP(str.c_str(), BAD_OPERATION);
		}
	}

	image->GetImageSource().mHeight = ilGetInteger(IL_IMAGE_HEIGHT);
	image->GetImageSource().mWidth = ilGetInteger(IL_IMAGE_WIDTH);
	image->GetImageSource().mDepth = ilGetInteger(IL_IMAGE_DEPTH);

	//if (ilGetInteger(IL_IMAGE_ORIGIN) == IL_ORIGIN_UPPER_LEFT)
	//	iluFlipImage();

	if(format == CImageFormats::NF_DEFAULT)
	{
		CDevILFormats inf;
		inf.SetFormat(ilGetInteger(IL_IMAGE_FORMAT));
		format = inf.GetExFormat();
	}

	CDevILFormats informat;
	informat.SetExFormat(format);
	image->GetImageSource().mPixelFormat = format;


	size_t _size = image->GetWidth() * image->GetHeight() * image->GetDepth() * ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL);
	image->GetBits().FreeBuffer();
	image->GetBits().AllocBuffer(_size);

	ilCopyPixels(0, 0, 0, image->GetWidth(), image->GetHeight(),
		image->GetDepth(), informat.GetFormat(), IL_UNSIGNED_BYTE, image->GetBits().GetBegin());

	ilDeleteImages(1, &image_id);

	ILenum Error = 0;
	if((Error = ilGetError()) != NULL)
	{
		nstring str("CDevILCodec::DecodeFormStream(): Can not load image file - ");
		str.append(iluErrorString(Error));
		throw NOVA_EXP(str.c_str(), BAD_OPERATION);
	}
}
void CDevILCodec::CodeToBuffer(CMemoryBuffer & out, const CImage &image,
							   ESaveFormats ext)
{
	ILuint imageid;
	CDevILFormats informat;
	informat.SetExFormat(image.GetPixelFormat());
	// Generate the main image name to use.
	ilGenImages(1, &imageid);

	// Bind this image name.
	ilBindImage(imageid);

	ilTexImage(image.GetWidth(), image.GetHeight(), image.GetDepth(), informat.GetInternalChannels(),
		informat.GetFormat(), IL_UNSIGNED_BYTE, image.GetBitsPtr());

	ILenum type = 0;
	switch(ext)
	{
	case SF_BMP:
		type = IL_BMP;
		break;
	case SF_ICO:
		type = IL_ICO;
		break;
	case SF_JPG:
		type = IL_JPG;
		break;
	case SF_PCX:
		type = IL_PCX;
		break;
	case SF_PIC:
		type = IL_PIC;
		break;
	case SF_PNG:
		type = IL_PNG;
		break;
	case SF_TGA:
		type = IL_TGA;
		break;
	case SF_TIF:
		type = IL_TIF;
		break;
	case SF_GIF:
		type = IL_GIF;
		break;
	case SF_DDS:
		type = IL_DDS;
		break;
	case SF_PIX:
		type = IL_PIX;
		break;
	case SF_HDR:
		type = IL_HDR;
		break;

	default:
		return;
	}

	out.AllocBuffer(image.GetSize()+0xff);
	ilSaveL(type, out.GetBegin(), out.GetBufferSize());

	ilDeleteImages(1, &imageid);

	ILenum Error = 0;
	if((Error = ilGetError()) != NULL)
	{
		nstring str("CDevILCodec::CodeToStream: ");
		str.append(iluErrorString(Error));
		throw NOVA_EXP(str.c_str(), BAD_OPERATION);
	}
}