ISimpleMesh* CMeshManager::createSphereMesh( const std::string& name, f32 radius, u32 sliceCount, u32 stackCount, E_MEMORY_USAGE usage) { if (sliceCount == 0) { GF_PRINT_CONSOLE_INFO("The sliceCount of a sphere mesh can't be 0.\n"); return nullptr; } if (stackCount == 0) { GF_PRINT_CONSOLE_INFO("The stackCount of a sphere mesh can't be 0.\n"); return nullptr; } SGeometryData geoData; mGeometryCreator->createSphereData(radius, sliceCount, stackCount, geoData); u32 vertexFormat = EVF_POSITION | EVF_NORMAL | EVF_TANGENT | EVF_TEXCOORD0; ISimpleMesh* mesh = createSimpleMesh(name, vertexFormat, &geoData.Vertices[0], &geoData.Indices[0], geoData.Vertices.size(), mGeometryCreator->getVertexStride(), geoData.Indices.size(), geoData.Aabb, false, usage); return mesh; }
bool CD3D11Texture3D::copyDataToAnotherTexture(ITexture* dest) { if (!dest) return false; if (dest->getType() != ETT_TEXTURE_3D) { GF_PRINT_CONSOLE_INFO("Texture's data cannot be copied between different types\n"); return false; } CD3D11Texture3D* pAnotherTexture = dynamic_cast<CD3D11Texture3D*>(dest); if (getElementSize() != pAnotherTexture->getElementSize()) { GF_PRINT_CONSOLE_INFO("Buffers with different element size couldn't copy data with each other.\n"); return false; } if (mTextureWidth > pAnotherTexture->getWidth() || mTextureHeight > pAnotherTexture->getHeight() || mTextureDepth > pAnotherTexture->getDepth()) { GF_PRINT_CONSOLE_INFO("Destination Buffer' size is smaller than Source Buffer.\n"); return false; } md3dDeviceContext->CopyResource(pAnotherTexture->md3dTexture, md3dTexture); return true; }
IPipeline* CPipelineManager::create(const std::string& name, IShader** shaders, u32 shaderCount, IInputLayout* inputlayout, E_PRIMITIVE_TYPE primitiveType, IRenderState* renderState) { auto it = mPipelinesCache.find(name); if (it != mPipelinesCache.end()) { GF_PRINT_CONSOLE_INFO("create pipeline (%s) repeatedly!\n", name.c_str()); return it->second; } IPipeline* pipeline = mResourceFactory->createPipeline(name, shaders, shaderCount, inputlayout, primitiveType, renderState); if (!pipeline) { GF_PRINT_CONSOLE_INFO("create pipeline '%s' failed.\n", name.c_str()); return nullptr; } mPipelinesCache.insert(std::make_pair(name, pipeline)); return pipeline; }
ISimpleMesh* CResourceFactory::createSimpleMesh( const std::string& name, u32 sortcode, u32 vertexFormat, void* vertices, void* indices, u32 vertexCount, u32 vertexStride, u32 indiceCount, const math::SAxisAlignedBox& aabb, bool bit32Index, E_MEMORY_USAGE usage) { IMeshBuffer* buffer = createMeshBuffer(usage, vertices, indices, vertexCount, indiceCount, vertexStride, bit32Index); if (!buffer) { GF_PRINT_CONSOLE_INFO("The mesh ('%s') create failed!. Due to the failure of mesh buffer.\n", name.c_str()); return nullptr; } CSimpleMesh* mesh = new CSimpleMesh(name, sortcode, aabb, vertexFormat, buffer); if (!mesh) { GF_PRINT_CONSOLE_INFO("The mesh ('%s') create failed!. Due to the lack of memory.\n", name.c_str()); buffer->drop(); return nullptr; } return mesh; }
bool CResourceLoader::loadMaterial(const std::string& fullpath, const IResourceXmlParser::SMaterialCreateParams& createParams) const { IMaterial* material = mMaterialManager->get(createParams.Name); if (material) { GF_PRINT_CONSOLE_INFO("Material '%s' (in the file '%s') has already been loaded. It can't been loaded again. \ Do you put materials with same names in material files ?\n", createParams.Name.c_str(), fullpath.c_str()); return false; } IPipeline* pipelines[8]; for (u32 i = 0; i < createParams.PipelineNames.size(); i++) { const std::string& pipelineName = createParams.PipelineNames[i]; IPipeline* pipeline = mPipelineManager->get(pipelineName); if (!pipeline) { GF_PRINT_CONSOLE_INFO("The pipeline named '%s' doesn't exist in material '%s' (file location: %s).\n", pipelineName.c_str(), createParams.Name.c_str(), fullpath.c_str()); return false; } pipelines[i] = pipeline; } material = mMaterialManager->create(createParams.Name, createParams.MaterialColors, pipelines, createParams.PipelineNames.size()); if (!material) { GF_PRINT_CONSOLE_INFO("The material named '%s' created failed! ( file location: %s ).\n", createParams.Name.c_str(), fullpath.c_str()); return false; } for (u32 i = 0; i < createParams.TextureParams.size(); i++) { ITexture* texture = mTextureManager->get(createParams.TextureParams[i].Name); if (!texture) { GF_PRINT_CONSOLE_INFO("Texture '%s' doesn't exist in material '%s'. (file location: %s).\n", createParams.TextureParams[i].Name.c_str(), createParams.Name.c_str(), fullpath.c_str()); } else { material->setTexture(createParams.TextureParams[i].Index, texture); } } return true; }
IAnimatedMesh* CMeshManager::createAnimatedModelMesh( const std::string& name, u32 vertexFormat, void* vertices, void* animateVertices, void* indices, bool bit32Index, u32 vertexCount, u32 animateVertexCount, u32 indicesCount, u32 vertexStride, u32 animateVertexStride, const math::SAxisAlignedBox& aabb, E_MEMORY_USAGE usage, const std::vector<SModelBone>& bones, const std::vector<SAnimatedModelSubset>& subsets, const std::vector<SBoneAnimationClip>& animateClips) { auto it = mMeshMap.find(name); if (it != mMeshMap.end()) { if (it->second->getType() == EMT_ANIMATE_MODEL_MESH) { GF_PRINT_CONSOLE_INFO("WARNING: The animated mesh named '%s' has already existed.\n", name.c_str()); return dynamic_cast<IAnimatedMesh*>(it->second); } else { GF_PRINT_CONSOLE_INFO("WARNING: The mesh named '%s' has already existed. \ Futhermore it is not a animated mesh.\n", name.c_str()); return nullptr; } } u32 sortcode = mCodeAllocator.allocate(); IAnimatedMesh* mesh = mResourceFactory->createAnimatedModelMesh(name, sortcode, vertexFormat, vertices, animateVertices, indices, vertexCount, animateVertexCount, indicesCount, vertexStride, animateVertexStride, aabb, bit32Index, usage, subsets, bones, animateClips); if (!mesh) { GF_PRINT_CONSOLE_INFO("ERROR:The mesh named '%s' created failed!\n", name.c_str()); mCodeAllocator.release(sortcode); return nullptr; } mMeshMap.insert(std::make_pair(name, mesh)); return mesh; }
IAnimatedMesh* CResourceFactory::createAnimatedModelMesh( const std::string& name, u32 sortcode, u32 vertexFormat, void* vertices, void* animateVertices, void* indices, u32 vertexCount, u32 animateVertexCount, u32 indicesCount, u32 vertexStride, u32 animateVertexStride, const math::SAxisAlignedBox& aabb, bool bit32Index, E_MEMORY_USAGE usage, const std::vector<SAnimatedModelSubset>& subsets, const std::vector<SModelBone>& bones, const std::vector<SBoneAnimationClip>& animateClips) { IAnimatedMeshBuffer* buffer = createAnimatedMeshBuffer(usage, vertices, animateVertices, indices, vertexCount, animateVertexCount, indicesCount, vertexStride, animateVertexStride, bit32Index); if (!buffer) { GF_PRINT_CONSOLE_INFO("The mesh ('%s') create failed!. Due to the failure of mesh buffer.\n", name.c_str()); return nullptr; } if (subsets.size() < 1) { GF_PRINT_CONSOLE_INFO("FAIL:The mesh ('%s') create failed!. The subsets count must be greater than 1.\n", name.c_str()); return nullptr; } CAnimatedMesh* mesh = new CAnimatedMesh(name, sortcode, aabb, vertexFormat, subsets, bones, animateClips, buffer); //CModelMesh* mesh = new CModelMesh(name, sortcode, subsets, buffer); if (!mesh) { GF_PRINT_CONSOLE_INFO("The mesh ('%s') create failed!. Due to the lack of memory.\n", name.c_str()); buffer->drop(); return nullptr; } return mesh; }
ISimpleMesh* CMeshManager::createPlaneMesh( const std::string& name, f32 width, f32 depth, u32 xsegments, u32 ysegments, f32 uTiles, f32 vTiles, E_MEMORY_USAGE usage) { if (xsegments == 0 || ysegments == 0) { GF_PRINT_CONSOLE_INFO("The segments of a plane mesh can't be 0.\n"); return nullptr; } SGeometryData geoData; mGeometryCreator->createPlaneData(width, depth, xsegments, ysegments, uTiles, vTiles, geoData); u32 vertexFormat = EVF_POSITION | EVF_NORMAL | EVF_TANGENT | EVF_TEXCOORD0; ISimpleMesh* mesh = createSimpleMesh(name, vertexFormat, &geoData.Vertices[0], &geoData.Indices[0], geoData.Vertices.size(), mGeometryCreator->getVertexStride(), geoData.Indices.size(), geoData.Aabb, false, usage); return mesh; }
IFpsCameraNode* CSceneManager::addFpsCameraNode(u32 id, ISceneNode* parent, const XMFLOAT3& position, const XMFLOAT3& lookat, const XMFLOAT3& up, f32 maxUpAngle, f32 maxDownAngle, f32 fov, f32 nearZ, f32 farZ, f32 aspectRatio) { if (parent == nullptr) parent = this; if (id <= 0 || id >= MAX_CAMERA_COUNT) { GF_PRINT_CONSOLE_INFO("The camera id must between 1 and %d.\n", 0, MAX_CAMERA_COUNT - 1); return nullptr; } if (mCameraNodes[id] != nullptr) { GF_PRINT_CONSOLE_INFO("The camera with id %d already existed!\n", id); return nullptr; } /* if the aspectRatio is the default param. */ if (aspectRatio < 0) { f32 width = static_cast<f32>(mDevice->getClientWidth()); f32 height = static_cast<f32>(mDevice->getClientHeight()); aspectRatio = width / height; } IFpsCameraNode* camera = new CFpsCameraNode(parent, this, position, lookat, up, aspectRatio, fov, nearZ, farZ, maxUpAngle, maxDownAngle); mCameraNodes[id] = camera; if (mActiveCameraId == EMPTY_CAMERA_ID) setActiveCamera(id); return camera; }
ILightNode* CSceneManager::getLightNode(u32 id) { if (id < 0 || id >= MAX_LIGHT_COUNT) { GF_PRINT_CONSOLE_INFO("The light id must between 0 and %d.\n", 0, MAX_LIGHT_COUNT - 1); return nullptr; } return mLightNodes[id]; }
ITerrainMesh* CMeshManager::createTerrainMesh( const std::string& name, const std::string& szRawFileName, f32 vertexSpace, f32 heightScale, bool bCreateTessellationMesh, bool bCreateNormal, f32 fTexcoordScale, u32 cellsPerPatch, E_MEMORY_USAGE usage) { auto it = mMeshMap.find(name); if (it != mMeshMap.end()) { if (it->second->getType() == EMT_TERRAIN_MESH) { GF_PRINT_CONSOLE_INFO("WARNING: The terrain mesh named '%s' has already existed.\n", name.c_str()); return dynamic_cast<ITerrainMesh*>(it->second); } else { GF_PRINT_CONSOLE_INFO("WARNING: The mesh named '%s' has already existed. \ Furtheremore it is not a animated mesh.\n", name.c_str()); return nullptr; } } u32 sortcode = mCodeAllocator.allocate(); ITerrainMesh* mesh = mResourceFactory->createTerrainMesh(name, sortcode, szRawFileName, vertexSpace, heightScale, bCreateTessellationMesh, bCreateNormal, fTexcoordScale, cellsPerPatch, usage, mTextureManager); if (!mesh) { GF_PRINT_CONSOLE_INFO("ERROR:The terrain mesh named '%s' created failed!\n", name.c_str()); mCodeAllocator.release(sortcode); return nullptr; } mMeshMap.insert(std::make_pair(name, mesh)); return mesh; }
ITerrainMesh* CResourceFactory::createTerrainMesh( const std::string& name, u32 sortcode, const std::string& szRawFileName, f32 vertexSpace, f32 heightScale, bool bCreateTessellationMesh, bool bCreateNormal, f32 fTexcoordScale, u32 cellsPerPatch, E_MEMORY_USAGE usage, ITextureManager* textureManager) { CTerrainMesh* mesh = new CTerrainMesh(name, sortcode, vertexSpace, heightScale); if (!mesh) { GF_PRINT_CONSOLE_INFO("The terrain mesh ('%s') create failed! Due to memory shortage.\n", name.c_str()); return nullptr; } // szRawFileName is just the file name without full path // so here full path must be obtained through ResourceGroupManager's getResourceFullPath method std::string rawFilePath; if (!IResourceGroupManager::getInstance()->getResourceFullPath(szRawFileName, rawFilePath)) { GF_PRINT_CONSOLE_INFO("The terrain mesh ('%s') create failed! Since raw file named '%s' has not been found.\n", name.c_str(), szRawFileName.c_str()); return nullptr; } if (!mesh->init(szRawFileName, rawFilePath, this, textureManager, bCreateTessellationMesh, bCreateNormal, fTexcoordScale, cellsPerPatch, usage)) { mesh->drop(); return nullptr; } return mesh; }
ILightNode* CSceneManager::addLightNode(u32 id, ISceneNode* parent, const XMFLOAT3& position) { if (parent == nullptr) parent = this; if (id < 0 || id >= MAX_LIGHT_COUNT) { GF_PRINT_CONSOLE_INFO("The light id must between 0 and %d.\n", 0, MAX_LIGHT_COUNT - 1); return nullptr; } if (mLightNodes[id] != nullptr) { GF_PRINT_CONSOLE_INFO("The light with id %d already existed!\n", id); return nullptr; } ILightNode* pLight = new CLightNode(id, parent, this, position); mLightNodes[id] = pLight; return pLight; }
IBillboardCollectionMesh* CMeshManager::createBillboardCollectionMesh( const std::string& name, const math::SAxisAlignedBox& aabb, bool alterable, u32 maxNum, const std::vector<SBillboard>& billboards) { auto it = mMeshMap.find(name); if (it != mMeshMap.end()) { if (it->second->getType() == EMT_BILLBOARD_COLLECTION_MESH) { GF_PRINT_CONSOLE_INFO("WARNING: The billboard mesh named '%s' has already existed.\n", name.c_str()); return dynamic_cast<IBillboardCollectionMesh*>(it->second); } else { GF_PRINT_CONSOLE_INFO("WARNING: The mesh named '%s' has already existed. " "Futhermore it is not a billboard mesh.\n", name.c_str()); return nullptr; } } u32 sortcode = mCodeAllocator.allocate(); IBillboardCollectionMesh* mesh = mResourceFactory->createBillboardCollectionMesh(name, sortcode, aabb, alterable, maxNum, billboards); if (!mesh) { GF_PRINT_CONSOLE_INFO("ERROR:The mesh named '%s' created failed!\n", name.c_str()); mCodeAllocator.release(sortcode); return nullptr; } mMeshMap.insert(std::make_pair(name, mesh)); return mesh; }
bool CResourceLoader::loadTexture(const std::string& name) { std::string fullpath; if (!mResourceGroupManager->getFullPath(name, fullpath)) { GF_PRINT_CONSOLE_INFO("The texture named %s doesn't exist.\n", name); return false; } ITexture* texture = mTextureManager->load(name, fullpath); if (texture == nullptr) return false; return true; }
ISampler* CSamplerManager::create(const std::string& name, const SSamplerDesc& desc) { auto it = mSamplerMap.find(name); if (it != mSamplerMap.end()) { GF_PRINT_CONSOLE_INFO("The sampler named '%s' already exists.\n", name.c_str()); return nullptr; } ISampler* sampler = mResourceFactory->createSampler(name, desc); if (!sampler) return nullptr; mSamplerMap.insert(std::make_pair(name, sampler)); return sampler; }
IInputLayout* CD3D11ResourceFactory::createInputLayout( u32 sortCode, const std::vector<SInputLayoutElement>& elements, IShader* shader, u32 hashcode) { if (shader->getType() != EST_VERTEX_SHADER) { GF_PRINT_CONSOLE_INFO("InputLayout must be created according to a vertex shader.\n"); return nullptr; } CD3D11Shader* pdxShader = dynamic_cast<CD3D11Shader*>(shader); ID3D10Blob* pd3dBlob = pdxShader->getShaderBuffer(); IInputLayout* layout = new CD3D11InputLayout(sortCode, md3dDevice, md3dDeviceContext, pd3dBlob, elements, hashcode); return layout; }
bool CResourceLoader::loadMeshFromFile(const std::string& name) { std::string fullpath; if (!mResourceGroupManager->getFullPath(name, fullpath)) { GF_PRINT_CONSOLE_INFO("The mesh named %s doesn't exist.\n", name.c_str()); return false; } IModelFileParser::SModelMeshCreateParams createParams; if (!mModelFileParser->parseModelFile(fullpath, createParams)) return false; if (mMeshManager->getMesh(name)) { GF_PRINT_CONSOLE_INFO("The mesh named '%s' has already existed. \ Do you have two different mesh files named '%s' ?\n", name.c_str(), name.c_str()); return false; }
bool CResourceLoader::loadMaterialsFromFile(const std::string& name) { std::string fullpath; if (!mResourceGroupManager->getFullPath(name, fullpath)) { GF_PRINT_CONSOLE_INFO("The material file named %s doesn't exist.\n", name.c_str()); return false; } std::vector<IResourceXmlParser::SMaterialCreateParams> createParamsArray; if (!mResourceXmlParser->parseMaterialFile(fullpath, createParamsArray)) return false; for (u32 i = 0; i < createParamsArray.size(); i++) { loadMaterial(fullpath, createParamsArray[i]); } return true; }
IMeshBuffer* CD3D11ResourceFactory::createMeshBuffer( E_MEMORY_USAGE usage, void* vertices, void* indices, u32 vertexCount, u32 indicesCount, u32 vertexStride, bool bit32Index) { CD3D11MeshBuffer* buffer = new CD3D11MeshBuffer(usage, md3dDevice, md3dDeviceContext, md3dDriver); if (!buffer) { GF_PRINT_CONSOLE_INFO("The CD3D11MeshBuffer created failed! Due to lack of memory!\n"); return nullptr; } if (!buffer->init(vertices, indices, vertexCount, indicesCount, vertexStride, bit32Index)) { buffer->drop(); return nullptr; } return buffer; }
bool CD3D11Texture2D::create(u32 width, u32 height, u32 bindFlags, void* rawData, u32 miplevel, E_GI_FORMAT format, u32 pitch, E_MEMORY_USAGE memoryUsage) { HRESULT hr; ID3D11Texture2D* pd3dTexture = NULL; ID3D11ShaderResourceView* pd3dSRV = NULL; ID3D11UnorderedAccessView* pd3dUAV = NULL; CD3D11RenderTarget* pRenderTarget = nullptr; D3D11_TEXTURE2D_DESC texDesc; texDesc.Width = width; texDesc.Height = height; texDesc.MipLevels = miplevel; texDesc.ArraySize = 1; texDesc.Format = getDxgiFormat(format); texDesc.SampleDesc.Count = 1; texDesc.SampleDesc.Quality = 0; texDesc.BindFlags = getD3dx11BindFlags(bindFlags); texDesc.CPUAccessFlags = getD3dx11CpuAccessFlag(bindFlags); texDesc.MiscFlags = 0; texDesc.Usage = getD3d11Usage(memoryUsage); if (memoryUsage == EMU_UNKNOWN) { if ((bindFlags & ETBT_CPU_ACCESS_READ)) { texDesc.Usage = D3D11_USAGE_STAGING; memoryUsage = EMU_STAGING; } else if (bindFlags & ETBT_CPU_ACCESS_WRITE) { texDesc.Usage = D3D11_USAGE_DYNAMIC; memoryUsage = EMU_DEFAULT; } else if (rawData) { texDesc.Usage = D3D11_USAGE_IMMUTABLE; memoryUsage = EMU_STATIC; } else if (!rawData) { texDesc.Usage = D3D11_USAGE_DEFAULT; memoryUsage = EMU_DEFAULT; } } else { if (memoryUsage == EMU_DEFAULT || memoryUsage == EMU_STATIC) { if ((bindFlags & ETBT_CPU_ACCESS_READ) || (bindFlags & ETBT_CPU_ACCESS_WRITE)) { GF_PRINT_CONSOLE_INFO("Static or Default Buffer cannot be accessed by CPU.\n"); return false; } } else if (memoryUsage == EMU_DYNAMIC) { if (bindFlags & ETBT_CPU_ACCESS_READ) { GF_PRINT_CONSOLE_INFO("Dynamic Buffer cannot be read by CPU.\n"); return false; } } } if (memoryUsage == D3D11_USAGE_STAGING) { if ((bindFlags & ETBT_SHADER_RESOURCE) || (bindFlags & ETBT_UNORDERED_ACCESS)){ GF_PRINT_CONSOLE_INFO("Buffer with the memory usage 'STARING' cannot have SHADER_RESOURCE or UNORDERED_ACCESS."); return false; } } if (rawData) { D3D11_SUBRESOURCE_DATA texData; texData.pSysMem = rawData; if (pitch == 0) pitch = getFormatOffset(format) * width; texData.SysMemPitch = pitch; texData.SysMemSlicePitch = 0; hr = md3dDevice->CreateTexture2D(&texDesc, &texData, &pd3dTexture); } else { hr = md3dDevice->CreateTexture2D(&texDesc, NULL, &pd3dTexture); } if (FAILED(hr)) { return false; } if (bindFlags & ETBT_SHADER_RESOURCE) { D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = texDesc.Format; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = -1; hr = md3dDevice->CreateShaderResourceView(pd3dTexture, &srvDesc, &pd3dSRV); if (FAILED(hr)) { ReleaseCOM(pd3dTexture); return false; } } if (bindFlags & ETBT_UNORDERED_ACCESS) { D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc; uavDesc.Format = texDesc.Format; uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; uavDesc.Texture2D.MipSlice = 0; hr = md3dDevice->CreateUnorderedAccessView(pd3dTexture, &uavDesc, &pd3dUAV); if (FAILED(hr)) { ReleaseCOM(pd3dTexture); return false; } } if (bindFlags & ETBT_RENDER_TARGET) { pRenderTarget = new CD3D11RenderTarget(md3dDevice, md3dDeviceContext); if (!pRenderTarget->create(this, pd3dTexture, pd3dSRV, width, height, format)) { ReleaseReferenceCounted(pRenderTarget); ReleaseCOM(pd3dSRV); ReleaseCOM(pd3dTexture); return false; } } ReleaseReferenceCounted(mRenderTarget); ReleaseReferenceCounted(mDepthStencilSurface); ReleaseCOM(md3dSRV); ReleaseCOM(md3dUAV); ReleaseCOM(md3dTexture); md3dTexture = pd3dTexture; md3dSRV = pd3dSRV; md3dUAV = pd3dUAV; mRenderTarget = pRenderTarget; mTextureWidth = width; mTextureHeight = height; mFormat = format; return true; }
bool CD3D11Texture2D::createDepthStencilTexture(u32 width, u32 height, u32 depthBitNum, u32 stencilBitNum, bool multiSampling, u32 multiSamplingCount, u32 multiSamplingQuality, bool bShaderBound /*= true*/, bool bindDepthToShader /*= true*/) { DXGI_FORMAT d3dTexFormat; DXGI_FORMAT d3dDepthStencilFormat; DXGI_FORMAT d3dShaderViewFormat; ID3D11Texture2D* pd3dTexture = nullptr; CD3D11DepthStencilSurface* pd3dDepthStencilSurface = nullptr; ID3D11ShaderResourceView* pd3dSRV = nullptr; HRESULT hr; if (!multiSampling) { multiSamplingCount = 1; multiSamplingQuality = 0; } if (depthBitNum == 32 && stencilBitNum == 0) { d3dTexFormat = DXGI_FORMAT_R32_TYPELESS; d3dDepthStencilFormat = DXGI_FORMAT_D32_FLOAT; d3dShaderViewFormat = DXGI_FORMAT_R32_FLOAT; mFormat = EGF_D32; } else if (depthBitNum == 24 && stencilBitNum == 8) { d3dTexFormat = DXGI_FORMAT_R24G8_TYPELESS; d3dDepthStencilFormat = DXGI_FORMAT_D24_UNORM_S8_UINT; if (bindDepthToShader) d3dShaderViewFormat = DXGI_FORMAT_R24_UNORM_X8_TYPELESS; else d3dShaderViewFormat = DXGI_FORMAT_X24_TYPELESS_G8_UINT; mFormat = EGF_D24S8; } else if (depthBitNum == 16 && stencilBitNum == 0) { d3dTexFormat = DXGI_FORMAT_R16_TYPELESS; d3dDepthStencilFormat = DXGI_FORMAT_D16_UNORM; d3dShaderViewFormat = DXGI_FORMAT_R16_FLOAT; mFormat = EGF_D16; } else { GF_PRINT_CONSOLE_INFO("The format of depth-stencil-surface ('%s') is invalid.\n", mName.c_str()); return false; } // create texture D3D11_TEXTURE2D_DESC texDesc; ZeroMemory(&texDesc, sizeof(texDesc)); texDesc.Width = width; texDesc.Height = height; texDesc.MipLevels = 1; texDesc.ArraySize = 1; texDesc.Format = d3dTexFormat; texDesc.SampleDesc.Count = multiSamplingCount; texDesc.SampleDesc.Quality = multiSamplingQuality; texDesc.Usage = D3D11_USAGE_DEFAULT; texDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; if (bShaderBound) texDesc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; texDesc.CPUAccessFlags = 0; texDesc.MiscFlags = 0; hr = md3dDevice->CreateTexture2D(&texDesc, NULL, &pd3dTexture); if (FAILED(hr)) { GF_PRINT_CONSOLE_INFO("The Depth-stencil-surface('%s') has failed to be created. Because of the failure of texture creation.\n", mName.c_str()); return false; } // create shader-resource-view, if needed. if (bShaderBound) { D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = d3dShaderViewFormat; if (multiSampling) { srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; } else{ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = 1; } hr = md3dDevice->CreateShaderResourceView(pd3dTexture, &srvDesc, &pd3dSRV); if (FAILED(hr)) { GF_PRINT_CONSOLE_INFO("The Depth-stencil-surface('%s') has failed to be created.\ Because of the failure of ShaderResourceView creation.\n", mName.c_str()); ReleaseCOM(pd3dTexture); return false; } } else {
bool CD3D11AnimatedMeshBuffer::init(void* vertices, void* animateVertices, void* indices, u32 vertexCount, u32 animateVertexCount, u32 indicesCount, u32 vertexStride, u32 animateVertexStride, bool bit32Index) { HRESULT hr; mVertexCount = vertexCount; mAnimateVertexCount = animateVertexCount; mIndiceCount = indicesCount; mVertexStride = vertexStride; mAnimateVertexStride = animateVertexStride; /* struct Vertex { XMFLOAT3 Pos; XMFLOAT3 Normal; XMFLOAT2 Tex; XMFLOAT3 Weights; u8 BoneIndices[4]; }; std::ofstream file; file.open("log3.txt", std::ios::out); Vertex* p = (Vertex*)animateVertices; for (u32 i = animateVertexCount - 1; i > 0; i--) { Vertex v = p[i]; file << v.Pos.x << " " << v.Pos.y << " " << v.Pos.z << "\n"; file << (u32)v.BoneIndices[0] << " " << (u32)v.BoneIndices[1] << " " << (u32)v.BoneIndices[2] << " " << (u32)v.BoneIndices[3] << "\n"; file << v.Weights.x << " " << v.Weights.y << " " << v.Weights.z << "\n"; } file.close(); */ if (vertices == nullptr && animateVertices == nullptr) { GF_PRINT_CONSOLE_INFO("Create D3D11 Mesh failed! Because the vertices parameters is empty!\n"); return false; } if (bit32Index) mIndexFormat = DXGI_FORMAT_R32_UINT; else mIndexFormat = DXGI_FORMAT_R16_UINT; // TODO: should modify in the future if (mMemoryUsage != EMU_STATIC && mMemoryUsage != EMU_DEFAULT) { throw std::runtime_error("can not create dynamic now!"); return false; } D3D11_USAGE d3dUsage = getD3d11Usage(mMemoryUsage); D3D11_BUFFER_DESC vbDesc; vbDesc.Usage = d3dUsage; vbDesc.CPUAccessFlags = 0; vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vbDesc.StructureByteStride = 0; vbDesc.MiscFlags = 0; /* create vertex buffer */ if (mVertexCount > 0) { vbDesc.ByteWidth = vertexStride * vertexCount; D3D11_SUBRESOURCE_DATA vbData; vbData.pSysMem = vertices; hr = md3dDevice->CreateBuffer(&vbDesc, &vbData, &md3dVertexBuffer); if (FAILED(hr)) return false; } /* create animate vertex buffer. */ if (mAnimateVertexCount > 0) { vbDesc.ByteWidth = animateVertexStride * animateVertexCount; D3D11_SUBRESOURCE_DATA vbData; vbData.pSysMem = animateVertices; hr = md3dDevice->CreateBuffer(&vbDesc, &vbData, &md3dAnimateVertexBuffer); if (FAILED(hr)) return false; } u32 indiceStride = sizeof(WORD); if (bit32Index) indiceStride = sizeof(DWORD); D3D11_BUFFER_DESC ibDesc; ibDesc.ByteWidth = indiceStride * indicesCount; ibDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; ibDesc.CPUAccessFlags = 0; ibDesc.MiscFlags = 0; ibDesc.StructureByteStride = 0; ibDesc.Usage = D3D11_USAGE_IMMUTABLE; D3D11_SUBRESOURCE_DATA ibData; ibData.pSysMem = indices; hr = md3dDevice->CreateBuffer(&ibDesc, &ibData, &md3dIndexBuffer); if (FAILED(hr)) return false; return true; }
bool CResourceLoader::loadPipeline(const std::string& fullpath, const IResourceXmlParser::SPipelineCreateParams& createParams) const { /* if the pipeline with the same name has already been loaded, maybe some mistake has occurred. such as two pipeline file with the same pipeline name. */ IPipeline* pipeline = mPipelineManager->get(createParams.Name); if (pipeline) { GF_PRINT_CONSOLE_INFO("Pipeline '%s' (in the file '%s') has already been loaded. It can't been loaded again. \ Do you put the pipelines with same names in different files ?\n", createParams.Name, fullpath.c_str()); return false; } u32 shaderCount = createParams.Shaders.size(); IShader* shaders[5]; IShader* vertexShader; for (u32 i = 0; i < shaderCount; i++) { const IResourceXmlParser::SShaderCreateParams shaderCreateParams = createParams.Shaders[i]; std::string shaderName = shaderCreateParams.FileName + std::string("-") + shaderCreateParams.FunctionName; IShader* shader = mShaderManager->get(shaderName); /* if the shader has not been loaded. Load it first. */ if (!shader) { std::string shaderFullPath; if (!mResourceGroupManager->getFullPath(shaderCreateParams.FileName, shaderFullPath)) { GF_PRINT_CONSOLE_INFO("Pipeline '%s' creation failed. Because the shader file '%s' doesn't exist.\n", createParams.Name.c_str(), shaderCreateParams.FileName.c_str()); return false; } shader = mShaderManager->load(shaderCreateParams.Type, shaderFullPath, shaderCreateParams.FunctionName, shaderName); if (shader == nullptr) { GF_PRINT_CONSOLE_INFO("Pipeline '%s' creation failed. Due to the '%s' function in '%s' shader file.\n", createParams.Name.c_str(), shaderCreateParams.FunctionName.c_str(), shaderFullPath.c_str()); return false; } } shaders[i] = shader; /* find the vertex shader, which will be used to create input-layout soon.*/ if (shader->getType() == EST_VERTEX_SHADER) { vertexShader = shader; } } /* create the input-layout. */ /* if the input-layout with the same layout has been created before, just get it.*/ IInputLayout* inputLayout = mInputlayoutManager->get(createParams.InputLayoutElements); // if there is no input-layout with the same vertex formats. just create it. if (!inputLayout) { inputLayout = mInputlayoutManager->create(createParams.InputLayoutElements, vertexShader); if (!inputLayout) { GF_PRINT_CONSOLE_INFO("Pipeline '%s' creation failed. Due to the input-layout create failure in file '%s'.\n", createParams.Name, fullpath.c_str()); return false; } } /* create render state */ std::string rsname = createParams.Name + ".rs"; IRenderState* pRenderState = mRenderStateManager->get(rsname); if (!pRenderState) { pRenderState = mRenderStateManager->create(rsname); if (!pRenderState) { GF_PRINT_CONSOLE_INFO("Pipeline '%s' creation failed. Due to the render-state create failure in file '%s'.\n", createParams.Name, fullpath.c_str()); return false; } } // set all the render states. for (u32 i = 0; i < createParams.RenderStates.size(); i++) { const IResourceXmlParser::SRenderStateCreateParams& rsCreateParam = createParams.RenderStates[i]; switch (rsCreateParam.StateType) { /* if the render-state need a float value */ case ERS_DEPTH_BIAS_CLAMP: pRenderState->setFloat(rsCreateParam.StateType, rsCreateParam.FloatValue); break; /* others are unsigned int. */ default: pRenderState->set(rsCreateParam.StateType, rsCreateParam.DwordValue); break; } } pRenderState->confirm(); // create the pipeline object pipeline = mPipelineManager->create(createParams.Name, shaders, shaderCount, inputLayout, createParams.PrimitiveType, pRenderState); if (!pipeline) { GF_PRINT_CONSOLE_INFO("Pipeline '%s' creation failed (in file '%s').\n", createParams.Name, fullpath.c_str()); // TODO: should drop pRenderState object. return false; } /* set the shader auto-inject variables. */ for (u32 i = 0; i < createParams.ShaderAutoVariables.size(); i++) { pipeline->addShaderAutoVariable(createParams.ShaderAutoVariables[i]); } return true; }
int main() { int d = 1; GF_PRINT_CONSOLE_INFO("Hello:%d\n", d); SDeviceContextSettings settings; settings.MultiSamplingCount = 4; settings.MultiSamplingQuality = 32; IDevice* device = createDevice(EDT_DIRECT3D11, 800, 600, EWS_NONE, true, settings); IVideoDriver* driver = device->getVideoDriver(); IShaderManager* shaderManager = driver->getShaderManager(); IInputLayoutManager* inputlayoutManager = driver->getInputLayoutManager(); IPipelineManager* pipelineMgr = driver->getPipelineManager(); IShader* vs = shaderManager->load(EST_VERTEX_SHADER, "color.hlsl", "ColorVertexShader"); IShader* ps = shaderManager->load(EST_PIXEL_SHADER, "PixelShader.hlsl", "ColorPixelShader"); std::vector<SInputLayoutElement> elements; elements.resize(2); elements[0].SemanticName = "POSITION"; elements[0].SemanticIndex = 0; elements[0].Format = EGF_R32G32B32_FLOAT; elements[0].Offset = 0; elements[1].SemanticName = "COLOR"; elements[1].SemanticIndex = 0; elements[1].Format = EGF_R32G32B32A32_FLOAT; elements[1].Offset = 12; IInputLayout* layout = inputlayoutManager->create(elements, vs); IShader* shaders[2] = { vs, ps }; IPipeline* pipeline = pipelineMgr->create("color", shaders, 2, layout, EPT_TRIANGLELIST); ISceneManager* smgr = device->getSceneManager(); Vertex vertices[3]; vertices[0] = Vertex(XMFLOAT3(-1.0f, -0.6f, 0.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f)); vertices[1] = Vertex(XMFLOAT3(0.0f, 0.6f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f)); vertices[2] = Vertex(XMFLOAT3(1.0f, -0.6f, 0.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f)); //IMesh* mesh = smgr->createSimpleMesh(&vertices, 3, sizeof(Vertex), nullptr, 0, 0); IMesh* mesh = smgr->createCubeMesh(); IMeshNode* meshNode = smgr->addMeshNode(mesh, pipeline); //CD3D11ShaderManager* s = new CD3D11ShaderManager(nullptr); XMVECTOR eye = XMVectorSet(0.0f, 0.0f, -5.0f, 1.0f); XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); XMVECTOR at = XMVectorZero(); XMMATRIX view = XMMatrixLookAtLH(eye, at, up); XMMATRIX proj = XMMatrixPerspectiveFovLH(0.25f * 3.14f, static_cast<float>(SCREEN_WIDTH) / static_cast<float>(SCREEN_HEIGHT), 1.0f, 1000.0f); meshNode->translate(0, 0, 5.0f); XMMATRIX world = meshNode->getAbsoluteTransformation(); //XMMATRIX world = XMMatrixIdentity(); pipeline->setMatrix("viewMatrix", reinterpret_cast<f32*>(&view)); pipeline->setMatrix("projectionMatrix", reinterpret_cast<f32*>(&proj)); SShaderAutoVariable var; var.Type = ESAVT_WORLD_MATRIX; var.ShaderType = EST_VERTEX_SHADER; var.VariableName = "worldMatrix"; pipeline->addShaderAutoVariable(var); std::cout << "Hello World" << std::endl; ITimer* timer = device->createTimer(); timer->reset(); while (device->run()) { const float clearColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; driver->beginScene(true, true, clearColor); f32 dt = timer->tick(); //std::cout << dt << std::endl; meshNode->setPosition(0, 0, -2.0f); meshNode->yaw(1.0f * dt); smgr->drawAll(); //XMMATRIX world = meshNode->getAbsoluteTransformation(); //pipeline->setMatrix("worldMatrix", reinterpret_cast<f32*>(&world)); driver->endScene(); } return 0; }
bool CD3D11Texture2DArray::copyDataToAnotherTexture(ITexture* dest) { GF_PRINT_CONSOLE_INFO("TextureArray cannot copy now.\n"); return false; }
bool CD3D11Driver::init(SCreationParameters& createParam) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator = 0, denominator = 1, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; D3D11_TEXTURE2D_DESC depthBufferDesc; //D3D11_DEPTH_STENCIL_DESC depthStencilDesc; //D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; //D3D11_RASTERIZER_DESC rasterDesc; //D3D11_VIEWPORT viewport; //const SCreationParameters& params = mDevice->getCreationParameters(); // Create a DirectX graphics interface factory. mBackBufferWidth = createParam.BackBufferWidth; mBackBufferHeight = createParam.BackBufferHeight; result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(result)) { return false; } // Use the factory to create an adapter for the primary graphics interface (video card). result = factory->EnumAdapters(0, &adapter); if (FAILED(result)) { return false; } // Enumerate the primary adapter output (monitor). result = adapter->EnumOutputs(0, &adapterOutput); if (FAILED(result)) { return false; } // Get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor). result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if (FAILED(result)) { return false; } // Create a list to hold all the possible display modes for this monitor/video card combination. displayModeList = new DXGI_MODE_DESC[numModes]; if (!displayModeList) { return false; } // Now fill the display mode list structures. result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if (FAILED(result)) { return false; } // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the numerator and denominator of the refresh rate for that monitor. for (i = 0; i < numModes; i++) { if (displayModeList[i].Width == (unsigned int)createParam.BackBufferWidth) { if (displayModeList[i].Height == (unsigned int)createParam.BackBufferHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } // Get the adapter (video card) description. result = adapter->GetDesc(&adapterDesc); if (FAILED(result)) { return false; } // Store the dedicated video card memory in megabytes. mVideoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to a character array and store it. error = wcstombs_s(&stringLength, mVideoCardDescription, 128, adapterDesc.Description, 128); if (error != 0) { return false; } // Release the display mode list. delete[] displayModeList; displayModeList = 0; // Release the adapter output. adapterOutput->Release(); adapterOutput = 0; // Release the adapter. adapter->Release(); adapter = 0; // Release the factory. factory->Release(); factory = 0; UINT createDeviceFlags = 0; #if defined(DEBUG) || defined(_DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevel; /* 如果将这个标志设为DEBUG,则绘制效率大大降低,且帧频极不稳定 */ //createDeviceFlags = 0; HRESULT hr; hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, 0, 0, D3D11_SDK_VERSION, &md3dDevice, &featureLevel, &md3dDeviceContext); if (FAILED(hr)) return false; #if defined(DEBUG) || defined(_DEBUG) md3dDevice->QueryInterface(__uuidof(ID3D11Debug), reinterpret_cast<void**>(&md3dDebug)); #endif if (featureLevel != D3D_FEATURE_LEVEL_11_0) { throw std::runtime_error("DirectX11 is not supported!"); return false; } UINT numQualityLevels; md3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &numQualityLevels); IDXGIDevice* dxgiDevice = 0; md3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); IDXGIAdapter* dxgiAdapter = 0; dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter); IDXGIFactory* dxgiFactory = 0; dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory); DXGI_SWAP_CHAIN_DESC swapChainDesc; // Initialize the swap chain description. ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); // Set the width and height of the back buffer. swapChainDesc.BufferDesc.Width = createParam.BackBufferWidth; swapChainDesc.BufferDesc.Height = createParam.BackBufferHeight; // Set regular 32-bit surface for the back buffer. swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Set the refresh rate of the back buffer. if (createParam.VsyncEnabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } // Set multisampling. if (createParam.MultiSamplingQuality == 0) { swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; createParam.MultiSamplingCount = 1; } else { swapChainDesc.SampleDesc.Count = createParam.MultiSamplingCount; UINT numQualityLevels; md3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &numQualityLevels); swapChainDesc.SampleDesc.Quality = min(numQualityLevels - 1, createParam.MultiSamplingQuality); createParam.MultiSamplingQuality = swapChainDesc.SampleDesc.Quality; } // set member attributes of class // Set to a single back buffer. swapChainDesc.BufferCount = 1; // Set the usage of the back buffer. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // Set the handle for the window to render to. swapChainDesc.OutputWindow = (HWND)createParam.BackBufferWindowHandle; // Set to full screen or windowed mode. if (createParam.WindowStyle & EWS_FULLSCREEN) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } // Set the scan line ordering and scaling to unspecified. swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // Discard the back buffer contents after presenting. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // Don't set the advanced flags. swapChainDesc.Flags = 0; hr = dxgiFactory->CreateSwapChain(md3dDevice, &swapChainDesc, &md3dSwapChain); if (FAILED(hr)) return false; ReleaseCOM(dxgiDevice); ReleaseCOM(dxgiAdapter); ReleaseCOM(dxgiFactory); // Get the pointer to the back buffer. ID3D11Texture2D* backBuffer; result = md3dSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBuffer); if (FAILED(result)) { return false; } md3dDevice->CreateRenderTargetView(backBuffer, 0, &mDefaultRenderTargetView); ReleaseCOM(backBuffer); mDefaultRenderTarget = new CD3D11RenderTarget(md3dDevice, md3dDeviceContext, mDefaultRenderTargetView, createParam.BackBufferWidth, createParam.BackBufferHeight); // Initialize the description of the depth buffer. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); // Setup the viewport for rendering. setViewport(0, 0, static_cast<f32>(mBackBufferWidth), static_cast<f32>(mBackBufferHeight)); //create resource factory mResourceFactory = new CD3D11ResourceFactory( md3dDevice, md3dDeviceContext, this); IResourceFactory::_setInstance(mResourceFactory); //create geometry creator mGeometryCreator = new CGeometryCreator; IGeometryCreator::_setInstance(mGeometryCreator); //create material manager mMaterialManager = new CMaterialManager; IMaterialManager::_setInstance(mMaterialManager); //create sampler manager mSamplerManager = new CSamplerManager(mResourceFactory); ISamplerManager::_setInstance(mSamplerManager); // create shadermanager mShaderManager = new CShaderManager(mResourceFactory); IShaderManager::_setInstance(mShaderManager); // create inputlayout manager mInputLayoutManager = new CInputLayoutManager(mResourceFactory); IInputLayoutManager::_setInstance(mInputLayoutManager); //create texture manager mTextureManager = new CTextureManager(mDevice, mResourceFactory); ITextureManager::_setInstance(mTextureManager); //create render state manager mRenderStateManager = new CRenderStateManager(mResourceFactory); IRenderStateManager::_setInstance(mRenderStateManager); //create mesh manager mMeshManager = new CMeshManager(mResourceFactory, mGeometryCreator, mTextureManager); IMeshManager::_setInstance(mMeshManager); //create pipeline manager mPipeManager = new CPipelineManager(mResourceFactory); IPipelineManager::_setInstance(mPipeManager); //create resource group manager mResourceGroupManager = new CResourceGroupManager(mTextureManager, mShaderManager, mInputLayoutManager, mRenderStateManager, mPipeManager, mMaterialManager, mMeshManager, mSamplerManager); IResourceGroupManager::_setInstance(mResourceGroupManager); //mResourceFactory->setResourceGroupManager(mResourceGroupManager); // create default depth-stencil-buffer bool multiSampling = (createParam.MultiSamplingCount > 1); mDepthStencilSurface = mTextureManager->createDepthStencilSurface("_default_depth_stencil_surface", 0, 0, createParam.DepthBits, createParam.StencilBits, multiSampling, createParam.MultiSamplingCount, createParam.MultiSamplingQuality, true); if (!mDepthStencilSurface) { GF_PRINT_CONSOLE_INFO("Depth Stencil Surface has failed to be created.\n"); return false; } D3D11DriverState.DepthStencilSurface = mDepthStencilSurface; CD3D11DepthStencilSurface* d3dDepthStencilSurface = dynamic_cast<CD3D11DepthStencilSurface*>(mDepthStencilSurface); mDefaultDepthStencilView = d3dDepthStencilSurface->getDepthStencilView(); D3D11DriverState.DepthStencilView = mDefaultDepthStencilView; // create mShadowMapRasterizeState. This state is only for rendering shadow maps. D3D11_RASTERIZER_DESC shadowRasterizeState; shadowRasterizeState.FillMode = D3D11_FILL_SOLID; shadowRasterizeState.CullMode = D3D11_CULL_BACK; // RENDER BACK FACE shadowRasterizeState.FrontCounterClockwise = TRUE; shadowRasterizeState.DepthBiasClamp = 0.0f; //shadowRasterizeState.DepthBias = 100000; //shadowRasterizeState.SlopeScaledDepthBias = 1.0f; shadowRasterizeState.DepthBias = 0; shadowRasterizeState.SlopeScaledDepthBias = 0; shadowRasterizeState.DepthClipEnable = TRUE; shadowRasterizeState.ScissorEnable = FALSE; shadowRasterizeState.MultisampleEnable = FALSE; shadowRasterizeState.AntialiasedLineEnable = FALSE; hr = md3dDevice->CreateRasterizerState(&shadowRasterizeState, &mShadowMapRasterizeState); if (FAILED(hr)) return false; D3D11DriverState.ShadowMapRasterizerState = mShadowMapRasterizeState; return true; }
IBillboardCollectionMesh* CResourceFactory::createBillboardCollectionMesh( const std::string& name, u32 sortcode, const math::SAxisAlignedBox& aabb, bool alterable, u32 maxNum, const std::vector<SBillboard>& billboards) { IMeshBuffer* buffer = nullptr; if (alterable) { if (billboards.size() > maxNum) { GF_PRINT_CONSOLE_INFO("Billboard buffer creation failed." "billboards' number exceeds the maxNum.\n"); return nullptr; } void* vertices = nullptr; if (!billboards.empty()) vertices = (void*)&billboards[0]; buffer = createMeshBuffer(EMU_DYNAMIC, nullptr, nullptr, maxNum, 0, sizeof(SBillboard), true); buffer->setVertexData(vertices, billboards.size()); } else { // create a static buffer. // use the size of billboards as the maxNum. just ignore the 'maxNum' maxNum = billboards.size(); if (maxNum == 0) { GF_PRINT_CONSOLE_INFO("billboards cannot be empty when creating a " "billboard mesh"); return nullptr; } buffer = createMeshBuffer(EMU_STATIC, (void*)&billboards[0], nullptr, billboards.size(), 0, sizeof(SBillboard), true); } if (!buffer) { GF_PRINT_CONSOLE_INFO("The mesh ('%s') create failed!. Due to the failure of mesh buffer.\n", name.c_str()); return nullptr; } CBillboardCollectionMesh* mesh = new CBillboardCollectionMesh(name, sortcode, aabb, maxNum, alterable, billboards, buffer); if (!mesh) { GF_PRINT_CONSOLE_INFO("The mesh ('%s') create failed!. Due to the lack of memory.\n", name.c_str()); buffer->drop(); return nullptr; } return mesh; }
bool CResourceGroupManager::init(const std::string& configFileName) { std::ifstream infile; infile.open(configFileName, std::ios::in); if (infile.fail()) { //throw std::runtime_error("Can't open the resource config file!"); GF_PRINT_CONSOLE_INFO("Can't open the resource config file!"); return false; } std::string groupName = ""; std::string line; E_RESOURCE_STORE_METHOD storeMethod; std::string dirPath; SResourceGroup* currentGroup; while (!infile.eof()) { infile >> line; if (isResourceGroupLexical(line, groupName)) { SResourceGroup group; group.Name = groupName; mResourceGroups.push_back(group); currentGroup = &mResourceGroups.back(); } else { /* if the first group has not found. */ if (groupName == "") continue; if (isResourceDirectoryLexical(line, storeMethod, dirPath)) { SResourceDirectory dir; dir.Path = dirPath; dir.StoreMethod = storeMethod; currentGroup->Directories.push_back(dir); } } std::cout << line << std::endl; } infile.close(); /* build the full paths of resources files. */ for (u32 i = 0; i < mResourceGroups.size(); i++) { for (u32 j = 0; j < mResourceGroups[i].Directories.size(); j++) { setupFilePathsInDirectory(i, j); } } /* sort the resource files in each group according to the type. */ for (u32 i = 0; i < mResourceGroups.size(); i++) { sort(mResourceGroups[i].Files.begin(), mResourceGroups[i].Files.end(), [](const SResourceFile& file1, const SResourceFile& file2){ return file1.Type < file2.Type; }); } return true; }