void CSceneManager::collectMeshNodeShaders(IMeshNode* node) { // collect all the shaders ( for per-frame variables optimization) u32 subsetCount = node->getSubsetCount(); for (u32 i = 0; i < subsetCount; i++) { IMaterial* material = node->getMaterial(i); if (material) { for (u32 j = 0; j < material->getPipelineCount(); j++) { IPipeline* pipeline = material->getPipeline(j); if (pipeline) { for (u32 k = 0; k < EST_SHADER_COUNT; k++) { IShader* shader = pipeline->getShader((E_SHADER_TYPE)k); if (shader != nullptr) mActiveShaders.insert(shader); } } } } } }
static jint nativeSetPipeline(JNIEnv *env, jobject thiz, ID_TYPE id_pipeline, jobject pipeline_obj) { ENTER(); jint result = JNI_ERR; CallbackPipeline *pipeline = reinterpret_cast<CallbackPipeline *>(id_pipeline); if (pipeline) { IPipeline *pipeline = getPipeline(env, pipeline_obj); result = pipeline->setPipeline(pipeline); } RETURN(result, jint); }
void CModelMeshNode::renderInstanced(E_PIPELINE_USAGE usage, u32 instanceCount, IMeshBuffer* instanceBuffer) { if (instanceCount == 0) mMesh->bind(); else mMesh->bind(instanceBuffer); IPipeline* prePipeline = nullptr; /* 记录前一个流水线 */ IMaterial* preMaterial = nullptr; /* 记录前一个子集的材质 */ u32 subsetCount = mMesh->getSubsetCount(); for (u32 i = 0; i < subsetCount; i++) { IMaterial* material = mMaterials[i]; if (!material) continue; IPipeline* pipeline = material->getPipeline(usage); if (!pipeline) continue; //如果当前的流水线和上一条相同,则除了材质外的其他变量不用注入 if (pipeline == prePipeline) { //当且仅当材质也不同于上一个时才注入 if (preMaterial != material) { CShaderVariableInjection::injectMaterial(material, pipeline); pipeline->apply(usage); } } else // 如果两条流水线不同,全部变量都需要更新 { CShaderVariableInjection::inject(this, pipeline, i); pipeline->apply(usage); prePipeline = pipeline; } if (instanceCount == 0) mMesh->drawSubset(i); else mMesh->drawSubsetInstanced(i, instanceCount); preMaterial = material; } }
IInstanceCollectionNode* EditorScene::CreateCollectionNode(IModelMesh* mesh, int maxNum) { IInstanceCollectionNode* collectionNode = mSceneManager->addInstanceCollectionNode(mesh, nullptr, maxNum, 0); IMaterialManager* materialManager = IMaterialManager::getInstance(); IPipelineManager* pipelineManager = IPipelineManager::getInstance(); std::string prefix = "multi_"; for (u32 i = 0; i < mesh->getSubsetCount(); i++) { IMaterial* material = mesh->getMaterial(i); if (!material) continue; std::string multiMaterialName = prefix + material->getName(); IMaterial* multi_material = materialManager->get(multiMaterialName, false); if (!multi_material) { SMaterial material2(*material); material2.setName(multiMaterialName); for (u32 j = 0; j < EPU_COUNT; j++) { IPipeline* pipeline = material2.getPipeline(j); if (pipeline) { std::string pipeline_name2 = prefix + pipeline->getName(); IPipeline* pipeline2 = pipelineManager->get(pipeline_name2); material2.setPipeline(j, pipeline2); } } materialManager->add(material2); multi_material = materialManager->get(multiMaterialName, false); } collectionNode->setMaterial(i, multi_material); } collectionNode->addShadow(1); return collectionNode; }
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() { SDeviceContextSettings settings; settings.MultiSamplingCount = 1; settings.MultiSamplingQuality = 0; IApplication* device = createDevice(EDT_DIRECT3D11, SCREEN_WIDTH, SCREEN_HEIGHT, EWS_NONE, true, settings); IVideoDriver* driver = device->getVideoDriver(); ISceneManager* smgr = device->createSceneManager(); IMeshManager* meshManager = driver->getMeshManager(); IPipelineManager* pipelineManager = driver->getPipelineManager(); IResourceGroupManager* resourceGroupManager = driver->getResourceGroupManager(); resourceGroupManager->init("Resources.cfg"); ISimpleMesh* mesh = createWaterMesh(meshManager, "waterwave", 1000.0f, 1000.0f, 30, 30); IMeshNode* meshNode = smgr->addMeshNode(mesh, nullptr, nullptr); meshNode->setMaterialName("test/wave_material"); meshNode->setNeedCulling(false); IPipeline* pipeline = pipelineManager->get("test/wave_pipeline"); ILightNode* light = smgr->addPointLight(1, nullptr, false, XMFLOAT3(10.0f, 50.0f, -10.0f), 1000.0f); light->setSpecular(XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)); light->setDiffuse(XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f)); light->setAttenuation(1.0f, 0.0f, 0.0f); // gTangentWorldMatrix XMVECTOR normal = XMVectorSet(0, 1.0f, 0, 0); XMVECTOR tangent = XMVectorSet(1.0f, 0, 0, 0); XMVECTOR B = XMVector3Cross(normal, tangent); XMMATRIX TBN = XMMATRIX(tangent, B, normal, XMVectorSet(0, 0, 0, 1.0f)); pipeline->setMatrix("gTangentWorldMatrix", TBN); ICameraNode* camera = smgr->addFpsCameraNode(1, nullptr, XMFLOAT3(0, 40.0f, -4.0f), XMFLOAT3(0, 40.0f, 0.0f)); camera->setFarZ(10000.0f); char caption[200]; ITimer* timer = device->getTimer(); timer->reset(); static float t1 = 0.0f; static float t2 = 0.0f; E_FILL_MODE fillMode = E_FILL_SOLID; /* SCompositorCreateParam param; param.Bloom.BlurPassCount = 3; param.Bloom.BrightnessThreshold = 0.85f; param.Bloom.BlurTexelDistance = 1.0f; param.Bloom.BlurTextureWidth = 400; param.Bloom.BlurTextureHeight = 300; ICompositor* bloom = smgr->createCompositor(ECT_BLOOM, param); smgr->addCompositor(bloom); */ while (device->run()) { const float clearColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; driver->beginScene(true, true, clearColor); float dt = timer->tick() * 0.001f; t1 += dt * 0.032f; t2 += dt * 0.02f; if (t1 > 1.0f) t1 -= 1.0f; if (t2 > 1.0f) t2 -= 1.0f; XMMATRIX texTransform1 = XMMatrixTranslation(t1, 0, 0); XMMATRIX texTransform2 = XMMatrixTranslation(0, t2, 0); pipeline->setMatrix("gTexTransform1", texTransform1); pipeline->setMatrix("gTexTransform2", texTransform2); updateCamera(camera, dt); smgr->update(dt); smgr->drawAll(); driver->endScene(); sprintf(caption, "FPS:%f", getFps(dt)); device->setWindowCaption(caption); } device->drop(); return 0; }
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; }