Archived

This topic is now archived and is closed to further replies.

Renderer always rendering png textures as all black

This topic is 5149 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

It seems that whenever I try to render a mesh that has a png (24 bit) texture, it doesn't render the texture or it renders it as all black. I have been trying to figure out what I might be doing incorrectly and I can't figure it out for the life of me, so I thought to try and ask some experts. I was adding support for png files to my currently existing code base, which has a working renderer. For some reason, every texture that is loaded as a png shows up as pure black in the game. At first I thought it was my alphablending flags in the rendering function, but they seem fine?? Then I thought it was the way I was loading png files, but I don't see a problem in there either. I use both libjpg and libpng. Well, anyways, I will cut to the chase... I would appreciate some opinions on wether this looks 'ok' at a first glance. The code base is using Directx 6 and less for compatibility reasons.


//-------------------------------------------------------------------------------------------------

// Name: LoadTextureImageAsJPG()

// Desc: Loads a texture map and associates ptcTexture->hBitmap to that memory

//-------------------------------------------------------------------------------------------------

static HRESULT LoadTextureImageAsJPG( HMODULE hArtDLL, TextureContainer* ptcTexture, int nType )
{
	//-----------------------------------------------------------------------

	// Check to make sure the resource exists and lock it, otherwise fail

	//-----------------------------------------------------------------------

	UINT wd, ht;
	LPBYTE pBits ;
	TCHAR* strFilename = ptcTexture->strName;
	char fname[_MAX_FNAME];

	_splitpath( strFilename, NULL, NULL, fname, NULL);

	HRSRC hrsrc = FindResource( hArtDLL, fname, "JPG" ) ;
	if ( !hrsrc )
		return DDERR_NOTFOUND;

	HGLOBAL hg = LoadResource( hArtDLL, hrsrc ) ;
	if ( !hg )
		return DDERR_NOTFOUND;

	BYTE *pRes = (BYTE *) LockResource( hg ) ;
	if ( !pRes )
		return DDERR_NOTFOUND;

	//-----------------------------------------------------------------------

	// If specified, load the graphic as a PNG file

	//-----------------------------------------------------------------------

	if( nType == LOAD_PNG )
	{
		//-----------------------------------------------------------------------

		// Hard code the png loading variables for now, change when it works

		//-----------------------------------------------------------------------

		boolean bHasAlpha = TRUE;
		int wd2=111;
		int ht2 = 111;
		ReadPNG( "C:\\test.png", 0, pBits, wd2, ht2, bHasAlpha );

		if ( !pBits)
			return DDERR_NOTFOUND;

		//-----------------------------------------------------------------------

		// Create a device independent bitmap for the texture

		//-----------------------------------------------------------------------

		BITMAPINFO bmi;
		BITMAPINFOHEADER& bmiHeader = bmi.bmiHeader;
		bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		bmiHeader.biWidth = wd;
		bmiHeader.biHeight = ht;
		bmiHeader.biPlanes = 1;
		bmiHeader.biBitCount = 32;
		bmiHeader.biCompression = BI_PNG;
		bmiHeader.biSizeImage = 0;
		bmiHeader.biXPelsPerMeter = 0;
		bmiHeader.biYPelsPerMeter = 0;
		bmiHeader.biClrUsed = 0;
		bmiHeader.biClrImportant = 0;

		HDC hdc = GetDC(NULL);
		ptcTexture->hbmBitmap = CreateDIBitmap(hdc, &bmi.bmiHeader, CBM_INIT,(CONST VOID *)pBits,  &bmi,  DIB_RGB_COLORS);
		return DD_OK;
	}
	else if( nType == LOAD_JPG )
	{
		pBits = JpegFile::JpegFileToRGB( pRes, SizeofResource( hArtDLL, hrsrc ), &wd, &ht ) ;

		/*
			Try to load a jpeg but set the alpha to 255, This seems to crash and can't get to work
			right so disable this for now. The pBits buffer created by JpegFileToRGB, needs to allocate
			more room for alpha values... currently, it doesn't

			for(int y=0; y<ht; y++)
			{
				for(int x=0; x<wd; x++ )
				{
					int *pbyte = NULL;
					(int*)pbyte = (int*)(pBits + (y*(wd*4) + x*4));
					*pbyte = MakePixel( 255, RedValue(*pbyte), GreenValue(*pbyte), BlueValue(*pbyte) );
				}
			}
		*/

		//   Set up for display, do this before DWORD-alignment!

		//this works on packed (not DWORD-aligned) buffers swap red and blue for display

		JpegFile::BGRFromRGB(pBits, wd, ht);

		// Vertical flip for display

		JpegFile::VertFlipBuf(pBits, wd * 3, ht);

		// DWORD-align for display

		UINT widthDW;
		LPBYTE tmp = JpegFile::MakeDwordAlignedBuf(pBits, wd, ht, &widthDW);

		// create bitmap for future usage

		BITMAPINFO bmi;
		BITMAPINFOHEADER& bmiHeader = bmi.bmiHeader;
		bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		bmiHeader.biWidth = wd;
		bmiHeader.biHeight = ht;
		bmiHeader.biPlanes = 1;
		bmiHeader.biBitCount = 24;
		bmiHeader.biCompression = BI_RGB;
		bmiHeader.biSizeImage = 0;
		bmiHeader.biXPelsPerMeter = 0;
		bmiHeader.biYPelsPerMeter = 0;
		bmiHeader.biClrUsed = 0;
		bmiHeader.biClrImportant = 0;

		HDC hdc = GetDC(NULL);
		ptcTexture->hbmBitmap = CreateDIBitmap(hdc, &bmi.bmiHeader, CBM_INIT,(CONST VOID *)tmp, &bmi,  DIB_RGB_COLORS);

		ReleaseDC(NULL, hdc);
		delete[] tmp;
		delete[] pBits;

		if(!ptcTexture->hbmBitmap)
		{
			return DDERR_NOTFOUND;
		}
	}

	return DD_OK;
 }



The above function is how I am loading textures, and associating the texture to the memory (LPBYTES), by creating a DIBitmap... I know of no other way to do this?
//-----------------------------------------------------------------------

// Rendering function to draw the world objects

//-----------------------------------------------------------------------

VOID CDXFileMesh::Render( LPDIRECT3DDEVICE3 pd3dDevice, LPDIRECT3DMATERIAL3 pmtrl ,DWORD transp_type,DWORD r_flag)
{
	static DWORD transFlags = 0;
	unsigned n;
	HRESULT hr;

	//-----------------------------------------------------------------------

	// Set up alpha blending

	//-----------------------------------------------------------------------

	DWORD src_blend, dst_blend, arg1, a_op;
	pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
	pd3dDevice->GetRenderState( D3DRENDERSTATE_SRCBLEND,   &src_blend);
	pd3dDevice->GetRenderState( D3DRENDERSTATE_DESTBLEND,  &dst_blend);
	pd3dDevice->GetTextureStageState( 0, D3DTSS_ALPHAARG1, &arg1) ;
	pd3dDevice->GetTextureStageState( 0, D3DTSS_ALPHAOP,   &a_op) ;

	if(oneTexture)
	{
             	//-----------------------------------------------------------------------

		//Apply the material

		//-----------------------------------------------------------------------

		hr = pmtrl->SetMaterial( &m_mtrl );
		ASSERT( hr == D3D_OK ) ;

		//-----------------------------------------------------------------------

		// If a texture isn't loaded, try to find one in the texture tree

		//-----------------------------------------------------------------------

		if ( m_Texture == NULL && m_strTexture[ 0 ] != '\0' )
		{
			m_Texture = D3DTextr_GetTexture( m_strTexture ) ;
		}

		//-----------------------------------------------------------------------

		// Set the texture

		//-----------------------------------------------------------------------

		pd3dDevice->SetTexture( 0, m_Texture );

		//-----------------------------------------------------------------------

		// Check the transparency type to determine the method of alpha blending,

		//-----------------------------------------------------------------------

		if(transp_type != 0)
		{
			pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
			if(transp_type == 1)
			{
				pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND,   g_FloorSrc);
				pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND,  g_FloorDst);
			}
		}
		else
		{
			pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
		}

		pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);

		if( !g_draw_untransformed_shadows )
		{
			try
			{
				pd3dDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, lpD3DVertexBuffer2, m_pIndices, m_dwNumIndices, 0 );
			}
			catch(...)
			{
				g_pKillMe = this;
				return;
			}
		}
		else
		{
 			 if(m_untransformed )
			 {
			    pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX, m_pVerticesU, m_dwNumVerticesU, 
					m_pIndicesU, m_dwNumIndicesU, 0 );
			 }
		}
	}
	else //multi-texturing

	{
		//-----------------------------------------------------------------------

		//	Check the transparency type of this object, to determine flags to setRenderState

		//  transp_type == 0, No alpha blending

		//				== 1, Source / Destination blend

		//              == 3, Use transparency specified in material

		//				== 4, Lighting interpolation

		//-----------------------------------------------------------------------

		if ( transp_type != 0 )
		{
			pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );

			if(transp_type == 1)
			{
				pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND,   g_FloorSrc);
				pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND,  g_FloorDst);
			}
			if ( transp_type == 3 )	// use transparency from material description

			{
				pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ) ;
				pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ) ;
				pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA ) ;
				pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA ) ;
			}
			if ( transp_type == 4 )	// Add object color to fraction of dest. color (for lamp)

			{
				pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ) ;
				pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ) ;
				pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE ) ;
				pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA ) ;
			}
		}
		else
		{
			pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
		}

		//-----------------------------------------------------------------------

		// Not working?? Force all object to blend alpha

		//-----------------------------------------------------------------------

		pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE);
		pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND,   g_FloorSrc);
		pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND,  g_FloorDst);


		//-----------------------------------------------------------------------

		// Go through the textures, and draw the primitives

		//-----------------------------------------------------------------------

		for(n = 0;n<groups.GetSize();n++)
		{
			CDXFileGroup *gp = &groups[ n ] ;

			//-----------------------------------------------------------------------

			// If the texture isn't set, try to find the texture in the tree

			//-----------------------------------------------------------------------

			if ( gp->m_Texture == NULL && gp->m_strTexture[ 0 ] != '\0' )
			{
				gp->m_Texture = D3DTextr_GetTexture( gp->m_strTexture ) ;
			}

			//-----------------------------------------------------------------------

			// Set the actual texture, and attempt to draw

			//-----------------------------------------------------------------------

			pd3dDevice->SetTexture( 0, gp->m_Texture ) ;
			try
			{
				pd3dDevice->DrawIndexedPrimitiveVB( D3DPT_TRIANGLELIST, lpD3DVertexBuffer2,
												m_pIndices+groups[n].from*3, groups[n].count*3, 0 );
			}
			catch(...)
			{
					//-----------------------------------------------------------------------

					// Something major went wrong, abort

					//-----------------------------------------------------------------------

					g_pKillMe = this;
					return;
			}
		}
	}

	pd3dDevice->SetTexture( 0, NULL ) ;

	//-----------------------------------------------------------------------

	// Render the next mesh in the tree

	//-----------------------------------------------------------------------

	if( m_pNext )
	{
		m_pNext->Render( pd3dDevice, pmtrl ,transp_type,r_flag);
	}
}



 
This rendering function is a bit fat for now, mostly because I was trying to experiment with different ways to do alpha blending. It seems none of them worked so I tried to 'force it' and failed Would anyone be so kind as to point out the missing flag?? I can't seem to find old school directx6 tutorials anymore, and newer directx versions have it natively supported so it isn't a problem, but i don't have that luxury [edited by - Rhapsodus on November 12, 2003 11:38:56 PM]

Share this post


Link to post
Share on other sites