void RTTITypeBase::addNewField(RTTIField* field) { if(field == nullptr) { BS_EXCEPT(InvalidParametersException, "Field argument can't be null."); } int uniqueId = field->mUniqueId; auto foundElementById = std::find_if(mFields.begin(), mFields.end(), [uniqueId](RTTIField* x) { return x->mUniqueId == uniqueId; }); if(foundElementById != mFields.end()) { BS_EXCEPT(InternalErrorException, "Field with the same ID already exists."); } String& name = field->mName; auto foundElementByName = std::find_if(mFields.begin(), mFields.end(), [&name](RTTIField* x) { return x->mName == name; }); if(foundElementByName != mFields.end()) { BS_EXCEPT(InternalErrorException, "Field with the same name already exists."); } mFields.push_back(field); }
void D3D9TimerQuery::createQuery() { mDevice = D3D9RenderAPI::getActiveD3D9Device(); HRESULT hr = mDevice->CreateQuery(D3DQUERYTYPE_TIMESTAMPDISJOINT, &mDisjointQuery); if (hr != S_OK) { BS_EXCEPT(RenderingAPIException, "Failed to create a timer query."); } hr = mDevice->CreateQuery(D3DQUERYTYPE_TIMESTAMPFREQ, &mFreqQuery); if (hr != S_OK) { BS_EXCEPT(RenderingAPIException, "Failed to create a timer query."); } hr = mDevice->CreateQuery(D3DQUERYTYPE_TIMESTAMP, &mBeginQuery); if (hr != S_OK) { BS_EXCEPT(RenderingAPIException, "Failed to create a timer query."); } hr = mDevice->CreateQuery(D3DQUERYTYPE_TIMESTAMP, &mEndQuery); if (hr != S_OK) { BS_EXCEPT(RenderingAPIException, "Failed to create a timer query."); } }
void D3D11HardwareBuffer::copyData(HardwareBuffer& srcBuffer, UINT32 srcOffset, UINT32 dstOffset, UINT32 length, bool discardWholeBuffer) { // If we're copying same-size buffers in their entirety if (srcOffset == 0 && dstOffset == 0 && length == mSizeInBytes && mSizeInBytes == srcBuffer.getSizeInBytes()) { mDevice.getImmediateContext()->CopyResource(mD3DBuffer, static_cast<D3D11HardwareBuffer&>(srcBuffer).getD3DBuffer()); if (mDevice.hasError()) { String errorDescription = mDevice.getErrorDescription(); BS_EXCEPT(RenderingAPIException, "Cannot copy D3D11 resource\nError Description:" + errorDescription); } } else { // Copy subregion D3D11_BOX srcBox; srcBox.left = (UINT)srcOffset; srcBox.right = (UINT)srcOffset + length; srcBox.top = 0; srcBox.bottom = 1; srcBox.front = 0; srcBox.back = 1; mDevice.getImmediateContext()->CopySubresourceRegion(mD3DBuffer, 0, (UINT)dstOffset, 0, 0, static_cast<D3D11HardwareBuffer&>(srcBuffer).getD3DBuffer(), 0, &srcBox); if (mDevice.hasError()) { String errorDescription = mDevice.getErrorDescription(); BS_EXCEPT(RenderingAPIException, "Cannot copy D3D11 subresource region\nError Description:" + errorDescription); } } }
D3D11TimerQuery::D3D11TimerQuery() :mFinalized(false), mContext(nullptr), mBeginQuery(nullptr), mEndQuery(nullptr), mDisjointQuery(nullptr), mTimeDelta(0.0f), mQueryEndCalled(false) { D3D11RenderAPI* rs = static_cast<D3D11RenderAPI*>(RenderAPICore::instancePtr()); D3D11Device& device = rs->getPrimaryDevice(); D3D11_QUERY_DESC queryDesc; queryDesc.Query = D3D11_QUERY_TIMESTAMP_DISJOINT; queryDesc.MiscFlags = 0; HRESULT hr = device.getD3D11Device()->CreateQuery(&queryDesc, &mDisjointQuery); if(hr != S_OK) { BS_EXCEPT(RenderingAPIException, "Failed to create a timer query."); } queryDesc.Query = D3D11_QUERY_TIMESTAMP; hr = device.getD3D11Device()->CreateQuery(&queryDesc, &mBeginQuery); if(hr != S_OK) { BS_EXCEPT(RenderingAPIException, "Failed to create a timer query."); } hr = device.getD3D11Device()->CreateQuery(&queryDesc, &mEndQuery); if(hr != S_OK) { BS_EXCEPT(RenderingAPIException, "Failed to create a timer query."); } mContext = device.getImmediateContext(); BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_Query); }
void* GLIndexBufferCore::lockImpl(UINT32 offset, UINT32 length, GpuLockOptions options) { GLenum access = 0; if(mIsLocked) { BS_EXCEPT(InternalErrorException, "Invalid attempt to lock an index buffer that has already been locked"); } #if BS_PROFILING_ENABLED if (options == GBL_READ_ONLY || options == GBL_READ_WRITE) { BS_INC_RENDER_STAT_CAT(ResRead, RenderStatObject_IndexBuffer); } if (options == GBL_READ_WRITE || options == GBL_WRITE_ONLY || options == GBL_WRITE_ONLY_DISCARD || options == GBL_WRITE_ONLY_NO_OVERWRITE) { BS_INC_RENDER_STAT_CAT(ResWrite, RenderStatObject_IndexBuffer); } #endif glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mBufferId); if ((options == GBL_WRITE_ONLY) || (options == GBL_WRITE_ONLY_NO_OVERWRITE) || (options == GBL_WRITE_ONLY_DISCARD)) { access = GL_MAP_WRITE_BIT; if(options == GBL_WRITE_ONLY_DISCARD) access |= GL_MAP_INVALIDATE_BUFFER_BIT; else if(options == GBL_WRITE_ONLY_NO_OVERWRITE) access |= GL_MAP_UNSYNCHRONIZED_BIT; } else if (options == GBL_READ_ONLY) access = GL_MAP_READ_BIT; else access = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT; void* pBuffer = nullptr; if (length > 0) { pBuffer = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length, access); if (pBuffer == nullptr) { BS_EXCEPT(InternalErrorException, "Index Buffer: Out of memory"); } mZeroLocked = false; } else mZeroLocked = true; void* retPtr = static_cast<void*>(static_cast<unsigned char*>(pBuffer)); mIsLocked = true; return retPtr; }
void RenderTextureCore::initialize() { RenderTargetCore::initialize(); const RENDER_SURFACE_CORE_DESC& colorSurface = mDesc.colorSurface; if (colorSurface.texture != nullptr) { SPtr<TextureCore> texture = colorSurface.texture; if (texture->getProperties().getUsage() != TU_RENDERTARGET) BS_EXCEPT(InvalidParametersException, "Provided texture is not created with render target usage."); mColorSurface = TextureCore::requestView(texture, colorSurface.mipLevel, 1, colorSurface.face, colorSurface.numFaces, GVU_RENDERTARGET); } const RENDER_SURFACE_CORE_DESC& depthStencilSurface = mDesc.depthStencilSurface; if (depthStencilSurface.texture != nullptr) { SPtr<TextureCore> texture = depthStencilSurface.texture; if (texture->getProperties().getUsage() != TU_DEPTHSTENCIL) BS_EXCEPT(InvalidParametersException, "Provided texture is not created with depth stencil usage."); mDepthStencilSurface = TextureCore::requestView(texture, depthStencilSurface.mipLevel, 1, depthStencilSurface.face, 0, GVU_DEPTHSTENCIL); } throwIfBuffersDontMatch(); if (mColorSurface != nullptr) { assert(mColorSurface->getTexture() != nullptr); SPtr<TextureCore> colorTexture = mColorSurface->getTexture(); const TextureProperties& texProps = colorTexture->getProperties(); UINT32 numSlices; if (texProps.getTextureType() == TEX_TYPE_3D) numSlices = texProps.getDepth(); else numSlices = texProps.getNumFaces(); if ((mColorSurface->getFirstArraySlice() + mColorSurface->getNumArraySlices()) > numSlices) { BS_EXCEPT(InvalidParametersException, "Provided number of faces is out of range. Face: " + toString(mColorSurface->getFirstArraySlice() + mColorSurface->getNumArraySlices()) + ". Max num faces: " + toString(numSlices)); } if (mColorSurface->getMostDetailedMip() > texProps.getNumMipmaps()) { BS_EXCEPT(InvalidParametersException, "Provided number of mip maps is out of range. Mip level: " + toString(mColorSurface->getMostDetailedMip()) + ". Max num mipmaps: " + toString(texProps.getNumMipmaps())); } } }
void D3D11RenderAPI::bindGpuProgram(const SPtr<GpuProgramCore>& prg) { THROW_IF_NOT_CORE_THREAD; switch(prg->getProperties().getType()) { case GPT_VERTEX_PROGRAM: { D3D11GpuVertexProgramCore* d3d11GpuProgram = static_cast<D3D11GpuVertexProgramCore*>(prg.get()); mDevice->getImmediateContext()->VSSetShader(d3d11GpuProgram->getVertexShader(), nullptr, 0); mActiveVertexShader = std::static_pointer_cast<D3D11GpuProgramCore>(prg); break; } case GPT_FRAGMENT_PROGRAM: { D3D11GpuFragmentProgramCore* d3d11GpuProgram = static_cast<D3D11GpuFragmentProgramCore*>(prg.get()); mDevice->getImmediateContext()->PSSetShader(d3d11GpuProgram->getPixelShader(), nullptr, 0); break; } case GPT_GEOMETRY_PROGRAM: { D3D11GpuGeometryProgramCore* d3d11GpuProgram = static_cast<D3D11GpuGeometryProgramCore*>(prg.get()); mDevice->getImmediateContext()->GSSetShader(d3d11GpuProgram->getGeometryShader(), nullptr, 0); break; } case GPT_DOMAIN_PROGRAM: { D3D11GpuDomainProgramCore* d3d11GpuProgram = static_cast<D3D11GpuDomainProgramCore*>(prg.get()); mDevice->getImmediateContext()->DSSetShader(d3d11GpuProgram->getDomainShader(), nullptr, 0); break; } case GPT_HULL_PROGRAM: { D3D11GpuHullProgramCore* d3d11GpuProgram = static_cast<D3D11GpuHullProgramCore*>(prg.get()); mDevice->getImmediateContext()->HSSetShader(d3d11GpuProgram->getHullShader(), nullptr, 0); break; } case GPT_COMPUTE_PROGRAM: { D3D11GpuComputeProgramCore* d3d11GpuProgram = static_cast<D3D11GpuComputeProgramCore*>(prg.get()); mDevice->getImmediateContext()->CSSetShader(d3d11GpuProgram->getComputeShader(), nullptr, 0); break; } default: BS_EXCEPT(InvalidParametersException, "Unsupported gpu program type: " + toString(prg->getProperties().getType())); } if (mDevice->hasError()) BS_EXCEPT(RenderingAPIException, "Failed to bindGpuProgram : " + mDevice->getErrorDescription()); BS_INC_RENDER_STAT(NumGpuProgramBinds); }
void GLTextureBuffer::blitFromTexture(GLTextureBuffer* src, const PixelVolume& srcBox, const PixelVolume& dstBox) { if (src->mMultisampleCount > 0 && mMultisampleCount == 0) // Resolving MS texture { if (mTarget != GL_TEXTURE_2D || mTarget != GL_TEXTURE_2D_MULTISAMPLE) BS_EXCEPT(InvalidParametersException, "Non-2D multisampled texture not supported."); GLint currentFBO = 0; glGetIntegerv(GL_FRAMEBUFFER_BINDING, ¤tFBO); GLuint readFBO = GLRTTManager::instance().getBlitReadFBO(); GLuint drawFBO = GLRTTManager::instance().getBlitDrawFBO(); // Attach source texture glBindFramebuffer(GL_FRAMEBUFFER, readFBO); src->bindToFramebuffer(0, 0, true); // Attach destination texture glBindFramebuffer(GL_FRAMEBUFFER, drawFBO); bindToFramebuffer(0, 0, true); // Perform blit glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO); glReadBuffer(GL_COLOR_ATTACHMENT0); glDrawBuffer(GL_COLOR_ATTACHMENT0); glBlitFramebuffer(srcBox.left, srcBox.top, srcBox.right, srcBox.bottom, dstBox.left, dstBox.top, dstBox.right, dstBox.bottom, GL_COLOR_BUFFER_BIT, GL_NEAREST); // Restore the previously bound FBO glBindFramebuffer(GL_FRAMEBUFFER, currentFBO); } else // Just plain copy { if (mMultisampleCount != src->mMultisampleCount) BS_EXCEPT(InvalidParametersException, "When copying textures their multisample counts must match."); if (mTarget == GL_TEXTURE_3D) // 3D textures can't have arrays so their Z coordinate is handled differently { glCopyImageSubData(src->mTextureID, src->mTarget, src->mLevel, srcBox.left, srcBox.top, srcBox.front, mTextureID, mTarget, mLevel, dstBox.left, dstBox.top, dstBox.front, srcBox.getWidth(), srcBox.getHeight(), srcBox.getDepth()); } else { glCopyImageSubData(src->mTextureID, src->mTarget, src->mLevel, srcBox.left, srcBox.top, src->mFace, mTextureID, mTarget, mLevel, dstBox.left, dstBox.top, mFace, srcBox.getWidth(), srcBox.getHeight(), 1); } } }
void RTTIField::checkIsArray(bool array) { if(array && !mIsVectorType) { BS_EXCEPT(InternalErrorException, "Invalid field type. Needed an array type but got a single type."); } if(!array && mIsVectorType) { BS_EXCEPT(InternalErrorException, "Invalid field type. Needed a single type but got an array type."); } }
void D3D11RenderAPI::setVertexBuffers(UINT32 index, SPtr<VertexBufferCore>* buffers, UINT32 numBuffers) { THROW_IF_NOT_CORE_THREAD; UINT32 maxBoundVertexBuffers = mCurrentCapabilities->getMaxBoundVertexBuffers(); if(index < 0 || (index + numBuffers) >= maxBoundVertexBuffers) BS_EXCEPT(InvalidParametersException, "Invalid vertex index: " + toString(index) + ". Valid range is 0 .. " + toString(maxBoundVertexBuffers - 1)); ID3D11Buffer* dx11buffers[MAX_BOUND_VERTEX_BUFFERS]; UINT32 strides[MAX_BOUND_VERTEX_BUFFERS]; UINT32 offsets[MAX_BOUND_VERTEX_BUFFERS]; for(UINT32 i = 0; i < numBuffers; i++) { SPtr<D3D11VertexBufferCore> vertexBuffer = std::static_pointer_cast<D3D11VertexBufferCore>(buffers[i]); const VertexBufferProperties& vbProps = vertexBuffer->getProperties(); dx11buffers[i] = vertexBuffer->getD3DVertexBuffer(); strides[i] = vbProps.getVertexSize(); offsets[i] = 0; } mDevice->getImmediateContext()->IASetVertexBuffers(index, numBuffers, dx11buffers, strides, offsets); BS_INC_RENDER_STAT(NumVertexBufferBinds); }
T TGpuDataParam<T, Core>::get(UINT32 arrayIdx) const { if (mParent == nullptr) return T(); GpuParamBufferType paramBlock = mParent->getParamBlockBuffer(mParamDesc->paramBlockSet, mParamDesc->paramBlockSlot); if (paramBlock == nullptr) return T(); #if BS_DEBUG_MODE if (arrayIdx >= mParamDesc->arraySize) { BS_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " + toString(mParamDesc->arraySize) + ". Requested size: " + toString(arrayIdx)); } #endif UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32); UINT32 sizeBytes = std::min(elementSizeBytes, (UINT32)sizeof(T)); T value; paramBlock->read((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &value, sizeBytes); return value; }
void TGpuParamStruct<Core>::get(void* value, UINT32 sizeBytes, UINT32 arrayIdx) const { if (mParent == nullptr) return; GpuParamBufferType paramBlock = mParent->getParamBlockBuffer(mParamDesc->paramBlockSet, mParamDesc->paramBlockSlot); if (paramBlock == nullptr) return; UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32); #if BS_DEBUG_MODE if (sizeBytes > elementSizeBytes) { LOGWRN("Provided element size larger than maximum element size. Maximum size: " + toString(elementSizeBytes) + ". Supplied size: " + toString(sizeBytes)); } if (arrayIdx >= mParamDesc->arraySize) { BS_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " + toString(mParamDesc->arraySize) + ". Requested size: " + toString(arrayIdx)); } #endif sizeBytes = std::min(elementSizeBytes, sizeBytes); paramBlock->read((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), value, sizeBytes); }
ScriptObjectBase::~ScriptObjectBase() { if(mManagedInstance != nullptr) BS_EXCEPT(InvalidStateException, "Script object is being destroyed without its instance previously being released."); ScriptObjectManager::instance().unregisterScriptObject(this); }
void RenderTextureCore::throwIfBuffersDontMatch() const { if (mColorSurface == nullptr || mDepthStencilSurface == nullptr) return; const TextureProperties& colorProps = mColorSurface->getTexture()->getProperties(); const TextureProperties& depthProps = mDepthStencilSurface->getTexture()->getProperties(); UINT32 colorMsCount = colorProps.getMultisampleCount(); UINT32 depthMsCount = depthProps.getMultisampleCount(); if (colorMsCount == 0) colorMsCount = 1; if (depthMsCount == 0) depthMsCount = 1; if (colorProps.getWidth() != depthProps.getWidth() || colorProps.getHeight() != depthProps.getHeight() || colorMsCount != depthMsCount) { String errorInfo = "\nWidth: " + toString(colorProps.getWidth()) + "/" + toString(depthProps.getWidth()); errorInfo += "\nHeight: " + toString(colorProps.getHeight()) + "/" + toString(depthProps.getHeight()); errorInfo += "\nMultisample Count: " + toString(colorMsCount) + "/" + toString(depthMsCount); BS_EXCEPT(InvalidParametersException, "Provided texture and depth stencil buffer don't match!" + errorInfo); } }
void D3D11BlendState::createInternal() { D3D11_BLEND_DESC blendStateDesc; ZeroMemory(&blendStateDesc, sizeof(D3D11_BLEND_DESC)); blendStateDesc.AlphaToCoverageEnable = mProperties.getAlphaToCoverageEnabled(); blendStateDesc.IndependentBlendEnable = mProperties.getIndependantBlendEnable(); for(UINT32 i = 0; i < BS_MAX_MULTIPLE_RENDER_TARGETS; i++) { blendStateDesc.RenderTarget[i].BlendEnable = mProperties.getBlendEnabled(i); blendStateDesc.RenderTarget[i].BlendOp = D3D11Mappings::get(mProperties.getBlendOperation(i)); blendStateDesc.RenderTarget[i].BlendOpAlpha = D3D11Mappings::get(mProperties.getAlphaBlendOperation(i)); blendStateDesc.RenderTarget[i].DestBlend = D3D11Mappings::get(mProperties.getDstBlend(i)); blendStateDesc.RenderTarget[i].DestBlendAlpha = D3D11Mappings::get(mProperties.getAlphaDstBlend(i)); blendStateDesc.RenderTarget[i].RenderTargetWriteMask = 0xf & (mProperties.getRenderTargetWriteMask(i)); // Mask out all but last 4 bits blendStateDesc.RenderTarget[i].SrcBlend = D3D11Mappings::get(mProperties.getSrcBlend(i)); blendStateDesc.RenderTarget[i].SrcBlendAlpha = D3D11Mappings::get(mProperties.getAlphaSrcBlend(i)); } D3D11RenderAPI* rs = static_cast<D3D11RenderAPI*>(RenderAPI::instancePtr()); D3D11Device& device = rs->getPrimaryDevice(); HRESULT hr = device.getD3D11Device()->CreateBlendState(&blendStateDesc, &mBlendState); if(FAILED(hr) || device.hasError()) { String errorDescription = device.getErrorDescription(); BS_EXCEPT(RenderingAPIException, "Cannot create blend state.\nError Description:" + errorDescription); } BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_BlendState); BlendState::createInternal(); }
void* D3D11TextureCore::map(ID3D11Resource* res, D3D11_MAP flags, UINT32 mipLevel, UINT32 face, UINT32& rowPitch, UINT32& slicePitch) { D3D11_MAPPED_SUBRESOURCE pMappedResource; pMappedResource.pData = nullptr; mipLevel = Math::clamp(mipLevel, (UINT32)mipLevel, mProperties.getNumMipmaps()); face = Math::clamp(face, (UINT32)0, mProperties.getNumFaces() - 1); if (mProperties.getTextureType() == TEX_TYPE_3D) face = 0; D3D11RenderAPI* rs = static_cast<D3D11RenderAPI*>(RenderAPICore::instancePtr()); D3D11Device& device = rs->getPrimaryDevice(); mLockedSubresourceIdx = D3D11CalcSubresource(mipLevel, face, mProperties.getNumMipmaps() + 1); device.getImmediateContext()->Map(res, mLockedSubresourceIdx, flags, 0, &pMappedResource); if (device.hasError()) { String errorDescription = device.getErrorDescription(); BS_EXCEPT(RenderingAPIException, "D3D11 device cannot map texture\nError Description:" + errorDescription); } UINT32 bytesPerPixel = PixelUtil::getNumElemBytes(mProperties.getFormat()); rowPitch = pMappedResource.RowPitch / bytesPerPixel; slicePitch = pMappedResource.DepthPitch / bytesPerPixel; return pMappedResource.pData; }
void D3D11TextureCore::copyImpl(UINT32 srcFace, UINT32 srcMipLevel, UINT32 destFace, UINT32 destMipLevel, const SPtr<TextureCore>& target) { D3D11TextureCore* other = static_cast<D3D11TextureCore*>(target.get()); UINT32 srcResIdx = D3D11CalcSubresource(srcMipLevel, srcFace, mProperties.getNumMipmaps() + 1); UINT32 destResIdx = D3D11CalcSubresource(destMipLevel, destFace, target->getProperties().getNumMipmaps() + 1); D3D11RenderAPI* rs = static_cast<D3D11RenderAPI*>(RenderAPICore::instancePtr()); D3D11Device& device = rs->getPrimaryDevice(); bool srcHasMultisample = mProperties.getMultisampleCount() > 1; bool destHasMultisample = target->getProperties().getMultisampleCount() > 1; if (srcHasMultisample && destHasMultisample && mProperties.getMultisampleCount() != target->getProperties().getMultisampleCount()) // Resolving from MS to non-MS texture { device.getImmediateContext()->ResolveSubresource(other->getDX11Resource(), destResIdx, mTex, srcResIdx, mDXGIFormat); } else { device.getImmediateContext()->CopySubresourceRegion(other->getDX11Resource(), destResIdx, 0, 0, 0, mTex, srcResIdx, nullptr); if (device.hasError()) { String errorDescription = device.getErrorDescription(); BS_EXCEPT(RenderingAPIException, "D3D11 device cannot copy subresource\nError Description:" + errorDescription); } } }
void D3D11RenderAPI::setRenderTarget(const SPtr<RenderTargetCore>& target, bool readOnlyDepthStencil) { THROW_IF_NOT_CORE_THREAD; mActiveRenderTarget = target; UINT32 maxRenderTargets = mCurrentCapabilities->getNumMultiRenderTargets(); ID3D11RenderTargetView** views = bs_newN<ID3D11RenderTargetView*>(maxRenderTargets); memset(views, 0, sizeof(ID3D11RenderTargetView*) * maxRenderTargets); ID3D11DepthStencilView* depthStencilView = nullptr; if (target != nullptr) { target->getCustomAttribute("RTV", views); if(readOnlyDepthStencil) target->getCustomAttribute("RODSV", &depthStencilView); else target->getCustomAttribute("DSV", &depthStencilView); } // Bind render targets mDevice->getImmediateContext()->OMSetRenderTargets(maxRenderTargets, views, depthStencilView); if (mDevice->hasError()) BS_EXCEPT(RenderingAPIException, "Failed to setRenderTarget : " + mDevice->getErrorDescription()); bs_deleteN(views, maxRenderTargets); applyViewport(); BS_INC_RENDER_STAT(NumRenderTargetChanges); }
void D3D11RenderAPI::unbindGpuProgram(GpuProgramType gptype) { THROW_IF_NOT_CORE_THREAD; switch(gptype) { case GPT_VERTEX_PROGRAM: mDevice->getImmediateContext()->VSSetShader(nullptr, nullptr, 0); mActiveVertexShader = nullptr; break; case GPT_FRAGMENT_PROGRAM: mDevice->getImmediateContext()->PSSetShader(nullptr, nullptr, 0); break; case GPT_GEOMETRY_PROGRAM: mDevice->getImmediateContext()->GSSetShader(nullptr, nullptr, 0); break; case GPT_DOMAIN_PROGRAM: mDevice->getImmediateContext()->DSSetShader(nullptr, nullptr, 0); break; case GPT_HULL_PROGRAM: mDevice->getImmediateContext()->HSSetShader(nullptr, nullptr, 0); break; case GPT_COMPUTE_PROGRAM: mDevice->getImmediateContext()->CSSetShader(nullptr, nullptr, 0); break; default: BS_EXCEPT(InvalidParametersException, "Unsupported gpu program type: " + toString(gptype)); } BS_INC_RENDER_STAT(NumGpuProgramBinds); }
void throwIfCoreThread() { #if !BS_FORCE_SINGLETHREADED_RENDERING if(BS_THREAD_CURRENT_ID == CoreThread::instance().getCoreThreadId()) BS_EXCEPT(InternalErrorException, "This method cannot be accessed from the core thread."); #endif }
MonoClass* MonoAssembly::getClass(const String& ns, const String& typeName, ::MonoClass* rawMonoClass) const { if (!mIsLoaded) BS_EXCEPT(InvalidStateException, "Trying to use an unloaded assembly."); if (rawMonoClass == nullptr) return nullptr; auto iterFind = mClassesByRaw.find(rawMonoClass); if (iterFind != mClassesByRaw.end()) return iterFind->second; MonoClass* newClass = new (bs_alloc<MonoClass>()) MonoClass(ns, typeName, rawMonoClass, this); mClassesByRaw[rawMonoClass] = newClass; if (!isGenericClass(typeName)) // No point in referencing generic types by name as all instances share it { MonoAssembly::ClassId classId(ns, typeName); mClasses[classId] = newClass; } return newClass; }
SPtr<typename TTechnique<Core>::PassType> TTechnique<Core>::getPass(UINT32 idx) const { if (idx < 0 || idx >= (UINT32)mPasses.size()) BS_EXCEPT(InvalidParametersException, "Index out of range: " + toString(idx)); return mPasses[idx]; }
VertexElementSemantic D3D9Mappings::get(D3DDECLUSAGE sem) { switch (sem) { case D3DDECLUSAGE_BLENDINDICES: return VES_BLEND_INDICES; case D3DDECLUSAGE_BLENDWEIGHT: return VES_BLEND_WEIGHTS; case D3DDECLUSAGE_COLOR: return VES_COLOR; case D3DDECLUSAGE_NORMAL: return VES_NORMAL; case D3DDECLUSAGE_POSITION: return VES_POSITION; case D3DDECLUSAGE_TEXCOORD: return VES_TEXCOORD; case D3DDECLUSAGE_BINORMAL: return VES_BITANGENT; case D3DDECLUSAGE_TANGENT: return VES_TANGENT; default: BS_EXCEPT(RenderingAPIException, "Invalid semantic for D3D9 render system: " + toString(sem)); } return VES_POSITION; }
void MenuItemManager::reloadAssemblyData() { clearMenuItems(); // Reload MenuItem attribute from editor assembly MonoAssembly* editorAssembly = MonoManager::instance().getAssembly(EDITOR_ASSEMBLY); mMenuItemAttribute = editorAssembly->getClass(EDITOR_NS, "MenuItem"); if (mMenuItemAttribute == nullptr) BS_EXCEPT(InvalidStateException, "Cannot find MenuItem managed class."); mPathField = mMenuItemAttribute->getField("path"); mShortcutField = mMenuItemAttribute->getField("shortcut"); mPriorityField = mMenuItemAttribute->getField("priority"); mSeparatorField = mMenuItemAttribute->getField("separator"); MainEditorWindow* mainWindow = EditorWindowManager::instance().getMainWindow(); Vector<String> scriptAssemblyNames = mScriptObjectManager.getScriptAssemblies(); for (auto& assemblyName : scriptAssemblyNames) { MonoAssembly* assembly = MonoManager::instance().getAssembly(assemblyName); // Find new menu item methods const Vector<MonoClass*>& allClasses = assembly->getAllClasses(); for (auto curClass : allClasses) { const Vector<MonoMethod*>& methods = curClass->getAllMethods(); for (auto& curMethod : methods) { String path; ShortcutKey shortcutKey = ShortcutKey::NONE; INT32 priority = 0; bool separator = false; if (parseMenuItemMethod(curMethod, path, shortcutKey, priority, separator)) { std::function<void()> callback = std::bind(&MenuItemManager::menuItemCallback, curMethod); if (separator) { Vector<String> pathElements = StringUtil::split(path, "/"); String separatorPath; if (pathElements.size() > 1) { const String& lastElem = pathElements[pathElements.size() - 1]; separatorPath = path; separatorPath.erase(path.size() - lastElem.size() - 1, lastElem.size() + 1); } GUIMenuItem* separatorItem = mainWindow->getMenuBar().addMenuItemSeparator(separatorPath, priority); mMenuItems.push_back(separatorItem); } GUIMenuItem* menuItem = mainWindow->getMenuBar().addMenuItem(path, callback, priority, shortcutKey); mMenuItems.push_back(menuItem); } } } } }
ID3D11ShaderResourceView* GpuBufferView::createSRV(D3D11GpuBuffer* buffer, UINT32 firstElement, UINT32 elementWidth, UINT32 numElements) { const GpuBufferProperties& props = buffer->getProperties(); if (props.getType() == GBT_APPENDCONSUME) BS_EXCEPT(InvalidParametersException, "Cannot create ShaderResourceView for an append/consume buffer."); D3D11_SHADER_RESOURCE_VIEW_DESC desc; ZeroMemory(&desc, sizeof(desc)); if (props.getType() == GBT_STRUCTURED || props.getType() == GBT_STANDARD) { desc.Format = DXGI_FORMAT_UNKNOWN; desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; desc.Buffer.FirstElement = firstElement; desc.Buffer.NumElements = numElements; } else if (props.getType() == GBT_RAW) { desc.Format = DXGI_FORMAT_R32_TYPELESS; desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX; desc.BufferEx.Flags = D3D11_BUFFEREX_SRV_FLAG_RAW; desc.BufferEx.FirstElement = firstElement; desc.BufferEx.NumElements = numElements; } else if (props.getType() == GBT_INDIRECTARGUMENT) { desc.Format = DXGI_FORMAT_R32_UINT; desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; desc.Buffer.ElementOffset = firstElement * elementWidth; desc.Buffer.ElementWidth = elementWidth; } ID3D11ShaderResourceView* srv = nullptr; D3D11RenderAPI* d3d11rs = static_cast<D3D11RenderAPI*>(D3D11RenderAPI::instancePtr()); HRESULT hr = d3d11rs->getPrimaryDevice().getD3D11Device()->CreateShaderResourceView(buffer->getDX11Buffer(), &desc, &srv); if (FAILED(hr) || d3d11rs->getPrimaryDevice().hasError()) { String msg = d3d11rs->getPrimaryDevice().getErrorDescription(); BS_EXCEPT(RenderingAPIException, "Cannot create ShaderResourceView: " + msg); } return srv; }
CoreObject::~CoreObject() { if(!isDestroyed()) { // Object must be released with destroy() otherwise engine can still try to use it, even if it was destructed // (e.g. if an object has one of its methods queued in a command queue, and is destructed, you will be accessing invalid memory) BS_EXCEPT(InternalErrorException, "Destructor called but object is not destroyed. This will result in nasty issues."); } #if BS_DEBUG_MODE if(!mThis.expired()) { BS_EXCEPT(InternalErrorException, "Shared pointer to this object still has active references but " \ "the object is being deleted? You shouldn't delete CoreObjects manually."); } #endif }
MonoObject* ScriptDropDownWindow::internal_CreateInstance(MonoString* ns, MonoString* typeName, ScriptEditorWindow* parentWindow, Vector2I* position) { String strTypeName = MonoUtil::monoToString(typeName); String strNamespace = MonoUtil::monoToString(ns); String fullName = strNamespace + "." + strTypeName; MonoClass* windowClass = MonoManager::instance().findClass(strNamespace, strTypeName); if (windowClass == nullptr) return nullptr; MonoAssembly* assembly = MonoManager::instance().getAssembly(EDITOR_ASSEMBLY); MonoClass* defaultSizeAttrib = assembly->getClass("BansheeEditor", "DefaultSize"); if (defaultSizeAttrib == nullptr) BS_EXCEPT(InternalErrorException, "Cannot find DefaultSize managed class."); MonoField* defaultWidthField = defaultSizeAttrib->getField("width"); MonoField* defaultHeightField = defaultSizeAttrib->getField("height"); int width = 200; int height = 200; MonoObject* defaultSizeObj = windowClass->getAttribute(defaultSizeAttrib); if (defaultSizeObj != nullptr) { defaultWidthField->get(defaultSizeObj, &width); defaultHeightField->get(defaultSizeObj, &height); } MonoObject* instance = windowClass->createInstance(false); ManagedDropDownWindow* dropDownWindow = nullptr; if (parentWindow != nullptr && !parentWindow->isDestroyed()) { EditorWidgetBase* editorWidget = parentWindow->getEditorWidget(); EditorWidgetContainer* parentContainer = editorWidget->_getParent(); if (parentContainer != nullptr) { SPtr<RenderWindow> parentRenderWindow = parentContainer->getParentWindow()->getRenderWindow(); SPtr<Camera> parentCamera = parentContainer->getParentWidget().getCamera(); position->x += editorWidget->getX(); position->y += editorWidget->getY(); dropDownWindow = DropDownWindowManager::instance().open<ManagedDropDownWindow>( parentRenderWindow, parentCamera, *position, instance, width, height); } } ScriptDropDownWindow* nativeInstance = new (bs_alloc<ScriptDropDownWindow>()) ScriptDropDownWindow(dropDownWindow); if (dropDownWindow != nullptr) dropDownWindow->initialize(nativeInstance); windowClass->construct(instance); return instance; }
void ScriptEditorWindow::registerManagedEditorWindows() { MonoAssembly* assembly = MonoManager::instance().getAssembly(EDITOR_ASSEMBLY); if(assembly != nullptr) { MonoClass* defaultSizeAttrib = assembly->getClass("BansheeEditor", "DefaultSize"); if (defaultSizeAttrib == nullptr) BS_EXCEPT(InternalErrorException, "Cannot find DefaultSize managed attribute."); MonoField* defaultWidthField = defaultSizeAttrib->getField("width"); MonoField* defaultHeightField = defaultSizeAttrib->getField("height"); MonoClass* undoRedoLocalAttrib = assembly->getClass("BansheeEditor", "UndoRedoLocal"); if (undoRedoLocalAttrib == nullptr) BS_EXCEPT(InternalErrorException, "Cannot find UndoRedoLocal managed attribute."); MonoClass* editorWindowClass = assembly->getClass("BansheeEditor", "EditorWindow"); const Vector<MonoClass*>& allClasses = assembly->getAllClasses(); for(auto& curClass : allClasses) { if(curClass->isSubClassOf(editorWindowClass) && curClass != editorWindowClass) { UINT32 width = 400; UINT32 height = 400; MonoObject* defaultSize = curClass->getAttribute(defaultSizeAttrib); if (defaultSize != nullptr) { defaultWidthField->get(defaultSize, &width); defaultHeightField->get(defaultSize, &height); } bool hasLocalUndoRedo = curClass->getAttribute(undoRedoLocalAttrib) != nullptr; const String& className = curClass->getFullName(); EditorWidgetManager::instance().registerWidget(className, std::bind(&ScriptEditorWindow::openEditorWidgetCallback, curClass->getNamespace(), curClass->getTypeName(), width, height, hasLocalUndoRedo, _1)); AvailableWindowTypes.push_back(className); } } } }
void EditorWidgetManager::registerWidget(const String& name, std::function<EditorWidgetBase*(EditorWidgetContainer&)> createCallback) { auto iterFind = mCreateCallbacks.find(name); if(iterFind != mCreateCallbacks.end()) BS_EXCEPT(InvalidParametersException, "Widget with the same name is already registered. Name: \"" + name + "\""); mCreateCallbacks[name] = createCallback; }
void RTTIField::checkIsDataBlock() { if(!isDataBlockType()) { BS_EXCEPT(InternalErrorException, "Invalid field type. Needed: Data block. Got: " + toString(mIsVectorType) + ", " + toString(isPlainType()) + ", " + toString(isReflectableType()) + ", " + toString(isDataBlockType()) + ", " + toString(isReflectablePtrType())); } }