HRESULT InitD3D( HWND hWnd )
{
	HRESULT hr ;

	// Create the D3D object, which is needed to create the D3DDevice.
	if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
	{
		MessageBoxA(NULL, "Create D3D9 object failed!", "Error", 0) ;
		return E_FAIL;
	}

	D3DPRESENT_PARAMETERS d3dpp; 
	ZeroMemory( &d3dpp, sizeof(d3dpp) );

	d3dpp.Windowed = TRUE; // use window mode, not full screen
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
	d3dpp.BackBufferWidth = WindowWidth / 2 ;
	d3dpp.BackBufferHeight = WindowHeight / 2;

	// Create device
	if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
		D3DCREATE_SOFTWARE_VERTEXPROCESSING,
		&d3dpp, &g_pd3dDevice ) ) )
	{
		MessageBoxA(NULL, "Create D3D9 device failed!", "Error", 0) ;
		return E_FAIL;
	}

	// Disable lighting, since we didn't specify color for vertex
	g_pd3dDevice->SetRenderState( D3DRS_LIGHTING , FALSE );   

	// Create teapot
	D3DXCreateTeapot(g_pd3dDevice, &g_pTeapotMesh, NULL) ;

	// Create top-left render target
	hr = g_pd3dDevice->CreateRenderTarget(WindowWidth / 2, WindowHeight / 2, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &g_pSurfaceTopleft, NULL) ;
	if (FAILED(hr))
	{
		MessageBox(NULL, "Create Top-left render target failed!", "Error", 0) ;
		return hr ;
	}

	// Create top-right render target
	hr = g_pd3dDevice->CreateRenderTarget(WindowWidth / 2, WindowHeight / 2, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &g_pSurfaceTopright, NULL) ;
	if (FAILED(hr))
	{
		MessageBox(NULL, "Create Top-right render target failed!", "Error", 0) ;
		return hr ;
	}

	return S_OK;
}
HRESULT HookIDirect3DDevice9::CreateRenderTarget(LPVOID _this,
												 UINT Width,
												 UINT Height,
												 D3DFORMAT Format,
												 D3DMULTISAMPLE_TYPE MultiSample,
												 DWORD MultisampleQuality,
												 BOOL Lockable,
												 IDirect3DSurface9** ppSurface,
												 HANDLE* pSharedHandle)
{
	LOG_API();
	return pD3Dev->CreateRenderTarget(Width, Height, Format, MultiSample, MultisampleQuality, Lockable, ppSurface, pSharedHandle);
}
Beispiel #3
0
HRESULT CreateSurface(UINT nWidth, UINT nHeight) 
{ 
  HRESULT hr = g_pd3dDevice->CreateRenderTarget( 
               nWidth, nHeight, 
               D3DFMT_A8R8G8B8,  
               D3DMULTISAMPLE_NONE,  
               0, 
               true, 
               &g_pd3dSurface,  
               NULL); 
  if (SUCCEEDED(hr)) 
    hr = g_pd3dDevice-> 
         SetRenderTarget(0, g_pd3dSurface); 
  return hr; 
}
bool DirectXTextureManager::loadTileSetFromTexture(Game *game,
	wstring dir,
	wstring sourceImageFileName,
	int tileWidth,
	int tileHeight)
{
	// CONVERT THE FILE NAME INTO A WINDOW LONG CHAR wchar_t (LPCWSTR)
	wstring sourcePath = dir + sourceImageFileName;

	LPDIRECT3DTEXTURE9 textureToDivide;
	LPDIRECT3DSURFACE9 surfaceToDivide;
	//DXLoad
	//D3DXLoadSurfaceFromMemory()
	unsigned int result = fillTexture(sourcePath, &textureToDivide);
	textureToDivide->GetSurfaceLevel(0, &surfaceToDivide);//~15 seconds
	if (result != S_OK) return false;

	// DETERMINE THE NUMBER OF TILE ROWS AND COLUMNS
	D3DSURFACE_DESC surfaceDesc;
	surfaceToDivide->GetDesc(&surfaceDesc);
	int textureWidth = surfaceDesc.Width;
	int textureHeight = surfaceDesc.Height;
	int columns = textureWidth / tileWidth;
	int rows = textureHeight / tileHeight;
	DirectXGraphics *dxg = (DirectXGraphics*)graphics;

	LPDIRECT3DDEVICE9 graphicsDevice = ((DirectXGraphics*)graphics)->getGraphicsDevice();

	// THE TILE SET IMAGE LOADED SUCCESSFULLY, SO LET'S CUT IT UP
	// MAYBE IF IM FEELING CRAZY LATER ILL MULTI THREAD THIS
	for (int row = 0; row < rows; row++)
	{
		for (int column = 0; column < columns; column++)
		{
			LPDIRECT3DTEXTURE9 extractedTexture;
			LPDIRECT3DSURFACE9 extractedSurface;
			result = graphicsDevice->CreateRenderTarget(tileWidth,
				tileHeight,
				D3DFMT_A8R8G8B8,
				D3DMULTISAMPLE_NONE, 0, false, &extractedSurface, NULL);
			if (result != S_OK) return false;

			RECT sourceRect;
			sourceRect.left = column * tileWidth;
			sourceRect.right = tileWidth + (column * tileWidth) - 1;
			sourceRect.top = row * tileHeight;
			sourceRect.bottom = tileHeight + (row * tileHeight) - 1;

			graphicsDevice->StretchRect(surfaceToDivide, &sourceRect, extractedSurface, NULL, D3DTEXF_NONE);

			// BUILD A UNIQUE FILE NAME FOR THIS TEXTURE
			wstring textureFilename = sourceImageFileName;

			unsigned int id = wstringTable.getNumWStringsInTable();
			wchar_t dot = '.';
			int dotIndex = textureFilename.rfind(dot);
			textureFilename = textureFilename.substr(0, dotIndex);
			wstringstream idWss;
			idWss << id;
			wstring idText;
			idWss >> idText;
			textureFilename = textureFilename + idText + L".png";
			textureFilename = wstring(dir.begin(), dir.end()) + textureFilename;

			//D3DXCreateTextureFromFile()
			//D3DxCreateTexture
			HRESULT result = D3DXCreateTexture(graphicsDevice, tileWidth, tileHeight, 1, D3DPOOL_DEFAULT, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, &extractedTexture);
			if (result != S_OK) return false;
			LPDIRECT3DSURFACE9 t;
			extractedTexture->GetSurfaceLevel(0, &t);
			D3DXLoadSurfaceFromSurface(t, NULL, NULL, extractedSurface, NULL, NULL, D3DX_FILTER_NONE, 0);
					

			// ADD IT TO THE STRING TABLE
			wstringTable.putWStringInTable(textureFilename);

			// AND ADD IT TO THE TEXTURES
			textures[textureFilename] = extractedTexture;
			extractedSurface->Release();
			t->Release();
		}
	}
	surfaceToDivide->Release();
	textureToDivide->Release();
	return true;
}
void TextureGPU::createDrawableIntoColorTextureWithDepth(PrimitiveTypes::UInt32 w, PrimitiveTypes::UInt32 h, ESamplerState sampler, bool use32BitRedForDepth /* = false*/)
{
	StringOps::writeToString("createDrawableIntoColorTextureWithDepth", m_name, 256);
	m_samplerState = sampler;

#	if APIABSTRACTION_D3D9
	D3D9Renderer *pD3D9Renderer = static_cast<D3D9Renderer *>(m_pContext->getGPUScreen());
	LPDIRECT3DDEVICE9 pDevice = pD3D9Renderer->m_pD3D9Device;
	
	m_viewport.X = 0;
	m_viewport.Y = 0;
	m_viewport.Width = w;
	m_viewport.Height = h;
	m_viewport.MinZ = 0.0f;
	m_viewport.MaxZ = 1.0f;
#if APIABSTRACTION_X360
	HRESULT hr = D3DXCreateTexture(pDevice, 
		w, 
		h, 
		1, 
		D3DUSAGE_RENDERTARGET, 
		use32BitRedForDepth ? D3DFMT_R32F : D3DFMT_A8R8G8B8,
		D3DPOOL_DEFAULT, 
		&this->m_pTexture );
#else
	HRESULT hr = pDevice->CreateTexture(
		w, 
		h, 
		1, 
		D3DUSAGE_RENDERTARGET, 
		use32BitRedForDepth ? D3DFMT_R32F : D3DFMT_A8R8G8B8,
		D3DPOOL_DEFAULT, 
		&this->m_pTexture,
		NULL);
#endif

	D3DSURFACE_DESC desc;
	m_pTexture->GetSurfaceLevel( 0, &m_pSurface );
	m_pSurface->GetDesc( &desc );

#ifdef _XBOX
	//create depth stencil surface to use with this texture
	hr = pDevice->CreateDepthStencilSurface(
		w,
		h,
		D3DFMT_D24S8,
		D3DMULTISAMPLE_NONE,
		0,     // multi sample quality
		TRUE,  // Set this flag to TRUE to enable z-buffer discarding, and FALSE otherwise.
		//If this flag is set, the contents of the depth stencil buffer will be invalid
		// after calling either IDirect3DDevice9::Present or IDirect3DDevice9::SetDepthStencilSurface with a different depth surface.
		&m_pEDRamDSRenderTargetSurface,
		NULL);

	assert(SUCCEEDED(hr));

	hr = pDevice->CreateRenderTarget(
		desc.Width, desc.Height,
		( D3DFORMAT )MAKESRGBFMT( desc.Format ),
		D3DMULTISAMPLE_NONE, 0, 0,
		&m_pEDRamColorRenderTargetSurface, NULL );
#else
#if D3D9_USE_RENDER_TO_SURFACE
	hr = D3DXCreateRenderToSurface(pDevice, 
		desc.Width, 
		desc.Height, 
		desc.Format, 
		TRUE, 
		D3DFMT_D16, 
		&m_pRenderToSurface );
#else
	//create depth stencil surface to use with this texture
	hr = pDevice->CreateDepthStencilSurface(
		w,
		h,
		D3DFMT_D24S8,
		D3DMULTISAMPLE_NONE,
		0,     // multi sample quality
		TRUE,  // Set this flag to TRUE to enable z-buffer discarding, and FALSE otherwise.
		//If this flag is set, the contents of the depth stencil buffer will be invalid
		// after calling either IDirect3DDevice9::Present or IDirect3DDevice9::SetDepthStencilSurface with a different depth surface.
		&m_pDSSurface,
		NULL);
#endif
#endif

	assert(SUCCEEDED(hr));

#elif APIABSTRACTION_OGL

	SamplerState &ss = SamplerStateManager::getInstance()->getSamplerState(m_samplerState);

	GLuint texture;
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);
    IRenderer::checkForErrors("glTexImage2D");
    
    #if PE_PLAT_IS_IOS
        PEWARN("We are creating depth texture as 32 bit, because I could not get 16 bit depth working. If you figure it out, change it to 16 bit for better perf (hopefully!)");
    #endif
    
    glTexImage2D(
		GL_TEXTURE_2D,				// Target
		0,							// Mip-level
        #if PE_PLAT_IS_IOS
            GL_DEPTH_COMPONENT, 	// InternalFormat
        #else
            GL_DEPTH_COMPONENT16,
        #endif
        w,							// width size
		h,							// height size
		0,							// border
		GL_DEPTH_COMPONENT,						// input pixel format
        #if PE_PLAT_IS_IOS
            GL_UNSIGNED_INT,			// input pixel type
        #else
            GL_UNSIGNED_SHORT,
        #endif
		NULL);						// input pixels

    IRenderer::checkForErrors("glTexImage2D");
    
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, ss.val_GL_TEXTURE_MIN_FILTER);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, ss.val_GL_TEXTURE_MAG_FILTER);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, ss.val_GL_TEXTURE_WRAP_S);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, ss.val_GL_TEXTURE_WRAP_T);
    
#if !APIABSTRACTION_IOS
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,0); //only one mip

	// depth related comparison functions
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
#endif
    
	glBindTexture(GL_TEXTURE_2D, 0);
	
	#if APIABSTRACTION_PS3
		glGenFramebuffersOES(1, &m_frameBufferObject);
	#else
		glGenFramebuffers(1, &m_frameBufferObject);
	#endif

	#if APIABSTRACTION_PS3
		glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_frameBufferObject); //set framebuffer for reading and writing. could also use GL_READ_FRAMEBUFFER to set a buffer for reading vs writing. 
	#else
		glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferObject); //set framebuffer for reading and writing. could also use GL_READ_FRAMEBUFFER to set a buffer for reading vs writing. 
	#endif

	//glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, w); / no need for this, since it take size of the texture passed

	#if APIABSTRACTION_PS3
		glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_TEXTURE_2D, texture, 0);
	#else
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture, 0);
	#endif

	m_viewport.x = 0;
	m_viewport.y = 0;
	m_viewport.w = w;
	m_viewport.h = h;
	m_viewport.minDepth = 0;
	m_viewport.maxDepth = 1.0f;

	// had to comment out this assert becasue apparently with newest hardware it is actually complete too
	//assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE); // make sure API requires color texture too

	// need to cerate color texture too, otherwise framebuffer object is incomplete
	glGenTextures(1, &m_texture);
	glBindTexture(GL_TEXTURE_2D, m_texture);
    IRenderer::checkForErrors("glTexImage2D");
    #if PE_PLAT_IS_IOS
        if (use32BitRedForDepth)
            PEWARN("We are creating depth+color and storing dpeth in color. for ios we store it as rgba, since we cant store it as 32bit red..");
    #endif
	glTexImage2D(
		GL_TEXTURE_2D,				// Target
		0,							// Mip-level
		#if defined(SN_TARGET_PS3)
			use32BitRedForDepth ? GL_LUMINANCE32F_ARB  : GL_ARGB_SCE,
		#else
			#if APIABSTRACTION_IOS
				use32BitRedForDepth ? GL_RGBA : GL_RGBA,				// InternalFormat, for ps3 use GL_ARGB_SCE, why?
			#else
				use32BitRedForDepth ? GL_R32F : GL_RGBA,						// InternalFormat, for ps3 use GL_ARGB_SCE, why?
			#endif
		#endif
		w,							// width size
		h,							// height size
		0,							// border
		GL_RGBA,					// input pixel format
		GL_UNSIGNED_BYTE,			// input pixel type
		NULL);						// input pixels
    IRenderer::checkForErrors("glTexImage2D");
    
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, ss.val_GL_TEXTURE_MIN_FILTER);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, ss.val_GL_TEXTURE_MAG_FILTER);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, ss.val_GL_TEXTURE_WRAP_S);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, ss.val_GL_TEXTURE_WRAP_T);
    
#if !APIABSTRACTION_IOS
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,0); //only one mip
#endif
    
	//depth related
	//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_MODE_ARB,GL_COMPARE_R_TO_TEXTURE_ARB);
	//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
	glBindTexture(GL_TEXTURE_2D, 0);

	#if APIABSTRACTION_PS3
		glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
	#else
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0);
	#endif

	#if !APIABSTRACTION_IOS
		#if APIABSTRACTION_PS3
			assert(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) == GL_FRAMEBUFFER_COMPLETE_OES);
		#else
			assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
		#endif
	#endif
    
    IRenderer::checkRenderBufferComplete();
    
	#if APIABSTRACTION_PS3
		glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); // back to default
	#else
		glBindFramebuffer(GL_FRAMEBUFFER, 0); // back to default
	#endif
#elif APIABSTRACTION_D3D11
	m_viewport.TopLeftX = 0;
	m_viewport.TopLeftY = 0;
	m_viewport.Width = w;
	m_viewport.Height = h;
	m_viewport.MinDepth = 0.0f;
	m_viewport.MaxDepth = 1.0f;

	D3D11Renderer *pD3D11Renderer = static_cast<D3D11Renderer *>(m_pContext->getGPUScreen());
	ID3D11Device *pDevice = pD3D11Renderer->m_pD3DDevice;
	ID3D11DeviceContext *pDeviceContext = pD3D11Renderer->m_pD3DContext;

	//ID3D11Texture2D *pColorMap = 0;

	D3D11_TEXTURE2D_DESC texDesc;
	texDesc.Width = w;
	texDesc.Height = h;
	texDesc.MipLevels = 1;
	texDesc.ArraySize = 1;
	texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	texDesc.SampleDesc.Count = 1;
	texDesc.SampleDesc.Quality = 0;
	texDesc.Usage = D3D11_USAGE_DEFAULT;
	texDesc.BindFlags = D3D11_BIND_RENDER_TARGET |
		D3D11_BIND_SHADER_RESOURCE;
	texDesc.CPUAccessFlags = 0;
	texDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;

	HRESULT hr = pDevice->CreateTexture2D(&texDesc, 0, &m_pTexture);
	assert(SUCCEEDED(hr));

	// Null description means to create a view to all mipmap levels
	// using the format the texture was created with
	hr = pDevice->CreateRenderTargetView(m_pTexture, 0, &m_pRenderTargetView);
	assert(SUCCEEDED(hr));
	hr = pDevice->CreateShaderResourceView(m_pTexture, 0, &m_pShaderResourceView);
	assert(SUCCEEDED(hr));

	// Now create depth part fo the texture
	ID3D11Texture2D *pDepthMap = 0;

	texDesc.Format = DXGI_FORMAT_R32_TYPELESS;
	texDesc.Usage = D3D11_USAGE_DEFAULT;
	texDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL |
		D3D11_BIND_SHADER_RESOURCE;
	texDesc.CPUAccessFlags = 0;
	texDesc.MiscFlags = 0;

	hr = pDevice->CreateTexture2D(&texDesc, 0, &pDepthMap);
	assert(SUCCEEDED(hr));

	// setting up view for rendering into depth buffer/and reading (stenciling) from it (z-buffer algorithm red/write)
	D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
	dsvDesc.Format = DXGI_FORMAT_D32_FLOAT;
	dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
	dsvDesc.Texture2D.MipSlice = 0;
	dsvDesc.Flags = 0;//D3D11_DSV_READ_ONLY_DEPTH;

	hr = pDevice->CreateDepthStencilView(pDepthMap, &dsvDesc, &m_DepthStencilView);
	assert(SUCCEEDED(hr));

	D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
	srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
	srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
	srvDesc.Texture2D.MipLevels = texDesc.MipLevels;
	srvDesc.Texture2D.MostDetailedMip = 0;

	hr = pDevice->CreateShaderResourceView(pDepthMap, &srvDesc, &m_pDepthShaderResourceView);
	assert(SUCCEEDED(hr));

	pDepthMap->Release();
#endif
}
void TextureGPU::createDrawableIntoColorTexture(PrimitiveTypes::UInt32 w, PrimitiveTypes::UInt32 h, ESamplerState sampler)
{
	
	m_samplerState = sampler;

	StringOps::writeToString("DrawableIntoColorTexture", m_name, 256);

#	if APIABSTRACTION_D3D9
	D3D9Renderer *pD3D9Renderer = static_cast<D3D9Renderer *>(m_pContext->getGPUScreen());
	LPDIRECT3DDEVICE9 pDevice = pD3D9Renderer->m_pD3D9Device;
	
	m_viewport.X = 0;
	m_viewport.Y = 0;
	m_viewport.Width = w;
	m_viewport.Height = h;
	m_viewport.MinZ = 0.0f;
	m_viewport.MaxZ = 1.0f;

	IDirect3DTexture9 *pColorMap = 0;
#if APIABSTRACTION_X360
	HRESULT hr = D3DXCreateTexture( pDevice, 
		w, 
		h, 
		1, 
		D3DUSAGE_RENDERTARGET, 
		D3DFMT_A8R8G8B8, 
		D3DPOOL_DEFAULT, 
		&this->m_pTexture );
#else
	HRESULT hr = pDevice->CreateTexture( 
		w, 
		h, 
		1, 
		D3DUSAGE_RENDERTARGET, 
		D3DFMT_A8R8G8B8, 
		D3DPOOL_DEFAULT, 
		&this->m_pTexture,
		NULL);
#endif
	
	D3DSURFACE_DESC desc;
	m_pTexture->GetSurfaceLevel( 0, &m_pSurface );
	m_pSurface->GetDesc( &desc );
#ifdef _XBOX
	hr = pDevice->CreateRenderTarget(desc.Width, desc.Height, ( D3DFORMAT )MAKESRGBFMT( desc.Format ),
		D3DMULTISAMPLE_NONE, 0, 0,
		&m_pEDRamColorRenderTargetSurface, NULL );
#else
	#if D3D9_USE_RENDER_TO_SURFACE
		hr = D3DXCreateRenderToSurface(pDevice, 
			desc.Width, 
			desc.Height, 
			desc.Format, 
			false,
			D3DFMT_UNKNOWN, 
			&m_pRenderToSurface );
	#endif
#endif
		assert(SUCCEEDED(hr));

#elif APIABSTRACTION_OGL
	glGenTextures(1, &m_texture);
	glBindTexture(GL_TEXTURE_2D, m_texture);
    IRenderer::checkForErrors("glTexImage2D");
	glTexImage2D(
		GL_TEXTURE_2D,				// Target
		0,							// Mip-level
#if defined(SN_TARGET_PS3)
		GL_ARGB_SCE,
#else
		GL_RGBA,						// InternalFormat, for ps3 use GL_ARGB_SCE, why?
#endif
		w,							// width size
		h,							// height size
		0,							// border
		GL_RGBA,						// input pixel format
		GL_UNSIGNED_BYTE,			// input pixel type
		NULL);						// input pixels
    IRenderer::checkForErrors("glTexImage2D");
    
	SamplerState &ss = SamplerStateManager::getInstance()->getSamplerState(m_samplerState);

	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, ss.val_GL_TEXTURE_MIN_FILTER);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, ss.val_GL_TEXTURE_MAG_FILTER);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, ss.val_GL_TEXTURE_WRAP_S);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, ss.val_GL_TEXTURE_WRAP_T);
#if !APIABSTRACTION_IOS
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,0); //only one mip
#endif
	//depth related
	//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_MODE_ARB,GL_COMPARE_R_TO_TEXTURE_ARB);
	//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
	glBindTexture(GL_TEXTURE_2D, 0);

	#if APIABSTRACTION_PS3
		glGenFramebuffersOES(1, &m_frameBufferObject);
	#else
		glGenFramebuffers(1, &m_frameBufferObject);
	#endif
	#if APIABSTRACTION_PS3
		glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_frameBufferObject); //set framebuffer for reading and writing. could also use GL_READ_FRAMEBUFFER to set a buffer for reading vs writing. 
	#else
		glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferObject); //set framebuffer for reading and writing. could also use GL_READ_FRAMEBUFFER to set a buffer for reading vs writing. 
	#endif
	//glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, w); / no need for this, since it take size of the texture passed

	#if APIABSTRACTION_PS3
		glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0);
	#else
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0);
	#endif
	m_viewport.x = 0;
	m_viewport.y = 0;
	m_viewport.w = w;
	m_viewport.h = h;
	m_viewport.minDepth = 0;
	m_viewport.maxDepth = 1.0f;

	#if !APIABSTRACTION_IOS
		#if APIABSTRACTION_PS3
			assert(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) == GL_FRAMEBUFFER_COMPLETE_OES);
		#else
			assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
		#endif
	#endif

	#if APIABSTRACTION_PS3
		glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); // back to default
	#else
		glBindFramebuffer(GL_FRAMEBUFFER, 0); // back to default
	#endif
#elif APIABSTRACTION_D3D11
	m_viewport.TopLeftX = 0;
	m_viewport.TopLeftY = 0;
	m_viewport.Width = w;
	m_viewport.Height = h;
	m_viewport.MinDepth = 0.0f;
	m_viewport.MaxDepth = 1.0f;

	D3D11Renderer *pD3D11Renderer = static_cast<D3D11Renderer *>(m_pContext->getGPUScreen());
	ID3D11Device *pDevice = pD3D11Renderer->m_pD3DDevice;
	ID3D11DeviceContext *pDeviceContext = pD3D11Renderer->m_pD3DContext;

	//ID3D11Texture2D *pColorMap = 0;

	D3D11_TEXTURE2D_DESC texDesc;
		texDesc.Width = w;
		texDesc.Height = h;
		texDesc.MipLevels = 0;
		texDesc.ArraySize = 1;
		texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		texDesc.SampleDesc.Count = 1;
		texDesc.SampleDesc.Quality = 0;
		texDesc.Usage = D3D11_USAGE_DEFAULT;
		texDesc.BindFlags = D3D11_BIND_RENDER_TARGET |
		                    D3D11_BIND_SHADER_RESOURCE;
		texDesc.CPUAccessFlags = 0;
		texDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;

		HRESULT hr = pDevice->CreateTexture2D(&texDesc, 0, &m_pTexture);
		assert(SUCCEEDED(hr));

		// Null description means to create a view to all mipmap levels
		// using the format the texture was created with
		hr = pDevice->CreateRenderTargetView(m_pTexture, 0, &m_pRenderTargetView);
		assert(SUCCEEDED(hr));
		hr = pDevice->CreateShaderResourceView(m_pTexture, 0, &m_pShaderResourceView);
		assert(SUCCEEDED(hr));

#endif
}
bool DirectXTextureManager::loadTileSetFromTexture(	Game *game, 
													wstring dir,
													wstring sourceImageFileName,
													int tileWidth,
													int tileHeight,
													int spacing,
													int margin)
{
	// CONVERT THE FILE NAME INTO A WINDOW LONG CHAR wchar_t (LPCWSTR)
	wstring sourcePath = dir + sourceImageFileName;

	LPDIRECT3DTEXTURE9 textureToDivide;
	LPDIRECT3DSURFACE9 surfaceToDivide;

	unsigned int result = fillTexture(sourcePath, &textureToDivide);
	textureToDivide->GetSurfaceLevel(0, &surfaceToDivide);
	if (result != S_OK) return false;

	// DETERMINE THE NUMBER OF TILE ROWS AND COLUMNS
	D3DSURFACE_DESC surfaceDesc;
	surfaceToDivide->GetDesc(&surfaceDesc);
	int textureWidth = surfaceDesc.Width;
	int textureHeight = surfaceDesc.Height;
	int columns = (textureWidth-margin)/(tileWidth+spacing);
	int rows = (textureHeight-margin)/(tileHeight+spacing);
	DirectXGraphics *dxg = (DirectXGraphics*)graphics;

	LPDIRECT3DDEVICE9 graphicsDevice = ((DirectXGraphics*)graphics)->getGraphicsDevice();

	// THE TILE SET IMAGE LOADED SUCCESSFULLY, SO LET'S CUT IT UP
	for (int row = 0; row < rows; row++)
	{
		for (int column = 0; column < columns; column++)
		{
			LPDIRECT3DTEXTURE9 extractedTexture;
			LPDIRECT3DSURFACE9 extractedSurface;
			result = graphicsDevice->CreateRenderTarget(tileWidth,
					tileHeight,
					D3DFMT_A8R8G8B8,
					D3DMULTISAMPLE_NONE, 0, false, &extractedSurface, NULL);
			if (result != S_OK) return false;
	
			RECT sourceRect;
			sourceRect.left = (column * (tileWidth + spacing)) + margin;
			sourceRect.right = tileWidth + (sourceRect.left) - 1;
			sourceRect.top = (row * (tileHeight + spacing)) + margin;
			sourceRect.bottom = tileHeight + (sourceRect.top) - 1;
			
			graphicsDevice->StretchRect(surfaceToDivide, &sourceRect, extractedSurface, NULL, D3DTEXF_NONE);

			// BUILD A UNIQUE FILE NAME FOR THIS TEXTURE
			wstring textureFilename = sourceImageFileName;

			unsigned int id = wstringTable.getNumWStringsInTable();
			wchar_t dot = '.';
			int dotIndex = textureFilename.rfind(dot);
			textureFilename = textureFilename.substr(0, dotIndex);
			wstringstream idWss;
			idWss << id;
			wstring idText;
			idWss >> idText;
			textureFilename = textureFilename + idText + L".png";
			textureFilename = wstring(dir.begin(), dir.end()) + textureFilename;
				
			// LET'S PUT THE SURFACE IN AN IMAGE FILE
			D3DXSaveSurfaceToFileW(textureFilename.c_str(), D3DXIFF_PNG, extractedSurface, NULL, NULL); 
			D3DXIMAGE_INFO info;
			HRESULT result = D3DXGetImageInfoFromFile(textureFilename.c_str(), &info);
			if (result != S_OK) return false;

			// AND THEN LOAD IT BACK IN AS A TEXTURE
			result = D3DXCreateTextureFromFileEx(	graphicsDevice,		// GPU
													textureFilename.c_str(),			// BITMAP FILE PATH/NAME
													tileWidth,			// BITMAP IMAGE WIDTH
													tileHeight,		// BITMAP IMAGE HEIGHT
													1,					// MIP-MAP LEVELS (1 FOR NO CHAIN)
													D3DPOOL_DEFAULT,	// THE TYPE OF SURFACE (STANDARD)
													D3DFMT_UNKNOWN,		// SURFACE FORMAT (DEFAULT)
													D3DPOOL_DEFAULT,	// MEMORY CLASS FOR THE TEXTURE
													D3DX_DEFAULT,		// IMAGE FILTER
													D3DX_DEFAULT,		// MIP FILTER
													NULL,			// COLOR KEY
													&info,				// BITMAP FILE INFO
													NULL,				// COLOR PALETTE
													&extractedTexture );	// THE TEXTURE WE ARE CREATING AND LOADING					
			if (result != S_OK) return false;

			// ADD IT TO THE STRING TABLE
			wstringTable.putWStringInTable(textureFilename);

			// AND ADD IT TO THE TEXTURES
			textures[textureFilename] = extractedTexture;
		}
	}
	return true;
}
HRESULT CProteinVistaRenderer::SaveScreenImage ( LPCSTR fileName, long imageWidth, long imageHeight , D3DXIMAGE_FILEFORMAT format)
{
	HRESULT hr;
	LPDIRECT3DDEVICE9 pDev = GetD3DDevice();

	BOOL bChangeSize = TRUE;
	if ( imageWidth == -1 || imageHeight == -1 )
	{
		bChangeSize = FALSE;
		imageWidth = m_d3dpp.BackBufferWidth;
		imageHeight = m_d3dpp.BackBufferHeight;
	}

	//    홀수이면 짝수로 바꾼다.
	if ( imageWidth/2 != (imageWidth+1)/2 )
	{
		imageWidth = (imageWidth/2)*2;
		bChangeSize = TRUE;
	}
	if ( imageHeight/2 != (imageHeight+1)/2 )
	{
		imageHeight = (imageHeight/2)*2;
		bChangeSize = TRUE;
	}

	long imageWidthOld = m_d3dpp.BackBufferWidth;
	long imageHeightOld = m_d3dpp.BackBufferHeight;

	if ( bChangeSize == TRUE )
	{
		m_d3dpp.BackBufferWidth  = imageWidth;
		m_d3dpp.BackBufferHeight = imageHeight;

		m_d3dSettings.Windowed_Width = m_d3dpp.BackBufferWidth;
		m_d3dSettings.Windowed_Height = m_d3dpp.BackBufferHeight;

		if( FAILED( hr = Reset3DEnvironment() ) )
		{
			if( hr == D3DERR_DEVICELOST )
			{
				m_bDeviceLost = true;
			}
			else
			{
				return E_FAIL;
			}
		}
	}

	LPDIRECT3DSURFACE9 renderTargetOrig = NULL;	
	hr = pDev->GetRenderTarget(0,&renderTargetOrig);

	LPDIRECT3DSURFACE9 renderTargetCapture; // 캡쳐된 내용이 들어갈 서피스
	D3DSURFACE_DESC desc;
	renderTargetOrig->GetDesc(&desc);

	pDev->CreateRenderTarget(desc.Width, desc.Height, desc.Format, desc.MultiSampleType , desc.MultiSampleQuality, FALSE , &renderTargetCapture, NULL);

	pDev->SetRenderTarget(0, renderTargetCapture);
	pDev->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1, 0);

	//    
	Render();

	pDev->SetRenderTarget(0, renderTargetOrig);
	SAFE_RELEASE(renderTargetOrig);

	// save the image to specified file
	CString filename(fileName);
	hr=D3DXSaveSurfaceToFile(filename,format,renderTargetCapture,NULL,NULL);
	if ( FAILED(hr) )
		return hr;

	SAFE_RELEASE(renderTargetCapture);

	//
	// return status of save to caller
	// 
	if ( bChangeSize == TRUE )
	{
		m_d3dpp.BackBufferWidth  = imageWidthOld;
		m_d3dpp.BackBufferHeight = imageHeightOld;

		m_d3dSettings.Windowed_Width = m_d3dpp.BackBufferWidth;
		m_d3dSettings.Windowed_Height = m_d3dpp.BackBufferHeight;

		if( FAILED( hr = Reset3DEnvironment() ) )
		{
			if( hr == D3DERR_DEVICELOST )
			{
				m_bDeviceLost = true;
			}
			else
			{
				return E_FAIL;
			}
		}

		Render3DEnvironment();
	}

	return hr;
}