Beispiel #1
0
GLuint NvCreateTextureFromDDSEx(const char* filename, NvBool flipVertical, NvBool useMipmaps, int* width, int* height, NvBool* alpha, NvBool *isCubeMap)
{
    // Clear the GL error before this function, since at the end of this 
    // function, we test the error and report it.  We do not want to report
    // an error that happened at some random time before.  If we want to
    // catch those, we need more general/comprehensive handling.  But having
    // this function print a GL error for something that happened in other 
    // random code is confusing, especially to non-rail developers.
    // Some other code, like NVBitfont, prints error messages at the top of
    // the function and print a message that implies that the error was there
    // at the time of call.  That may make sense as an optional setting down
    // the road
    glGetError();

    GLuint tex = 0;
    NVHHDDSImage *img = NVHHDDSLoad(filename, flipVertical ? 1 : 0);
    if (img)
    {
        if(isCubeMap)
        {
            *isCubeMap = img->cubemap ? NV_TRUE:NV_FALSE;
        }
        if (width)
            *width = img->width;
        if (height)
            *height = img->height;
        if (alpha)
            *alpha = img->alpha ? NV_TRUE : NV_FALSE;

        glGenTextures(1, &tex);
        if (!img->cubemap)
        {
            glBindTexture(GL_TEXTURE_2D, tex);
            LoadTextureFromDDSData(GL_TEXTURE_2D, 0, img, useMipmaps);
        }
        else
        {
            int baseLevel = 0;
            glBindTexture(GL_TEXTURE_CUBE_MAP, tex);

            LoadTextureFromDDSData(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, baseLevel, img, useMipmaps);
            baseLevel += img->numMipmaps ? img->numMipmaps : 1;

            LoadTextureFromDDSData(GL_TEXTURE_CUBE_MAP_POSITIVE_X, baseLevel, img, useMipmaps);
            baseLevel += img->numMipmaps ? img->numMipmaps : 1;

            LoadTextureFromDDSData(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, baseLevel, img, useMipmaps);
            baseLevel += img->numMipmaps ? img->numMipmaps : 1;

            LoadTextureFromDDSData(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, baseLevel, img, useMipmaps);
            baseLevel += img->numMipmaps ? img->numMipmaps : 1;

            LoadTextureFromDDSData(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, baseLevel, img, useMipmaps);
            baseLevel += img->numMipmaps ? img->numMipmaps : 1;

            LoadTextureFromDDSData(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, baseLevel, img, useMipmaps);
            baseLevel += img->numMipmaps ? img->numMipmaps : 1;
        }

        GLint err = glGetError();
        if (err)
            NVLogError("NvCreateTextureFromDDSEx error", "");

        NVHHDDSFree(img);
    }

    return tex;
}
Beispiel #2
0
bool createNormalMapGL(GLuint &textureID, const unsigned int index,
					   const GLenum textureUnit, const GLfloat heightScale,
					   const char *filename)
{

	//Temporary variables for loading pixel data
	unsigned char* pHeightPixels, *pNormalPixels;
	unsigned int uiFormat, uiType, uiWidth, uiHeight;

	NVHHDDSImage *img = NVHHDDSLoad(filename, (NvS32)1);
	if(!img)
	{
		DEBUG("ERROR createNormalMapGL: problem loading height map texture.");
		return false;
	}

	pHeightPixels = (unsigned char*)(img->data[0]);
	uiWidth       = (unsigned int)  (img->width);
	uiHeight      = (unsigned int)  (img->height);
	uiFormat      = (unsigned int)  (img->format);
	uiType        = (unsigned int)  (img->componentFormat);

	unsigned int uiFormatWidth = 4U;

	pNormalPixels = new unsigned char[uiWidth * uiHeight * uiFormatWidth];
	for(unsigned int j = 0U; j < uiHeight; j++)
		for(unsigned int i = 0U; i < uiWidth; i++)
		{
			unsigned int iCenterIdx = uiFormatWidth * (j * uiWidth + i);
			unsigned int iLeftIdx   = uiFormatWidth * ((i > 0U) ?
				( j              * uiWidth + (i       - 1U)) :
				( j              * uiWidth + (uiWidth - 1U)));
			unsigned int iRightIdx  = uiFormatWidth * ((i < uiWidth - 1U) ?
				( j              * uiWidth + (i       + 1U)) :
				( j              * uiWidth +            0U ));
			unsigned int iUpIdx     = uiFormatWidth * ((j > 0U) ?
				((j        - 1U) * uiWidth +  i            ) :
				((uiHeight - 1U) * uiWidth +  i            ));
			unsigned int iDownIdx   = uiFormatWidth * ((j < uiHeight - 1U) ?
				((j        + 1U) * uiWidth +  i            ) :
				(            0U  * uiWidth +  i            ));

			GLfloat fDx, fDy, fDz;
			//Compute gradients
			fDx  = (GLfloat)(pHeightPixels[iRightIdx]); //[   0, 255]
			fDy  = (GLfloat)(pHeightPixels[iUpIdx]);    //[   0, 255]
			fDx -= (GLfloat)(pHeightPixels[iLeftIdx]);  //[-255, 255]
			fDy -= (GLfloat)(pHeightPixels[iDownIdx]);  //[-255, 255]
			fDx /= 255.0F;                              //[  -1,   1]
			fDy /= 255.0F;                              //[  -1,   1]
			//Scale them
			fDx *= heightScale;                         //[  -H,   H]
			fDy *= heightScale;                         //[  -H,   H]
			//Putting them in vectors (1, 0, fDx) and (0, 1, fDy) and
			//doing a cross product results in (-fDx, -fDy, 1)
			//BUT, for some reason, fDx needs to be turned into its
			//negative again for normal mapping to work, so we will only
			//turn fDy into its negative
			fDy *= -1;                                  //[  -H,   H]
			//We normalize the vector
			GLfloat fDet = (GLfloat)(sqrt(fDx * fDx + fDy * fDy + 1.0));
			fDx /= fDet;   fDy /= fDet;                 //[  -1,   1]
			//Now, we have to fit them into unsigned chars. We map them from
            //[-1, 1] to [0, 255]
			fDx += 1.0F;   fDy += 1.0F;                 //[   0,   2]
			fDx *= 128.0F; fDy *= 128.0F;               //[   0, 255]

			//The z component of the vector is just 1
			//(not scaled, but normalized)
			fDz  = (GLfloat)1.0F / fDet;                //[   0,   1]
			fDz *= 255.0F;

			pNormalPixels[iCenterIdx + 0U] = (unsigned char)fDx;
			pNormalPixels[iCenterIdx + 1U] = (unsigned char)fDy;
			pNormalPixels[iCenterIdx + 2U] = (unsigned char)fDz;
			pNormalPixels[iCenterIdx + 3U] = pHeightPixels[iCenterIdx];
		}

	NVHHDDSFree(img);

	glGenTextures(1, &(textureID));
	glActiveTexture(textureUnit);
	glBindTexture(GL_TEXTURE_2D, textureID);
	glTexImage2D(GL_TEXTURE_2D, (GLint)0, (GLint)uiFormat,
				 (GLsizei)uiWidth, (GLsizei)uiHeight, (GLint)0,
				 (GLenum)uiFormat, (GLenum)uiType,
				 (const GLvoid*)pNormalPixels);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	delete [] pNormalPixels;

	return true;
}