⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decal.cpp

📁 hair solusion, c&#226 cs ádasda
💻 CPP
字号:
#include "Decal.h"

Decal::Decal()
{
	InitVariables();
}

Decal::Decal(tgaInfo *psImageFile)
{
	InitVariables();

	SetDecal(psImageFile);
}

Decal::Decal(char *sFileName)
{
	InitVariables();

	SetDecal(sFileName);
}

Decal::~Decal()
{
	if (pData)
	{
		delete[] pData;
		pData = NULL;
	}
}

void Decal::InitVariables()
{
	fPhysicalTextureWidth  = 0.0;
	fPhysicalTextureHeight = 0.0;

	fCenterTextureX = 0.0;
	fCenterTextureY = 0.0;

	fSinglePixelSize = 0.0;

	nPixelTextureWidth  = 0;
	nPixelTextureHeight = 0;

	nDecalWidth  = 0;
	nDecalHeight = 0;

	nOldDecalWidth = 0;
	nOldDecalHeight = 0;

	fTexCoordWidth  = 1.0;
	fTexCoordHeight = 1.0;

	texName = 0;

	pData = NULL;
}

void Decal::SetDecal(char *sFileName)
{
	tgaInfo *psImageFile = NULL;

	psImageFile = tgaLoad(sFileName);

	SetDecal(psImageFile);

	tgaDestroy(psImageFile);
}

void Decal::SetDecal(tgaInfo *psImageFile)
{
	unsigned char *pSource = NULL;
	GLubyte *pTarget = NULL;
	GLuint channels = 0;
	GLuint i, j, k;

	nPixelTextureWidth  = psImageFile->width;
	nPixelTextureHeight = psImageFile->height;

	nDecalWidth  = EvenPower(psImageFile->width);
	nDecalHeight = EvenPower(psImageFile->height);

	if ( ( nDecalWidth != nOldDecalWidth ) || (nDecalHeight != nOldDecalHeight ) )
	{
		// Remove the previous texture, if necessary
		if (pData)
		{
			delete[] pData;
			pData = NULL;
		}

		// Create a new texture
		pData = new GLubyte[4 * nDecalWidth * nDecalHeight];

		// Keep track of the current texture width
		nOldDecalWidth = nDecalWidth;
		nOldDecalHeight = nDecalHeight;
	}

	// Copy the targa into pData
	pSource = psImageFile->imageData;
	pTarget = pData;

	channels = psImageFile->pixelDepth / 8;

	for (j = 0; j < nDecalHeight; j++)
	{
		for (i = 0; i < nDecalWidth; i++)
		{
			if ( ( i < ( (GLuint) nPixelTextureWidth ) ) && ( j < ( (GLuint) nPixelTextureHeight ) ) )
			{
				// copy the RGB and alpha
				for (k = 0; k < channels; k++)
					pTarget[k] = pSource[k];

				if ( channels < 4 )
					pTarget[3] = 255;

				// Skip the pointer to the next pixel
				pSource += channels;
			}
			else
			{
				// set RGB and alpha to 0
				for (k = 0; k < 4; k++)
					pTarget[k] = 0;
			}

			pTarget += 4;
		}
	}

	fTexCoordWidth  = (float) psImageFile->width / nDecalWidth;
	fTexCoordHeight = (float) psImageFile->height / nDecalHeight;

	// Compute the width and height the plane needs to have the same aspect ratio as the texture
	fPhysicalTextureWidth  = 1.0;
	fPhysicalTextureHeight = 1.0;
	if ( psImageFile->width > psImageFile->height )
		fPhysicalTextureHeight = (float) psImageFile->height / (float) psImageFile->width;
	else if ( psImageFile->height > psImageFile->width )
		fPhysicalTextureWidth  = (float) psImageFile->width / (float) psImageFile->height;

	fSinglePixelSize = fPhysicalTextureWidth / psImageFile->width;

	fCenterTextureX = 0.5 * fPhysicalTextureWidth;
	fCenterTextureY = 0.5 * fPhysicalTextureHeight;
}

//void Decal::InitGLTexture(GLuint &id)
void Decal::InitGLTexture()
{
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	if ( ! texName )
		glGenTextures(1, &texName);

	glBindTexture(GL_TEXTURE_2D, texName);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, nDecalWidth, nDecalHeight,
		0, GL_RGBA, GL_UNSIGNED_BYTE, pData);
}

void Decal::Draw()
{
	glEnable(GL_TEXTURE_2D);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
	glBindTexture(GL_TEXTURE_2D, texName);
	glBegin(GL_QUADS);

		glTexCoord2f( 0.0, 0.0 );
		glVertex3f( 0.0, 0.0,  0.0 );

		glTexCoord2f( 0.0, fTexCoordHeight );
		glVertex3f( 0.0, fPhysicalTextureHeight,  0.0 );

		glTexCoord2f( fTexCoordWidth, fTexCoordHeight );
		glVertex3f( fPhysicalTextureWidth,  fPhysicalTextureHeight,  0.0);

		glTexCoord2f( fTexCoordWidth, 0.0 );
		glVertex3f( fPhysicalTextureWidth, 0.0,  0.0);

	glEnd();
	glDisable(GL_TEXTURE_2D);
}

void Decal::GetPixel(GLuint x, GLuint y, GLubyte &red, GLubyte &green, GLubyte &blue, GLubyte &alpha)
{
	GLubyte *pPixel = pData + 4 * ( y * nDecalWidth + x );

	red   = pPixel[0];
	green = pPixel[1];
	blue  = pPixel[2];
	alpha = pPixel[3];
}

void Decal::DoTransform()
{
	glTranslatef( -fCenterTextureX, -fCenterTextureY, 0.0 );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -