Esempio n. 1
0
TexturePtr DrawContext::disc(u16 radius)
{
  TexturePtr result;
  
  string path = discPath(radius);
  if(!Application::instance()->resourceManager->hasTexture(path))
  {
    BitmapPtr bitmap(new Bitmap(2*radius, 2*radius, GL_RGBA));
    bitmap->disc(radius-.5, radius-.5, radius+.5);
    bitmap->premultiplyAlpha();
    result.reset(new Texture(bitmap));
    Application::instance()->resourceManager->texture(path, result);
  }
  else
  {
    result = Application::instance()->resourceManager->texture(path);
  }
  
  return result;
}
Esempio n. 2
0
	void setupScene()
	{
		m_window->getViewports().front()->setRenderQueueIdMask(~RenderQueueId_OffscreenTransparentObjects);

		LightPtr light(new Light);
		light->setDirection(glm::normalize(glm::vec3(1.5, -1, -0.5)));
		light->setPosition(glm::vec3(0, 0.5, 0) + light->getDirection() * -10.0f);
		m_visSystem->addLight(light);

		// Volume
		std::vector<std::string> gridNames;
		gridNames.push_back(m_config.densityGridName);

		if (!m_config.temperatureGridName.empty())
		{
			gridNames.push_back(m_config.temperatureGridName);
		}

		std::vector<openvdb::GridBase::Ptr> baseGrids = loadGridsFromFile(m_config.vdbVilename, gridNames);

		openvdb::FloatGrid::Ptr densityGrid = openvdb::gridPtrCast<openvdb::FloatGrid>(baseGrids[0]);

		openvdb::FloatGrid::Ptr temperatureGrid;
		if (!m_config.temperatureGridName.empty())
		{
			temperatureGrid = openvdb::gridPtrCast<openvdb::FloatGrid>(baseGrids[1]);

			// Rescale temperature field to between 0 and 1
			{
				float minValue = 99999999999999;
				float maxValue = -99999999999999;
				for (openvdb::FloatGrid::ValueOnCIter iter = temperatureGrid->cbeginValueOn(); iter.test(); ++iter) {
					float value = *iter;
					minValue = std::min(minValue, value);
					maxValue = std::max(maxValue, value);
				}

				float scale = 1.0 / (maxValue - minValue);

				for (openvdb::FloatGrid::ValueOnIter iter = temperatureGrid->beginValueOn(); iter.test(); ++iter) {
					float value = *iter;
					value = (value - minValue) * scale;
					iter.setValue(value);
				}
			}

			// Ensure both grids have the same hierarchy
			{
				openvdb::FloatGrid::Ptr resultGrid = openvdb::FloatGrid::create();
				resultGrid->tree().combine2(densityGrid->tree(), temperatureGrid->tree(), CopyBIntoA());
				temperatureGrid->tree().combine(densityGrid->tree(), CopyBIntoA());

				densityGrid = resultGrid; 
			}
		}

		std::vector<GridPtr> grids;
		GridTextureRolesMap gridTextureRoles;

		grids.push_back(GridPtr(new VdbGrid<openvdb::FloatGrid>(densityGrid, 1)));
		gridTextureRoles[GridTextureRole_Diffuse] = grids.back();

		if (m_config.generateNormals)
		{
			Vec3UByteGrid::Ptr normalGrid = createNormalGrid(*densityGrid);
			grids.push_back(GridPtr(new VdbGrid<Vec3UByteGrid>(normalGrid, 3)));
			gridTextureRoles[GridTextureRole_Normal] = grids.back();
		}

		if (temperatureGrid)
		{
			grids.push_back(GridPtr(new VdbGrid<openvdb::FloatGrid>(temperatureGrid, 1)));
			gridTextureRoles[GridTextureRole_Temperature] = grids.back();
		}

		openvdb::CoordBBox bbox;
		densityGrid->constTree().evalLeafBoundingBox(bbox);

		float scale = 1.0f / (float)bbox.extents().asVec3s().length();

		glm::vec3 center = toVec3(bbox.getCenter() * scale);
		std::ostringstream ss;
		ss << "Grid extents: " << bbox.extents().x() << ", " << bbox.extents().y() << ", " << bbox.extents().z();
		defaultLogger()->logLine(ss.str());

		int renderQueueId;
		if (m_config.renderToLowResTarget)
		{
			renderQueueId = RenderQueueId_OffscreenTransparentObjects;
		}
		else
		{
			renderQueueId = getDefaultRenderQueueId();
		}

		RenderableVolumeConfig config;
		config.grids = grids;
		config.materialFactory.reset(new SparseVolumeMaterialFactoryI(gridTextureRoles, m_config.transparent, m_config.opacityMultiplier));
		config.scale = scale;
		config.batchBoxes = !m_config.transparent; // don't batch if we have transparency so we can sort

		RenderableVolumePtr volume = RenderableVolumeFactory::createRenderableVolume(config);
		BOOST_FOREACH(const GVis::RenderableNodePtr& node, volume->nodes)
		{
			node->translate(-center);
			m_visSystem->addRenderableNode(node, renderQueueId);
		}

		if (m_config.transparent)
		{
			RenderQueuePtr renderQueue = m_visSystem->getRenderQueue(renderQueueId);
			if (renderQueue)
				renderQueue->setSortingMode(RenderSortingMode_BackToFront);
		}

		if (m_config.renderToLowResTarget)
		{
			int volumeTargetWidth = m_window->getWidth() / 2;
			int volumeTargetHeight = m_window->getHeight() / 2;

			TexturePtr offscreenTransparentObjectsTexture;
			// Create offscreen transparent objects target
			{
				ImageTextureConfig config = ImageTextureConfig::createDefault();
				config.width = volumeTargetWidth;
				config.height = volumeTargetHeight;
				config.textureAddressMode = TextureAddressMode_Clamp;
				offscreenTransparentObjectsTexture.reset(new Texture(config));

				{
					RenderTextureTargetConfig config;
					config.texture = offscreenTransparentObjectsTexture;
					config.attachment = FrameBufferAttachment_Color;
					RenderTextureTargetPtr target(new RenderTextureTarget(config));

					{
						ViewportPtr viewport = target->addDefaultViewport(m_camera);
						viewport->setRenderQueueIdMask(RenderQueueId_OffscreenTransparentObjects);
						viewport->setBackgroundColor(glm::vec4(0,0,0,0));
					}

					m_window->addRenderTarget(target);
				}
			}

			// Composite offscreen particles
			{
				TextureUnit textureUnit(offscreenTransparentObjectsTexture, "albedoSampler");

				ShaderProgramPtr shader = ShaderProgram::createShaderProgram(ShaderProgramConfig("Shaders/Common/ScreenQuad.vert", "Shaders/Common/SimpleTextured.frag"));
				TechniquePtr technique(new Technique(shader));
				technique->addTextureUnit(textureUnit);
				technique->setAlphaBlendingMode(AlphaBlendingMode_PreMultiplied);
				MaterialPtr material(new Material);
				material->setTechnique(technique);

				{
					RectangleConfig config = RectangleConfig::defaultWithSize(glm::vec2(2, 2));
					MeshPtr mesh = RectangleMeshFactory::createMesh(config);
					GeoPtr geo(new Geo(mesh, material));
					
					RenderableNodePtr renderableNode = RenderableNode::createWithSingleGeo(geo);
					m_visSystem->addRenderableNode(renderableNode, RenderQueueId_CompositeOffscreenTransparentObjects);
				}
			}
		}

		if (m_config.orbitCam)
		{
			centerNode.reset(new SceneNode);
			centerNode->addChild(m_camera);
			m_cameraInputEnabled = false;
		}
		m_camera->setPosition_parentSpace(glm::vec3(0,0,1.4));
	}
Esempio n. 3
0
MeshContainer* XFileLoader::CreateMeshContainer()
{
	HRESULT hr;

	MeshContainer* meshContainer = NULL;

	Graphics* graphics = Graphics::GetInstance();
	IDirect3DDevice9Ptr pD3DDevice = graphics->GetDirect3DDevice();

	if( !(m_pD3DMesh->GetFVF() & D3DFVF_NORMAL) )
    {
		LPD3DXMESH tmpMesh = NULL;

        // 柔軟な頂点フォーマット (FVF) コードを使ってメッシュのコピーを作成する
        hr = m_pD3DMesh->CloneMeshFVF(
            m_pD3DMesh->GetOptions(),
            m_pD3DMesh->GetFVF() | D3DFVF_NORMAL,
            pD3DDevice,
            &tmpMesh); // ←ここにコピー
        if(FAILED(hr))
        {
            goto exit;
        }
        // メッシュに含まれる各頂点の法線を計算して、設定する
        //D3DXComputeNormals( tmpMesh, reinterpret_cast<DWORD*>(pAdjacencyBuf->GetBufferPointer()) );
		D3DXComputeNormals( tmpMesh, NULL );

		m_pD3DMesh->Release();
		m_pD3DMesh = tmpMesh;
	}

	D3DVERTEXELEMENT9 pDecl[MAX_FVF_DECL_SIZE];
	hr = m_pD3DMesh->GetDeclaration(pDecl);
	if( FAILED(hr) )
	{
		goto exit;
	}

	DWORD vertexNum = m_pD3DMesh->GetNumVertices();
	DWORD faceNum = m_pD3DMesh->GetNumFaces();

	DWORD attrNum = 0;
	m_pD3DMesh->GetAttributeTable(NULL, &attrNum);
	
	DWORD size = m_pD3DMesh->GetNumBytesPerVertex();

	BYTE* pD3DVertice = NULL;
	m_pD3DMesh->LockVertexBuffer( 0,(LPVOID*)&pD3DVertice );

	sVertex* vertices = new sVertex[vertexNum];

	for( DWORD vertIdx = 0;vertIdx<vertexNum;vertIdx++ )
	{
		sVertex* vertex = &vertices[vertIdx];
		vertex->uv = D3DXVECTOR2(0.0f,0.0f);
		vertex->color = 0xFFFFFFFF;

		for( DWORD i=0;i<MAX_FVF_DECL_SIZE;i++ )
		{
			D3DVERTEXELEMENT9& decl = pDecl[i];

			if( decl.Stream==0xFF )
			{
				break;
			}

			switch( decl.Usage )
			{
			case D3DDECLUSAGE_POSITION:
				vertex->position = *(D3DXVECTOR3*)(pD3DVertice+vertIdx*size+decl.Offset);
				vertex->position = vertex->position * m_scale;
				break;
			case D3DDECLUSAGE_NORMAL:
				vertex->normal = *(D3DXVECTOR3*)(pD3DVertice+vertIdx*size+decl.Offset);
				break;
			case D3DDECLUSAGE_TEXCOORD:
				vertex->uv = *(D3DXVECTOR2*)(pD3DVertice+vertIdx*size+decl.Offset);
				break;
			case D3DDECLUSAGE_COLOR:
				vertex->color = *(DWORD*)(pD3DVertice+vertIdx*size+decl.Offset);
				break;
			}
		}
	}

	m_pD3DMesh->UnlockVertexBuffer();

	LPDIRECT3DINDEXBUFFER9 pIndexBuffer = NULL;
	m_pD3DMesh->GetIndexBuffer( &pIndexBuffer );
	D3DINDEXBUFFER_DESC desc;
	pIndexBuffer->GetDesc( &desc );
	pIndexBuffer->Release();

	DWORD* indices = new DWORD[faceNum*3];

	if( desc.Format==D3DFMT_INDEX16 )
	{
		WORD* pD3DIndices = NULL;
		m_pD3DMesh->LockIndexBuffer(0,(LPVOID*)&pD3DIndices );
		for( DWORD i=0;i<faceNum*3;i++ )
		{
			indices[i] = pD3DIndices[i];
		}
		m_pD3DMesh->UnlockIndexBuffer();
	}
	else
	{
		DWORD* pD3DIndices =NULL;
		m_pD3DMesh->LockIndexBuffer(0,(LPVOID*)&pD3DIndices );
		memcpy( indices,pD3DIndices,sizeof(DWORD)*faceNum*3 );
		m_pD3DMesh->UnlockIndexBuffer();
	}

	D3DXATTRIBUTERANGE *attrList = new D3DXATTRIBUTERANGE[attrNum];
	m_pD3DMesh->GetAttributeTable(attrList, &attrNum);

	meshContainer = new MeshContainer;

	meshContainer->pMesh = new Mesh;
	meshContainer->pMesh->Create( vertexNum,faceNum,attrNum );

	meshContainer->pMesh->SetVertices( vertices );

	meshContainer->pMesh->SetIndices( indices );

	meshContainer->pMesh->SetAttributeRanges( attrList );

	delete[] vertices;
	delete[] indices;
	delete[] attrList;

	meshContainer->materialNum = m_Materials;
	meshContainer->pMaterials = new sMaterial[m_Materials];

	D3DXMATERIAL* pD3DMaterials = (D3DXMATERIAL*)m_pMaterialBuf->GetBufferPointer();

	for( DWORD i=0;i<m_Materials;i++ )
	{
		sMaterial* pMaterial = &meshContainer->pMaterials[i];

		D3DXMATERIAL* pD3DMaterial = &pD3DMaterials[i];

		pMaterial->colorDiffuse = pD3DMaterial->MatD3D.Diffuse;

		pMaterial->colorSpecular.r = pD3DMaterial->MatD3D.Specular.r;
		pMaterial->colorSpecular.g = pD3DMaterial->MatD3D.Specular.g;
		pMaterial->colorSpecular.b = pD3DMaterial->MatD3D.Specular.b;
		pMaterial->colorSpecular.a = 0.0f;

		pMaterial->colorAmbient.r = pD3DMaterial->MatD3D.Diffuse.r;
		pMaterial->colorAmbient.g = pD3DMaterial->MatD3D.Diffuse.g;
		pMaterial->colorAmbient.b = pD3DMaterial->MatD3D.Diffuse.b;
		pMaterial->colorAmbient.a = 0.0f;

		pMaterial->colorEmissive.r = pD3DMaterial->MatD3D.Emissive.r;
		pMaterial->colorEmissive.g = pD3DMaterial->MatD3D.Emissive.g;
		pMaterial->colorEmissive.b = pD3DMaterial->MatD3D.Emissive.b;
		pMaterial->colorEmissive.a = 0.0f;

		pMaterial->specularPower = pD3DMaterial->MatD3D.Power;

		TCHAR path[MAX_PATH];
		_tcscpy_s( path,m_path.c_str() );

		tstring texFileName;
		tstring sphereFileName;

		if( pD3DMaterial->pTextureFilename && strlen(pD3DMaterial->pTextureFilename)>0 )
		{
			tstring filename = to_tstring(pD3DMaterial->pTextureFilename);

			tstring::size_type index = filename.find( _T("*") );
			if( index != tstring::npos )
			{
				sphereFileName = filename.substr( index+1 );
				PathAppend( path,sphereFileName.c_str() );
				sphereFileName = path;
				PathRemoveFileSpec( path );

				texFileName = filename.erase( index );
				PathAppend( path,texFileName.c_str() );
				texFileName = path;
				PathRemoveFileSpec( path );
			}
			else
			{
				texFileName = filename;
				PathAppend( path,texFileName.c_str() );
				texFileName = path;
				PathRemoveFileSpec( path );
			}

			tstring ext = PathFindExtension( texFileName.c_str() );

			if( ext == _T(".sph" ) || ext == _T(".spa") )
			{
				sphereFileName = texFileName;
				texFileName = _T("");
			}
		}

		if( !texFileName.empty() )
		{
			TexturePtr pTex = ResourceManager::GetInstance().GetResource<Texture>( texFileName );
			if( !pTex )
			{
				pTex = TexturePtr(new Texture);
				if( pTex->CreateFromFile( texFileName ) )
				{
					ResourceManager::GetInstance().AddResource( texFileName,pTex );
				}
				else
				{
					pTex.reset();
				}
			}

			if( pTex )
			{
				pMaterial->textureDiffuse = pTex;
			}
		}

		if( !sphereFileName.empty() )
		{
			TexturePtr pTex = ResourceManager::GetInstance().GetResource<Texture>( sphereFileName );
			if( !pTex )
			{
				pTex = TexturePtr(new Texture);
				if( pTex->CreateFromFile( sphereFileName ) )
				{
					ResourceManager::GetInstance().AddResource( sphereFileName,pTex );
				}
				else
				{
					pTex.reset();
				}
			}

			if( pTex )
			{
				pMaterial->textureSphere = pTex;
			}

			tstring ext = PathFindExtension( sphereFileName.c_str() );
			if( ext == _T(".sph" ) )
			{
				pMaterial->spheremap = eSPHEREMAP_MUL;
			}
			else if( ext == _T(".spa") )
			{
				pMaterial->spheremap = eSPHEREMAP_ADD;
			}
		}
	}

exit:
	if( m_pMaterialBuf )
	{
		m_pMaterialBuf->Release();
		m_pMaterialBuf = NULL;
	}
	if( m_pEffectInstancesBuf )
	{
		m_pEffectInstancesBuf->Release();
		m_pEffectInstancesBuf = NULL;
	}
	if( m_pAdjacencyBuf )
	{
		m_pAdjacencyBuf->Release();
		m_pAdjacencyBuf = NULL;
	}
	if( m_pD3DMesh )
	{
		m_pD3DMesh->Release();
		m_pD3DMesh = NULL;
	}
	return meshContainer;
}
PMDModelPtr PMDFileLoader::Open( const tstring& filePath )
{
	m_fileName = filePath;

	TCHAR path[MAX_PATH];
	_tcscpy_s( path,MAX_PATH,filePath.c_str() );
	PathRemoveFileSpec( path );
	PathAddBackslash( path );
	m_path = path;

	FILE* fp=NULL;
	if( _tfopen_s(&fp,m_fileName.c_str(),_T("rb"))!=0 )
	{
		return PMDModelPtr();
	}

	fpos_t fsize = 0;
	fseek(fp,0,SEEK_END);
	fgetpos(fp,&fsize);

	fseek(fp,0,SEEK_SET); 

	size_t sz=(size_t)fsize;

	unsigned char* buffer=new unsigned char[sz];
	fread(buffer,1,sz,fp);

	fclose(fp);

	sPMD* pmd = new sPMD;
	bool ret = PMDLoad(buffer,sz,pmd);
	
	delete[] buffer;

	if( !ret )
	{
		delete pmd;
		return PMDModelPtr();
	}

	sPMD_Skin* skinBase = NULL;

	for( DWORD skinIdx=0;skinIdx<pmd->skin_list.skin_count;skinIdx++ )
	{
		sPMD_Skin* skin = &pmd->skin_list.skin[skinIdx];

		if( skin->skin_type == ePMD_SkinType_Base )
		{
			skinBase = skin;

			for( DWORD vertIdx = 0; vertIdx < skin->skin_vert_count ; vertIdx++ )
			{
				DWORD targetIndex = skin->skin_vert[vertIdx].index;
				memcpy( pmd->vertex_list.vertex[ targetIndex ].pos, skin->skin_vert[vertIdx].pos,sizeof(float)*3 );
			}
			
			break;
		}
	}

	for( DWORD skinIdx=0;skinIdx<pmd->skin_list.skin_count;skinIdx++ )
	{
		sPMD_Skin* skin = &pmd->skin_list.skin[skinIdx];

		if( skin->skin_type != ePMD_SkinType_Base )
		{
			for( DWORD vertIdx = 0; vertIdx < skin->skin_vert_count ; vertIdx++ )
			{
				DWORD targetIndex = skin->skin_vert[vertIdx].index;
				skin->skin_vert[vertIdx].index = skinBase->skin_vert[ targetIndex ].index;
			}
		}
	}

	Graphics* graphics = Graphics::GetInstance();

	sMaterial* pMaterials = new sMaterial[pmd->material_list.material_count];

	for( DWORD i=0;i<pmd->material_list.material_count;i++ )
	{
		sPMD_Material* pmdMat = &pmd->material_list.material[i];
		sMaterial* pMaterial = &pMaterials[i];

		pMaterial->colorDiffuse.r = 0.0f;
		pMaterial->colorDiffuse.g = 0.0f;
		pMaterial->colorDiffuse.b = 0.0f;
		pMaterial->colorDiffuse.a = pmdMat->alpha;

		pMaterial->colorAmbient.r = pmdMat->diffuse_color[0];
		pMaterial->colorAmbient.g = pmdMat->diffuse_color[1];
		pMaterial->colorAmbient.b = pmdMat->diffuse_color[2];
		pMaterial->colorAmbient.a = 0.0f;

		pMaterial->colorSpecular.r = pmdMat->specular_color[0];
		pMaterial->colorSpecular.g = pmdMat->specular_color[1];
		pMaterial->colorSpecular.b = pmdMat->specular_color[2];
		pMaterial->colorSpecular.a = 0.0f;

		pMaterial->colorEmissive.r = pmdMat->ambient_color[0];
		pMaterial->colorEmissive.g = pmdMat->ambient_color[1];
		pMaterial->colorEmissive.b = pmdMat->ambient_color[2];
		pMaterial->colorEmissive.a = 0.0f;

		pMaterial->specularPower = pmdMat->specularity;

		pMaterial->spheremap = eSPHEREMAP_MUL;

		pMaterial->edge = pmdMat->edge_flag!=0;

		TCHAR path[MAX_PATH];
		_tcscpy_s( path,m_path.c_str() );

		tstring texFileName;
		tstring sphereFileName;

		if( strlen(pmdMat->texture_file_name)>0 )
		{
			tstring filename = to_tstring(pmdMat->texture_file_name);

			tstring::size_type index = filename.find( _T("*") );
			if( index != tstring::npos )
			{
				sphereFileName = filename.substr( index+1 );
				PathAppend( path,sphereFileName.c_str() );
				sphereFileName = path;
				PathRemoveFileSpec( path );

				texFileName = filename.erase( index );
				PathAppend( path,texFileName.c_str() );
				texFileName = path;
				PathRemoveFileSpec( path );
			}
			else
			{
				texFileName = filename;
				PathAppend( path,texFileName.c_str() );
				texFileName = path;
				PathRemoveFileSpec( path );
			}

			tstring ext = PathFindExtension( texFileName.c_str() );

			if( ext == _T(".sph" ) || ext == _T(".spa") )
			{
				sphereFileName = texFileName;
				texFileName = _T("");
			}
		}

		if( !texFileName.empty() )
		{
			TexturePtr pTex = ResourceManager::GetInstance().GetResource<Texture>( texFileName );
			if( !pTex )
			{
				pTex = TexturePtr(new Texture);
				pTex->CreateFromFile( texFileName );

				ResourceManager::GetInstance().AddResource( texFileName,pTex );
			}

			pMaterial->textureDiffuse = pTex;
		}

		if( !sphereFileName.empty() )
		{
			TexturePtr pTex = ResourceManager::GetInstance().GetResource<Texture>( sphereFileName );
			if( !pTex )
			{
				pTex = TexturePtr(new Texture);
				pTex->CreateFromFile( sphereFileName );

				ResourceManager::GetInstance().AddResource( sphereFileName,pTex );
			}

			pMaterial->textureSphere = pTex;

			tstring ext = PathFindExtension( sphereFileName.c_str() );
			if( ext == _T(".sph" ) )
			{
				pMaterial->spheremap = eSPHEREMAP_MUL;
			}
			else if( ext == _T(".spa") )
			{
				pMaterial->spheremap = eSPHEREMAP_ADD;
			}
		}

		pMaterial->colorToon = D3DXCOLOR( 1.0f,1.0f,1.0f,1.0f );

		tstring toonTexName = _T("");
		tstring toonTexPath = _T("");

		if( 0<=pmdMat->toon_index && pmdMat->toon_index<10 )
		{
			// TODO:デフォルトのtoonファイルは固定パスか・・・
			toonTexName = to_tstring( pmd->toon_list.toon_file_name[pmdMat->toon_index] );
		}

		TexturePtr pTex;
		
		if( !toonTexName.empty() )
		{
			PathAppend( path,toonTexName.c_str() );
			toonTexPath = path;
			PathRemoveFileSpec( path );

			pTex = ResourceManager::GetInstance().GetResource<Texture>( toonTexPath );
			if( !pTex )
			{
				pTex = TexturePtr(new Texture);
				if( !pTex->CreateFromFile( toonTexPath ) )
				{
					pTex.reset();
				}
			}
		}

		if( !pTex )
		{
			pTex = graphics->GetDefaultToonTexture( pmdMat->toon_index );
			if( !pTex )
			{
				toonTexPath = _T("<FFFFFFFF>");

				pTex = ResourceManager::GetInstance().GetResource<Texture>( toonTexPath );
				if( !pTex )
				{
					pTex = TexturePtr(new Texture);
					if( !pTex->CreateDotColor( 0xFFFFFFFF ) )
					{
						pTex.reset();
					}
				}
			}
		}
		
		if( pTex )
		{
			pMaterial->textureToon = pTex;

			ResourceManager::GetInstance().AddResource( toonTexPath,pTex );

			IDirect3DTexture9Ptr pD3DTexture = pTex->GetTexture();

			D3DSURFACE_DESC desc;
			pD3DTexture->GetLevelDesc( 0,&desc );

			D3DLOCKED_RECT lockRect;
			pD3DTexture->LockRect(0, &lockRect, NULL, 0);

			int x = 0;
			int y = desc.Height-1;

			DWORD color;

			memcpy(&color,(BYTE*)lockRect.pBits + lockRect.Pitch*y + 4*x, sizeof(DWORD) );

			pD3DTexture->UnlockRect(0);

			pMaterial->colorToon = D3DXCOLOR( color );
		}
	}

	return PMDModelPtr( new PMDModel(pmd,pmd->material_list.material_count,pMaterials) );
}
Esempio n. 5
0
	void setupScene()
	{
		// Must create ClSystem before OpenGL textures. FIXME: this constraint should be more explicit
		m_clSystem.reset(new ClSystem);

		m_window->getViewports().front()->setRenderQueueIdMask(~RenderQueueId_OffscreenTransparentObjects);

		LightPtr light(new Light);
		light->setDirection(glm::normalize(glm::vec3(1.5, -1, -0.5)));
		light->setPosition(glm::vec3(0, 1.0, 0) + light->getDirection() * -10.0f);
		m_visSystem->addLight(light);

		{
			ShadowProjectorConfig config = ShadowProjectorConfig::createDefault();
			config.sceneHeight = config.sceneWidth = 2;
			config.shadowFormat = ShadowFormat_RGB32F;
			m_shadowProjector.reset(new ShadowProjector(config));
			m_shadowProjector->setLight(light);
			m_window->addRenderTarget(m_shadowProjector->getRenderTextureTarget());
		}

		RenderTextureTargetPtr sceneDepthTarget = createDepthTarget(m_camera, m_window->getWidth(), m_window->getHeight());
		sceneDepthTarget->getViewports().front()->setRenderQueueIdMask(~RenderQueueId_OffscreenTransparentObjects);
		TexturePtr sceneDepthTexture = sceneDepthTarget->getTexture();

		// Volume
		{
			int width = 64;
			int height = 128;
			int depth = 128;
			int size = width * height * depth * 4;
			m_imageData.reset(new unsigned char[size]);
			memset(m_imageData.get(), 0, size);

			// Density texture
			m_textureConfig = ImageTextureConfig::createDefault();
			m_textureConfig.width = width;
			m_textureConfig.height = height;
			m_textureConfig.depth = depth;
			m_textureConfig.is3d = true;
			m_textureConfig.format = PixelFormat_RGBA8;
			m_textureConfig.textureAddressMode = TextureAddressMode_Clamp;
			m_textureConfig.data = m_imageData.get();
			m_fluidStateTexture.reset(new Texture(m_textureConfig));

			// Normal texture
			{
				ImageTextureConfig normalTextureConfig = m_textureConfig;
				normalTextureConfig.width /= 2;
				normalTextureConfig.height /= 2;
				normalTextureConfig.depth /= 2;
				normalTextureConfig.data = 0;
				m_normalTexture.reset(new Texture(normalTextureConfig));
			}


			glm::vec3 boxSize(0.5, 1, 1);
			glm::vec3 volumeTextureSize(m_textureConfig.width, m_textureConfig.height, m_textureConfig.depth);

			MaterialPtr material(new Material);

			// Main technique
			{
				ShaderProgramPtr shader = ShaderProgram::createShaderProgram(ShaderProgramConfig("Shaders/Volume/RaymarchedVolume.vert", "Shaders/Volume/VolumetricSmoke.frag"));
				
				
				TechniquePtr technique(new Technique(shader));
				{
					Vec3ShaderParameterPtr boxModelSizeParameter(new Vec3ShaderParameter("volumeSize_modelSpace", boxSize));
					technique->addCustomShaderParameter(boxModelSizeParameter);

					Vec3ShaderParameterPtr oneOnVolumeTextureSizeParameter(new Vec3ShaderParameter("oneOnVolumeTextureSize", 1.0f / volumeTextureSize));
					technique->addCustomShaderParameter(oneOnVolumeTextureSizeParameter);
					technique->addCustomShaderParameter(ShaderParameterPtr(new FloatShaderParameter("opacityMultiplier", 30.0)));

					technique->setAlphaBlendingMode(AlphaBlendingMode_PreMultiplied);
					{
						TextureUnit unit(m_fluidStateTexture, "albedoSampler");
						technique->addTextureUnit(unit);
					}

					{
						TextureUnit unit(sceneDepthTexture, "sceneDepthSampler");
						technique->addTextureUnit(unit);
					}

					{
						TextureUnit unit(m_shadowProjector->getShadowTexture(), "shadowSampler");
						technique->addTextureUnit(unit);
					}

					{
						TextureUnit unit(m_normalTexture, "normalSampler");
						technique->addTextureUnit(unit);
					}
				}

				material->setTechnique(technique);
			}

			// Deep shadow caster technique
			{
				ShaderProgramPtr shader = ShaderProgram::createShaderProgram(ShaderProgramConfig("Shaders/Volume/RaymarchedVolume.vert", "Shaders/Volume/VolumeShadowCaster.frag"));

				TechniquePtr technique(new Technique(shader));
				{
					Vec3ShaderParameterPtr boxModelSizeParameter(new Vec3ShaderParameter("volumeSize_modelSpace", boxSize));
					technique->addCustomShaderParameter(boxModelSizeParameter);

					Vec3ShaderParameterPtr oneOnVolumeTextureSizeParameter(new Vec3ShaderParameter("oneOnVolumeTextureSize", 1.0f / volumeTextureSize));
					technique->addCustomShaderParameter(oneOnVolumeTextureSizeParameter);
					technique->addCustomShaderParameter(ShaderParameterPtr(new FloatShaderParameter("opacityMultiplier", 0.8)));

					{
						TextureUnit unit(m_fluidStateTexture, "albedoSampler");
						technique->addTextureUnit(unit);
					}
				}

				material->setTechnique(technique, TechniqueCategory_DepthRtt);
			}

			{
				BoxConfig config;
				config.size = boxSize;
				MeshPtr mesh = BoxMeshFactory::createMesh(config);
				GeoPtr geo(new Geo(mesh, material));

				RenderableNodePtr renderableNode(new RenderableNode);
				renderableNode->addRenderable(geo);
				renderableNode->setPosition(glm::vec3(0, 0.5, 0));
				m_visSystem->addRenderableNode(renderableNode, RenderQueueId_OffscreenTransparentObjects);
			}
		}

		// Scene geo
		{
			ShadowedMaterialFactory materialFactory(m_shadowProjector->getShadowTexture());
			// Ground plane
			{
				RectangleConfig config = RectangleConfig::defaultWithSize(glm::vec2(5, 5));
				config.orientation = glm::angleAxis(halfPi(), glm::vec3(-1, 0, 0));
				MeshPtr mesh = RectangleMeshFactory::createMesh(config);

				GeoPtr geo(new Geo(mesh, materialFactory.createMaterial(TextureRoles())));
				RenderableNodePtr renderableNode = RenderableNode::createWithSingleGeo(geo);
				m_visSystem->addRenderableNode(renderableNode);
			}
		}

		int volumeTargetWidth = m_window->getWidth() / 2;
		int volumeTargetHeight = m_window->getHeight() / 2;

		TexturePtr offscreenTransparentObjectsTexture;
		// Create offscreen transparent objects target
		{
			ImageTextureConfig config = ImageTextureConfig::createDefault();
			config.width = volumeTargetWidth;
			config.height = volumeTargetHeight;
			config.textureAddressMode = TextureAddressMode_Clamp;
			offscreenTransparentObjectsTexture.reset(new Texture(config));

			{
				RenderTextureTargetConfig config;
				config.texture = offscreenTransparentObjectsTexture;
				config.attachment = FrameBufferAttachment_Color;
				RenderTextureTargetPtr target(new RenderTextureTarget(config));

				{
					ViewportPtr viewport = target->addDefaultViewport(m_camera);
					viewport->setRenderQueueIdMask(RenderQueueId_OffscreenTransparentObjects);
					viewport->setBackgroundColor(glm::vec4(0,0,0,0));
				}

				m_window->addRenderTarget(target);
			}
		}

		// Composite offscreen particles
		{
			TextureUnit textureUnit(offscreenTransparentObjectsTexture, "albedoSampler");

			ShaderProgramPtr shader = ShaderProgram::createShaderProgram(ShaderProgramConfig("Shaders/Common/ScreenQuad.vert", "Shaders/Common/SimpleTextured.frag"));
			TechniquePtr technique(new Technique(shader));
			technique->addTextureUnit(textureUnit);
			technique->setAlphaBlendingMode(AlphaBlendingMode_PreMultiplied);
			MaterialPtr material(new Material);
			material->setTechnique(technique);

			{
				RectangleConfig config = RectangleConfig::defaultWithSize(glm::vec2(2, 2));
				MeshPtr mesh = RectangleMeshFactory::createMesh(config);
				GeoPtr geo(new Geo(mesh, material));

				RenderableNodePtr renderableNode(new RenderableNode);
				renderableNode->addRenderable(geo);
				m_visSystem->addRenderableNode(renderableNode, RenderQueueId_CompositeOffscreenTransparentObjects);
			}
		}

		int tempBufferElementCount = m_textureConfig.width * m_textureConfig.height * m_textureConfig.depth;

		std::string fluidKernelsDir = "Kernels/Fluid";

		TempBufferPoolPtr tempBufferPool(new TempBufferPool(*m_clSystem, tempBufferElementCount));
		m_solver = createFluidSolver(*m_clSystem, getGlTexture(m_fluidStateTexture), tempBufferPool, fluidKernelsDir);
		FluidSolverParamsPtr params = m_solver->getParams();
		params->temperatureBuoyancy = 15;
		params->densityWeight = 2.0;
		params->drag = 0.05;

		m_isosurfaceNormalCalculator = createIsosurfaceNormalCalculator(*m_clSystem, getGlTexture(m_normalTexture), m_solver, tempBufferPool, fluidKernelsDir);

		m_camera->setPosition(glm::vec3(2.2, 0.5, 0.7));
		m_cameraController->rotate(1.2, -0.05);
	}
Esempio n. 6
0
	void setupScene()
	{
		LightPtr light(new Light);
		light->setDirection(glm::normalize(glm::vec3(2, -1, -1)));
		m_visSystem->addLight(light);

		m_camera->getProjection()->setNearClipDistance(0.05);
		m_camera->getProjection()->setFarClipDistance(1000);

		// Create heightmap
		TexturePtr texture;
		{
			ImageTextureConfig config = ImageTextureConfig::createDefault();
			config.format = PixelFormat_R16;
			config.width = config.height = 512;
			
			boost::scoped_array<char16_t> buffer(new char16_t[config.width * config.height]);
			
			for (int y = 0; y < config.height; ++y)
			{
				for (int x = 0; x < config.width; ++x)
				{
					// interesting ripple pattern
					glm::vec2 r = glm::vec2((float)x / (float)config.width, (float)y / (float)config.height) * 2.0f - 1.0f;
					buffer[x + config.width * y] = 32768 + 32767 * std::sin(glm::length(r) * 30.0f);
				}
			}

			config.data = (unsigned char*)buffer.get();

			texture.reset(new Texture(config));
			texture->setTextureAddressMode(TextureAddressMode_Clamp);
		}

		// Create tessellated plane
		{
			ShaderProgramConfig config("c:\\projects\\Graphtane\\Shaders\\TessDisplacement\\TessDisplacement.vert", "c:\\projects\\Graphtane\\Shaders\\Common\\SimpleTextured.frag");
			config.shaderFilepaths[ShaderType_TessellationControl] = "c:\\projects\\Graphtane\\Shaders\\TessDisplacement\\TessDisplacement.tctrl";
			config.shaderFilepaths[ShaderType_TessellationEvaluation] = "c:\\projects\\Graphtane\\Shaders\\TessDisplacement\\TessDisplacement.teval";

			ShaderProgramPtr shader = ShaderProgram::createShaderProgram(config);
			TechniquePtr technique(new Technique(shader));
			technique->addTextureUnit(TextureUnit(texture, "heightSampler"));
			technique->addTextureUnit(TextureUnit(texture, "albedoSampler"));
			technique->addCustomShaderParameter(ShaderParameterPtr(new FloatShaderParameter("heightScale", 0.2f)));

			MaterialPtr material(new Material);
			material->setTechnique(technique);

			{
				RectangleConfig config = RectangleConfig::defaultWithSize(glm::vec2(10, 10));
				config.quads = true;
				config.segmentCountX = 32;
				config.segmentCountY = 32;
				config.orientation = glm::angleAxis(halfPi(), glm::vec3(-1, 0, 0));
				config.flipV = true;
				MeshPtr mesh = RectangleMeshFactory::createMesh(config);
				GeoPtr geo(new Geo(mesh, material));

				RenderableNodePtr node = RenderableNode::createWithSingleGeo(geo);
				node->setWireframeModeEnabled(true);
				m_visSystem->addRenderableNode(node);
			}
		}

		m_camera->setPosition(glm::vec3(0, 4, 6));
		m_cameraController->rotate(0, -0.3);
	}