static bool d3d9_cg_load_program(void *data,
      void *fragment_data, void *vertex_data, const char *prog, bool path_is_file)
{
   bool ret                   = true;
   const char *list           = NULL;
   char *listing_f            = NULL;
   char *listing_v            = NULL;
   CGprogram *fPrg            = (CGprogram*)fragment_data;
   CGprogram *vPrg            = (CGprogram*)vertex_data;
   CGprofile vertex_profile   = cgD3D9GetLatestVertexProfile();
   CGprofile fragment_profile = cgD3D9GetLatestPixelProfile();
   const char **fragment_opts = cgD3D9GetOptimalOptions(fragment_profile);
   const char **vertex_opts   = cgD3D9GetOptimalOptions(vertex_profile);
   cg_renderchain_t *cg_data  = (cg_renderchain_t*)data;

   RARCH_LOG("[D3D Cg]: Vertex profile: %s\n", cgGetProfileString(vertex_profile));
   RARCH_LOG("[D3D Cg]: Fragment profile: %s\n", cgGetProfileString(fragment_profile));

   if (path_is_file && !string_is_empty(prog))
      *fPrg = cgCreateProgramFromFile(cg_data->cgCtx, CG_SOURCE,
            prog, fragment_profile, "main_fragment", fragment_opts);
   else
      *fPrg = cgCreateProgram(cg_data->cgCtx, CG_SOURCE, stock_cg_d3d9_program,
            fragment_profile, "main_fragment", fragment_opts);

   list = cgGetLastListing(cg_data->cgCtx);
   if (list)
      listing_f = strdup(list);

   if (path_is_file && !string_is_empty(prog))
      *vPrg = cgCreateProgramFromFile(cg_data->cgCtx, CG_SOURCE,
            prog, vertex_profile, "main_vertex", vertex_opts);
   else
      *vPrg = cgCreateProgram(cg_data->cgCtx, CG_SOURCE, stock_cg_d3d9_program,
            vertex_profile, "main_vertex", vertex_opts);

   list = cgGetLastListing(cg_data->cgCtx);
   if (list)
      listing_v = strdup(list);

   if (!fPrg || !vPrg)
   {
      RARCH_ERR("CG error: %s\n", cgGetErrorString(cgGetError()));
      if (listing_f)
         RARCH_ERR("Fragment:\n%s\n", listing_f);
      else if (listing_v)
         RARCH_ERR("Vertex:\n%s\n", listing_v);
      ret = false;
      goto end;
   }

   cgD3D9LoadProgram(*fPrg, true, 0);
   cgD3D9LoadProgram(*vPrg, true, 0);

end:
   free(listing_f);
   free(listing_v);
   return ret;
}
Beispiel #2
0
static bool renderchain_compile_shaders(cg_renderchain_t *chain,
      void *fragment_data, void *vertex_data, const std::string &shader)
{
   CGprogram *fPrg            = (CGprogram*)fragment_data;
   CGprogram *vPrg            = (CGprogram*)vertex_data;
   CGprofile vertex_profile   = cgD3D9GetLatestVertexProfile();
   CGprofile fragment_profile = cgD3D9GetLatestPixelProfile();
   const char **fragment_opts = cgD3D9GetOptimalOptions(fragment_profile);
   const char **vertex_opts   = cgD3D9GetOptimalOptions(vertex_profile);

   RARCH_LOG("[D3D Cg]: Vertex profile: %s\n", cgGetProfileString(vertex_profile));
   RARCH_LOG("[D3D Cg]: Fragment profile: %s\n", cgGetProfileString(fragment_profile));

   if (shader.length() > 0)
   {
      RARCH_LOG("[D3D Cg]: Compiling shader: %s.\n", shader.c_str());
      *fPrg = cgCreateProgramFromFile(chain->cgCtx, CG_SOURCE,
            shader.c_str(), fragment_profile, "main_fragment", fragment_opts);

      if (cgGetLastListing(chain->cgCtx))
         RARCH_ERR("[D3D Cg]: Fragment error:\n%s\n", cgGetLastListing(chain->cgCtx));

      *vPrg = cgCreateProgramFromFile(chain->cgCtx, CG_SOURCE,
            shader.c_str(), vertex_profile, "main_vertex", vertex_opts);

      if (cgGetLastListing(chain->cgCtx))
         RARCH_ERR("[D3D Cg]: Vertex error:\n%s\n", cgGetLastListing(chain->cgCtx));
   }
   else
   {
      RARCH_LOG("[D3D Cg]: Compiling stock shader.\n");

      *fPrg = cgCreateProgram(chain->cgCtx, CG_SOURCE, stock_program,
            fragment_profile, "main_fragment", fragment_opts);

      if (cgGetLastListing(chain->cgCtx))
         RARCH_ERR("[D3D Cg]: Fragment error:\n%s\n", cgGetLastListing(chain->cgCtx));

      *vPrg = cgCreateProgram(chain->cgCtx, CG_SOURCE, stock_program,
            vertex_profile, "main_vertex", vertex_opts);

      if (cgGetLastListing(chain->cgCtx))
         RARCH_ERR("[D3D Cg]: Vertex error:\n%s\n", cgGetLastListing(chain->cgCtx));
   }

   if (!fPrg || !vPrg)
      return false;

   cgD3D9LoadProgram(*fPrg, true, 0);
   cgD3D9LoadProgram(*vPrg, true, 0);
   return true;
}
Beispiel #3
0
bool RenderChain::compile_shaders(CGprogram &fPrg, CGprogram &vPrg, const std::string &shader)
{
#ifdef HAVE_CG
   CGprofile vertex_profile = cgD3D9GetLatestVertexProfile();
   CGprofile fragment_profile = cgD3D9GetLatestPixelProfile();
   RARCH_LOG("[D3D Cg]: Vertex profile: %s\n", cgGetProfileString(vertex_profile));
   RARCH_LOG("[D3D Cg]: Fragment profile: %s\n", cgGetProfileString(fragment_profile));
   const char **fragment_opts = cgD3D9GetOptimalOptions(fragment_profile);
   const char **vertex_opts = cgD3D9GetOptimalOptions(vertex_profile);

   if (shader.length() > 0)
   {
      RARCH_LOG("[D3D Cg]: Compiling shader: %s.\n", shader.c_str());
      fPrg = cgCreateProgramFromFile(cgCtx, CG_SOURCE,
            shader.c_str(), fragment_profile, "main_fragment", fragment_opts);

      if (cgGetLastListing(cgCtx))
         RARCH_ERR("[D3D Cg]: Fragment error:\n%s\n", cgGetLastListing(cgCtx));

      vPrg = cgCreateProgramFromFile(cgCtx, CG_SOURCE,
            shader.c_str(), vertex_profile, "main_vertex", vertex_opts);

      if (cgGetLastListing(cgCtx))
         RARCH_ERR("[D3D Cg]: Vertex error:\n%s\n", cgGetLastListing(cgCtx));
   }
   else
   {
      RARCH_LOG("[D3D Cg]: Compiling stock shader.\n");

      fPrg = cgCreateProgram(cgCtx, CG_SOURCE, stock_program,
            fragment_profile, "main_fragment", fragment_opts);

      if (cgGetLastListing(cgCtx))
         RARCH_ERR("[D3D Cg]: Fragment error:\n%s\n", cgGetLastListing(cgCtx));

      vPrg = cgCreateProgram(cgCtx, CG_SOURCE, stock_program,
            vertex_profile, "main_vertex", vertex_opts);

      if (cgGetLastListing(cgCtx))
         RARCH_ERR("[D3D Cg]: Vertex error:\n%s\n", cgGetLastListing(cgCtx));
   }

   if (!fPrg || !vPrg)
      return false;

   cgD3D9LoadProgram(fPrg, true, 0);
   cgD3D9LoadProgram(vPrg, true, 0);
#endif
   return true;
}
Beispiel #4
0
static void createCgPrograms()
{
	const char **profileOpts;

	/* Determine the best profile once a device to be set. */
	g_cgVertexProfile = cgD3D9GetLatestVertexProfile();
	checkForCgError("getting latest profile");

	profileOpts = cgD3D9GetOptimalOptions(g_cgVertexProfile);
	checkForCgError("getting latest profile options");

	g_cgVertexProgram =
		cgCreateProgramFromFile(
		g_cgContext,              /* Cg runtime context */
		CG_SOURCE,                /* Program in human-readable form */
		g_strVertexProgramFileName,/* Name of file containing program */
		g_cgVertexProfile,        /* Profile: OpenGL ARB vertex program */
		g_strVertexProgramName,   /* Entry function name */
		profileOpts);             /* Pass optimal compiler options */
	checkForCgError("creating vertex program from file");

	//get variable handle
	g_cgWorldMatrix = cgGetNamedParameter(g_cgVertexProgram, "worldMatrix");
	g_cgWorldViewProjMatrix = cgGetNamedParameter(g_cgVertexProgram, "worldViewProjMatrix");
	g_cgAmbient = cgGetNamedParameter(g_cgVertexProgram, "ambient");
	g_cgLightColor = cgGetNamedParameter(g_cgVertexProgram, "lightColor");
	g_cgLightPos = cgGetNamedParameter(g_cgVertexProgram, "lightPos");
	g_cgEyePos = cgGetNamedParameter(g_cgVertexProgram, "eyePos");
	g_cgKe = cgGetNamedParameter(g_cgVertexProgram, "ke");
	g_cgKa = cgGetNamedParameter(g_cgVertexProgram, "ka");
	g_cgKd = cgGetNamedParameter(g_cgVertexProgram, "kd");
	g_cgKs = cgGetNamedParameter(g_cgVertexProgram, "ks");
	g_cgShininess = cgGetNamedParameter(g_cgVertexProgram, "shininess");

	assert(g_cgWorldMatrix && g_cgWorldViewProjMatrix && g_cgAmbient &&
		   g_cgLightColor && g_cgLightPos && g_cgEyePos &&
		   g_cgKe && g_cgKa && g_cgKd && g_cgKs && g_cgShininess);

}
Beispiel #5
0
FFxProgram::FFxProgram(CGdomain aProfileDomain, const char* aFileName, const char* aEntry, const char** aArgs) :
mProgramFlags(0),
mProgram(0),
mSourceBuffer(0),
mProfileDomain(aProfileDomain)
{
#ifdef WIN32
	if (GDD->GetClassID() == ClassIDZDisplayDeviceDX9)
		mProfile = (aProfileDomain == CG_VERTEX_DOMAIN) ?cgD3D9GetLatestVertexProfile():cgD3D9GetLatestPixelProfile();
	else
#endif
	{
		mProfile = (aProfileDomain == CG_VERTEX_DOMAIN) ?cgGLGetLatestProfile(CG_GL_VERTEX):cgGLGetLatestProfile(CG_GL_FRAGMENT );

		cgGLSetOptimalOptions(mProfile);
		checkForCgError("setprofile");
	}

	mFileName = aFileName;
	mEntry = aEntry;
    // FIXME mArgs
	//mArgs = aArgs;
}
static bool d3d9_cg_load_program(void *data,
      struct shader_pass *pass,
      const char *prog, bool path_is_file)
{
   const char *list           = NULL;
   char *listing_f            = NULL;
   char *listing_v            = NULL;
   CGprofile vertex_profile   = cgD3D9GetLatestVertexProfile();
   CGprofile fragment_profile = cgD3D9GetLatestPixelProfile();
   const char **fragment_opts = cgD3D9GetOptimalOptions(fragment_profile);
   const char **vertex_opts   = cgD3D9GetOptimalOptions(vertex_profile);
   cg_renderchain_t *chain    = (cg_renderchain_t*)data;
   CGcontext cgCtx            = chain->cgCtx;

   if (
         fragment_profile == CG_PROFILE_UNKNOWN ||
         vertex_profile   == CG_PROFILE_UNKNOWN)
   {
      RARCH_ERR("Invalid profile type\n");
      goto error;
   }

   RARCH_LOG("[D3D9 Cg]: Vertex profile: %s\n",
         cgGetProfileString(vertex_profile));
   RARCH_LOG("[D3D9 Cg]: Fragment profile: %s\n",
         cgGetProfileString(fragment_profile));

   if (path_is_file && !string_is_empty(prog))
      pass->fprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE,
            prog, fragment_profile, "main_fragment", fragment_opts);
   else
      pass->fprg = cgCreateProgram(cgCtx, CG_SOURCE, stock_cg_d3d9_program,
            fragment_profile, "main_fragment", fragment_opts);

   list = cgGetLastListing(cgCtx);
   if (list)
      listing_f = strdup(list);

   if (path_is_file && !string_is_empty(prog))
      pass->vprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE,
            prog, vertex_profile, "main_vertex", vertex_opts);
   else
      pass->vprg = cgCreateProgram(cgCtx, CG_SOURCE, stock_cg_d3d9_program,
            vertex_profile, "main_vertex", vertex_opts);

   list = cgGetLastListing(cgCtx);
   if (list)
      listing_v = strdup(list);

   if (!pass->fprg || !pass->vprg)
      goto error;

   cgD3D9LoadProgram(pass->fprg, true, 0);
   cgD3D9LoadProgram(pass->vprg, true, 0);

   free(listing_f);
   free(listing_v);

   return true;

error:
   RARCH_ERR("CG error: %s\n", cgGetErrorString(cgGetError()));
   if (listing_f)
      RARCH_ERR("Fragment:\n%s\n", listing_f);
   else if (listing_v)
      RARCH_ERR("Vertex:\n%s\n", listing_v);
   free(listing_f);
   free(listing_v);

   return false;
}
Beispiel #7
0
	void D3D9Device::init(
		const ion_uint32 width,const ion_uint32 height,
		const base::String& title,const bool fullscreen,void* displayhandle,
		const ion_uint32 adapter,
		const video::Pixelformat colorbufferformat,
		const video::Pixelformat depthstencilformat,const ion_uint32 Hz,const bool vsync)
	{
		if (!m_IsValid) {
			base::log("D3D9Device::init()",base::Warning) <<
				"Initializing an invalid device\n";
		}

		openWindow(width,height,title,fullscreen,displayhandle);

		bool windowed=!m_Fullscreen;

		D3DFORMAT adapterfmt;
		if (windowed) {
			 D3DDISPLAYMODE d3ddm;
			 m_pD3D9->GetAdapterDisplayMode(adapter,&d3ddm);
			 adapterfmt=d3ddm.Format;
		} else adapterfmt=d3dpixelformat(colorbufferformat);

		if (adapterfmt==D3DFMT_UNKNOWN) {
			base::log("D3D9Device::init()",base::Error) << "Unknown/unsupported color buffer format\n";
			m_IsValid=false; return;
		}

		RECT r;
		GetClientRect(m_hWindow,&r);

		m_D3DPP.Windowed=windowed;
		m_D3DPP.BackBufferWidth=r.right-r.left;
		m_D3DPP.BackBufferHeight=r.bottom-r.top;
		m_D3DPP.BackBufferCount=1;
		m_D3DPP.BackBufferFormat=adapterfmt;
		m_D3DPP.AutoDepthStencilFormat=d3dpixelformat(depthstencilformat);
		m_D3DPP.EnableAutoDepthStencil=TRUE;
		m_D3DPP.Flags=0;
		m_D3DPP.PresentationInterval=vsync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_IMMEDIATE;
		m_D3DPP.FullScreen_RefreshRateInHz=windowed ? 0 : Hz;
		m_D3DPP.hDeviceWindow=m_hWindow;
		m_D3DPP.MultiSampleQuality=0;
		m_D3DPP.MultiSampleType=D3DMULTISAMPLE_NONE;
		m_D3DPP.SwapEffect=D3DSWAPEFFECT_DISCARD;
		m_D3DPP.Windowed=windowed;

		// Getting caps
		base::log("D3D9Device::init()",base::Message) << "Getting caps\n";

		HRESULT hr=m_pD3D9->GetDeviceCaps(adapter,D3DDEVTYPE_HAL,&m_D3DCaps);
		if (FAILED(hr)) {
			base::log("D3D9Device::init()",base::Error) << "GetDeviceCaps() failed\n";
			m_IsValid=false;
			return;
		}

		// Caps structure is initialized here
		{
			base::log("D3D9Device::init()",base::Message) << "Analyzing caps\n";

			m_Caps.m_NPOTTextures=!((m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_POW2) ||
				(m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_NONPOW2CONDITIONAL));
			m_Caps.m_RectangularTextures=(m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_SQUAREONLY)==0;
			m_Caps.m_Cubemaps=(m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_CUBEMAP)!=0;
			m_Caps.m_NPOTCubemaps=(m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_CUBEMAP_POW2)==0;
			m_Caps.m_ProjectedTextures=(m_D3DCaps.TextureCaps&D3DPTEXTURECAPS_PROJECTED)!=0;
			m_Caps.m_DisplacementMaps=false;
			m_Caps.m_CompressedTextures=false;

			m_Caps.m_MaxTextureWidth=m_D3DCaps.MaxTextureWidth;
			m_Caps.m_MaxTextureHeight=m_D3DCaps.MaxTextureHeight;
			m_Caps.m_MaxTextureVolumeDepth=m_D3DCaps.MaxVolumeExtent;
			m_Caps.m_MaxAnisotropy=m_D3DCaps.MaxAnisotropy;
			m_Caps.m_MaxTextureBlendStages=m_D3DCaps.MaxTextureBlendStages;
			m_Caps.m_MaxActiveFFLights=m_D3DCaps.MaxActiveLights;
			m_Caps.m_MaxPointSize=m_D3DCaps.MaxPointSize;
			m_Caps.m_MaxPrimitiveCount=m_D3DCaps.MaxPrimitiveCount;
			m_Caps.m_MaxVertexIndex=m_D3DCaps.MaxVertexIndex;

		}

		// Probing formats
		{

			video::Caps::Texflags **pTexflags,
				*pTexflagarrays[]={m_Caps.m_Valid2DTextureFormats,m_Caps.m_Valid3DTextureFormats,
				m_Caps.m_ValidCubemapFormats,0};

			const D3DRESOURCETYPE rtype[]={D3DRTYPE_TEXTURE,D3DRTYPE_VOLUMETEXTURE,D3DRTYPE_CUBETEXTURE};

			pTexflags=pTexflagarrays;
			unsigned int ii=0;

			base::log("D3D9Device::init()",base::Message) << "Probing texture formats\n";

			while (*pTexflags) {

				video::Caps::Texflags *pTexflagarray=*pTexflags;

				for (unsigned int i=0;i<video::Pixelformat_NumFormats;++i) {
					D3DFORMAT fmt=d3dpixelformat((video::Pixelformat)i);
					hr=0;

					hr=m_pD3D9->CheckDeviceFormat(adapter,D3DDEVTYPE_HAL,adapterfmt,0,rtype[ii],fmt);
					if (FAILED(hr)) { pTexflagarray[i].m_Supported=false; continue; }
					else pTexflagarray[i].m_Supported=true;

					if ((i==video::Pixelformat_RGB_DXT1)
						|| (i==video::Pixelformat_RGBA_DXT1)
						|| (i==video::Pixelformat_RGBA_DXT3)
						|| (i==video::Pixelformat_RGBA_DXT5))
						m_Caps.m_CompressedTextures=true;

					// Volume textures are not supported as render targets
					if (rtype[ii]!=D3DRTYPE_VOLUMETEXTURE) {
						hr=m_pD3D9->CheckDeviceFormat(adapter,D3DDEVTYPE_HAL,adapterfmt,D3DUSAGE_RENDERTARGET,rtype[ii],fmt);
						pTexflagarray[i].m_Rendertarget=(hr==D3D_OK);
						m_Caps.m_Rendertargets=true;
					} else pTexflagarray[i].m_Rendertarget=false;

					hr=m_pD3D9->CheckDeviceFormat(adapter,D3DDEVTYPE_HAL,adapterfmt,D3DUSAGE_DYNAMIC,rtype[ii],fmt);
					pTexflagarray[i].m_Dynamic=(hr==D3D_OK);

					// For depth buffers, only depth formats are supported
					// Volume textures are not supported
					if (isDepthformat((video::Pixelformat)i) && (rtype[ii]!=D3DRTYPE_VOLUMETEXTURE)) {
						hr=m_pD3D9->CheckDeviceFormat(adapter,D3DDEVTYPE_HAL,adapterfmt,D3DUSAGE_DEPTHSTENCIL,rtype[ii],fmt);
						pTexflagarray[i].m_Depth=(hr==D3D_OK);
					} else pTexflagarray[i].m_Depth=false;

					if ((m_D3DCaps.DevCaps2&D3DDEVCAPS2_DMAPNPATCH)!=0) {
						hr=m_pD3D9->CheckDeviceFormat(adapter,D3DDEVTYPE_HAL,adapterfmt,D3DUSAGE_DMAP,rtype[ii],fmt);
						pTexflagarray[i].m_DisplacementMap=(hr==D3D_OK);
					} else pTexflagarray[i].m_DisplacementMap=false;
				}

				++pTexflags;
				++ii;
			}
		}

		base::log("D3D9Device::init()",base::Message) << "Creating D3D device\n";

		hr=m_pD3D9->CreateDevice(adapter,D3DDEVTYPE_HAL,m_hWindow,
			D3DCREATE_HARDWARE_VERTEXPROCESSING,&m_D3DPP,&m_pD3DDev9);

		if (FAILED(hr)) {
			base::log("D3D9Device::init()",base::Error) << "CreateDevice() failed\n";
			m_IsValid=false;
			return;
		}

		D3DVIEWPORT9 viewport;
		viewport.X=0;
		viewport.Y=0;
		viewport.Width=r.right-r.left;
		viewport.Height=r.bottom-r.top;
		viewport.MinZ=0;
		viewport.MaxZ=1;
		m_pD3DDev9->SetViewport(&viewport);

#ifdef D3D9DRV_USE_CG
		base::log("D3D9Device::init()",base::Message) << "Initializing Cg\n";
		{
			m_CgContext=cgCreateContext();
			cgD3D9SetDevice(m_pD3DDev9);

#ifdef D3D9DRV_CG_DEBUG_ERRORCALLBACK
			errctx=m_CgContext;
			cgSetErrorCallback(cgErrorCallback);
#endif

			m_CgVertexProfile=cgD3D9GetLatestVertexProfile();
			m_CgFragmentProfile=cgD3D9GetLatestPixelProfile();
			m_CgOptimalVertexProfileOptions=cgD3D9GetOptimalOptions(m_CgVertexProfile);
			m_CgOptimalFragmentProfileOptions=cgD3D9GetOptimalOptions(m_CgFragmentProfile);
		}
#endif
			
		base::log("D3D9Device::init()",base::Message) << "Probing queries\n";
		{
			IDirect3DQuery9* pQuery=0;
			hr=m_pD3DDev9->CreateQuery(D3DQUERYTYPE_OCCLUSION,&pQuery);
			m_Caps.m_HWOcclusionQueries=(hr==D3D_OK);
			if (pQuery) pQuery->Release();
		}
			
		{
			base::log("D3D9Device::init()",base::Message) << "Probing vertex program support\n";

			// Supported vertex programs
			{
				unsigned int version=HIBYTE(LOWORD(m_D3DCaps.VertexShaderVersion));
				unsigned int subversion=LOBYTE(LOWORD(m_D3DCaps.VertexShaderVersion));

				if (version>=3) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_vs11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_vs20");
					m_Caps.m_SupportedProgramFormats.addString("d3d_vs30");
				} else if (version>=2) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_vs11");
					if (subversion>=0) m_Caps.m_SupportedProgramFormats.addString("d3d_vs20");
				} else if (version>=1) {
					if (subversion>=1) m_Caps.m_SupportedProgramFormats.addString("d3d_vs11");
				}

				// HLSL support

				LPCSTR vsprofile=D3DXGetVertexShaderProfile(m_pD3DDev9);
				base::String hlslvsprofile;
				if (vsprofile) hlslvsprofile=vsprofile;

				if (hlslvsprofile.compare("vs_1_1",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs11");
				} else if (hlslvsprofile.compare("vs_2_0",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs20");
				} else if (hlslvsprofile.compare("vs_2_a",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs20");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs2a");
				} else if (hlslvsprofile.compare("vs_3_0",true) || (version>=3)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs20");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs2a");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_vs30");
				}

#ifdef D3D9DRV_USE_CG
				m_Caps.m_SupportedProgramFormats.addString("cg_vprogram");
#endif
			}

			base::log("D3D9Device::init()",base::Message) << "Probing fragment program support\n";

			// Supported fragment programs
			{
				unsigned int version=HIBYTE(LOWORD(m_D3DCaps.PixelShaderVersion));
				unsigned int subversion=LOBYTE(LOWORD(m_D3DCaps.PixelShaderVersion));

				if (version>=3) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps12");
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps13");
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps14");
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps20");
					if (subversion>=0) m_Caps.m_SupportedProgramFormats.addString("d3d_ps30");
				} else if (version>=2) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps12");
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps13");
					m_Caps.m_SupportedProgramFormats.addString("d3d_ps14");
					if (subversion>=0) m_Caps.m_SupportedProgramFormats.addString("d3d_ps20");
				} else if (version>=1) {
					if (subversion>=1) m_Caps.m_SupportedProgramFormats.addString("d3d_ps11");
					if (subversion>=2) m_Caps.m_SupportedProgramFormats.addString("d3d_ps12");
					if (subversion>=3) m_Caps.m_SupportedProgramFormats.addString("d3d_ps13");
					if (subversion>=4) m_Caps.m_SupportedProgramFormats.addString("d3d_ps14");
				}
				

				

				// HLSL support

				LPCSTR vsprofile=D3DXGetPixelShaderProfile(m_pD3DDev9);
				base::String hlslpsprofile;
				if (vsprofile) hlslpsprofile=vsprofile;

				if (hlslpsprofile.compare("ps_1_1",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11");
				} else if (hlslpsprofile.compare("ps_1_2",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12");
				} else if (hlslpsprofile.compare("ps_1_3",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps13");
				} else if (hlslpsprofile.compare("ps_1_4",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps13");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps14");
				} else if (hlslpsprofile.compare("ps_2_0",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps13");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps14");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps20");
				} else if (hlslpsprofile.compare("ps_2_a",true)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps13");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps14");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps20");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps2a");
				} else if (hlslpsprofile.compare("ps_3_0",true) || (version>=3)) {
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps11");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps12");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps13");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps14");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps20");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps2a");
					m_Caps.m_SupportedProgramFormats.addString("d3d_hlsl_ps30");
				}

#ifdef D3D9DRV_USE_CG
				m_Caps.m_SupportedProgramFormats.addString("cg_fprogram");
#endif
			}

		} // Caps end

		m_Displaywidth=viewport.Width;
		m_Displayheight=viewport.Height;
		m_ColorbufferFormat=colorbufferformat;
		m_DepthstencilbufferFormat=depthstencilformat;

		m_pD3DDev9->SetRenderState(D3DRS_FOGVERTEXMODE,D3DFOG_LINEAR);

		fixedLighting(false);

		base::log("D3D9Device::init()",base::Message) << "Init complete\n";
	}
void CD3D9CgMaterialRenderer::init(s32& pMaterialType,
	const c8* pVertexProgram, const c8* pVertexEntry, E_VERTEX_SHADER_TYPE pVertexProfile,
	const c8* pFragmentProgram, const c8* pFragmentEntry, E_PIXEL_SHADER_TYPE pFragmentProfile,
	const c8* pGeometryProgram, const c8* pGeometryEntry, E_GEOMETRY_SHADER_TYPE pGeometryProfile,
	scene::E_PRIMITIVE_TYPE pInType, scene::E_PRIMITIVE_TYPE pOutType, u32 pVertices)
{
	bool Status = true;
	CGerror Error = CG_NO_ERROR;
	pMaterialType = -1;

	// TODO: add profile selection

	if (pVertexProgram)
	{
		VertexProfile = cgD3D9GetLatestVertexProfile();

		if (VertexProfile)
			VertexProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, pVertexProgram, VertexProfile, pVertexEntry, 0);

		if (!VertexProgram)
		{
			Error = cgGetError();
			os::Printer::log("Cg vertex program failed to compile:", ELL_ERROR);
			os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR);

			Status = false;
		}
		else
			cgD3D9LoadProgram(VertexProgram, 0, 0);
	}

	if (pFragmentProgram)
	{
		FragmentProfile = cgD3D9GetLatestPixelProfile();

		if (FragmentProfile)
			FragmentProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, pFragmentProgram, FragmentProfile, pFragmentEntry, 0);

		if (!FragmentProgram)
		{
			Error = cgGetError();
			os::Printer::log("Cg fragment program failed to compile:", ELL_ERROR);
			os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR);

			Status = false;
		}
		else
			cgD3D9LoadProgram(FragmentProgram, 0, 0);
	}

	/*if (pGeometryProgram)
	{
		GeometryProfile = cgD3D9GetLatestGeometryProfile();

		if (GeometryProfile)
			GeometryProgram = cgCreateProgram(Driver->getCgContext(), CG_SOURCE, pGeometryProgram, GeometryProfile, pGeometryEntry, 0);

		if (!GeometryProgram)
		{
			Error = cgGetError();
			os::Printer::log("Cg geometry program failed to compile:", ELL_ERROR);
			os::Printer::log(cgGetLastListing(Driver->getCgContext()), ELL_ERROR);

			Status = false;
		}
		else
			cgD3D9LoadProgram(GeometryProgram, 0, 0);
	}*/

	getUniformList();

	// create D3D9 specifics sampler uniforms.
	for(unsigned int i = 0; i < UniformInfo.size(); ++i)
	{
		if (UniformInfo[i]->getType() == CG_SAMPLER2D)
		{
			bool IsGlobal = true;

			if (UniformInfo[i]->getSpace() == CG_PROGRAM)
				IsGlobal = false;

			CCgUniform* Uniform = new CD3D9CgUniformSampler2D(UniformInfo[i]->getParameter(), IsGlobal);
			delete UniformInfo[i];
			UniformInfo[i] = Uniform;
		}
	}

	if (Status)
		pMaterialType = Driver->addMaterialRenderer(this);
}
Beispiel #9
0
bool CD3DCG::LoadShader(const TCHAR *shaderFile)
{
	CCGShader cgShader;
	TCHAR shaderPath[MAX_PATH];
	TCHAR tempPath[MAX_PATH];
	HRESULT hr;
	GLenum error;

	ClearPasses();

	if (shaderFile == NULL || *shaderFile==TEXT('\0'))
		return true;

	lstrcpy(shaderPath,shaderFile);
	for(int i=lstrlen(shaderPath); i>=0; i--){
		if(IS_SLASH(shaderPath[i])){
			shaderPath[i]=TEXT('\0');
			break;
		}
	}

	SetCurrentDirectory(shaderPath);
	if(!cgShader.LoadShader(_tToChar(shaderFile)))
		return false;

	CGprofile vertexProfile = cgD3D9GetLatestVertexProfile();
	CGprofile pixelProfile = cgD3D9GetLatestPixelProfile();

	const char** vertexOptions = cgD3D9GetOptimalOptions(vertexProfile);
	const char** pixelOptions = cgD3D9GetOptimalOptions(pixelProfile);

	shaderPasses.push_back(shaderPass());

	for(CCGShader::passVector::iterator it=cgShader.shaderPasses.begin();
			it!=cgShader.shaderPasses.end();it++) {
		shaderPass pass;

		pass.scaleParams = it->scaleParams;
		/* if this is the last pass (the only one that can have CG_SCALE_NONE)
		   and no filter has been set use the GUI setting
		*/
		if(pass.scaleParams.scaleTypeX==CG_SCALE_NONE && !it->filterSet) {
			pass.linearFilter = GUI.BilinearFilter;
		} else {
			pass.linearFilter = it->linearFilter;
		}

		// paths in the meta file can be relative
		_tfullpath(tempPath,_tFromChar(it->cgShaderFile),MAX_PATH);
		char *fileContents = ReadShaderFileContents(tempPath);
		if(!fileContents)
			return false;

		pass.cgVertexProgram = cgCreateProgram( cgContext, CG_SOURCE, fileContents,
						vertexProfile, "main_vertex", vertexOptions);

		checkForCgError("Compiling vertex program");

		pass.cgFragmentProgram = cgCreateProgram( cgContext, CG_SOURCE, fileContents,
						pixelProfile, "main_fragment", pixelOptions);

		checkForCgError("Compiling fragment program");

		delete [] fileContents;
		if(!pass.cgVertexProgram || !pass.cgFragmentProgram) {
			return false;
		}
		if(pass.cgVertexProgram) {
			hr = cgD3D9LoadProgram(pass.cgVertexProgram,false,0);
		}
		checkForCgError("Loading vertex program");
		if(pass.cgFragmentProgram) {
			hr = cgD3D9LoadProgram(pass.cgFragmentProgram,false,0);
		}
		checkForCgError("Loading fragment program");

		/* generate vertex buffer
		*/
		
		hr = pDevice->CreateVertexBuffer(sizeof(VERTEX)*4,D3DUSAGE_WRITEONLY,0,D3DPOOL_MANAGED,&pass.vertexBuffer,NULL);
		if(FAILED(hr)) {
			pass.vertexBuffer = NULL;
			DXTRACE_ERR_MSGBOX(TEXT("Error creating vertex buffer"), hr);
			return false;
		}

		/* set up vertex declarations for the pass,
		   this also creates the vertex declaration
		*/
		setupVertexDeclaration(pass);

		shaderPasses.push_back(pass);
	}

	for(std::vector<CCGShader::lookupTexture>::iterator it=cgShader.lookupTextures.begin();it!=cgShader.lookupTextures.end();it++) {		
		lookupTexture tex;
		strcpy(tex.id,it->id);
		tex.linearFilter = it->linearfilter;

		_tfullpath(tempPath,_tFromChar(it->texturePath),MAX_PATH);

		hr = D3DXCreateTextureFromFileEx(
               pDevice,
               tempPath,
               D3DX_DEFAULT_NONPOW2,
               D3DX_DEFAULT_NONPOW2,
               0,
               0,
               D3DFMT_FROM_FILE,
               D3DPOOL_MANAGED,
			   it->linearfilter?D3DX_FILTER_LINEAR:D3DX_FILTER_POINT,
               0,
               0,
               NULL,
               NULL,
               &tex.tex);
		if FAILED(hr){
			tex.tex = NULL;
		}
		lookupTextures.push_back(tex);
	}

	shaderLoaded = true;

	return true;
}