//------------------------------------------------------------------------------ //## シェーダ側とホスト側で頂点レイアウトの過不足がある場合のテスト。必要な部分さえあれば描画は可能。 TEST_F(Test_Shader_Shader, NotProvidedVertexAttribute) { auto shader1 = Shader::create(LN_ASSETFILE("Shader/NotProvidedVertexAttribute-1.fx")); auto vertexDecl1 = newObject<VertexLayout>(); vertexDecl1->addElement(0, VertexElementType::Float3, VertexElementUsage::Position, 0); Vector3 v[] = { { 0, 0.5, 0 }, { 0.5, -0.25, 0 }, { -0.5, -0.25, 0 }, }; auto vb1 = newObject<VertexBuffer>(sizeof(v), v, GraphicsResourceUsage::Static); auto ctx = Engine::graphicsContext(); TestEnv::resetGraphicsContext(ctx); ctx->setVertexLayout(vertexDecl1); ctx->setVertexBuffer(0, vb1); ctx->setShaderPass(shader1->techniques()[0]->passes()[0]); ctx->setPrimitiveTopology(PrimitiveTopology::TriangleList); ctx->clear(ClearFlags::All, Color::White, 1.0f, 0); ctx->drawPrimitive(0, 1); ASSERT_SCREEN(LN_ASSETFILE("Shader/Result/Test_Shader_Shader-NotProvidedVertexAttribute-1.png")); }
//------------------------------------------------------------------------------ //## UniformBuffer TEST_F(Test_Shader_Shader, UniformBuffer) { auto shader1 = Shader::create(LN_ASSETFILE("Shader/UniformBufferTest-1.fx")); auto vertexDecl1 = newObject<VertexLayout>(); vertexDecl1->addElement(0, VertexElementType::Float3, VertexElementUsage::Position, 0); Vector3 v[] = { { 0, 0.5, 0 }, { 0.5, -0.25, 0 }, { -0.5, -0.25, 0 }, }; auto vb1 = newObject<VertexBuffer>(sizeof(v), v, GraphicsResourceUsage::Static); // VertexShader からのみ参照されるパラメータ shader1->findParameter("_Color1")->setVector(Vector4(1, 0, 0, 1)); // PixelShader からのみ参照されるパラメータ shader1->findParameter("_Color2")->setVector(Vector4(0, 0, 1, 1)); auto ctx = Engine::graphicsContext(); TestEnv::resetGraphicsContext(ctx); ctx->setVertexLayout(vertexDecl1); ctx->setVertexBuffer(0, vb1); ctx->setShaderPass(shader1->techniques()[0]->passes()[0]); ctx->setPrimitiveTopology(PrimitiveTopology::TriangleList); ctx->clear(ClearFlags::All, Color::White, 1.0f, 0); ctx->drawPrimitive(0, 1); ASSERT_SCREEN(LN_ASSETFILE("Shader/Result/Test_Shader_Shader-UniformBuffer-1.png")); }
VertexLayoutID GLBackend::addVertexLayout(const long numStreams, const VertexFormatDesc* formats, const VertexBufferID* vbIDs) { VertexLayout vl; glGenVertexArrays(1, &vl.vaoHandle); glBindVertexArray(vl.vaoHandle); GLsizei stride = 0; unsigned long offset = 0; for (GLuint stream=0; stream < numStreams; stream++) { VertexFormatDesc desc = formats[stream]; stride += desc.size * getDataSize(GLVertexDataTypes[desc.type]); } for (GLuint stream=0; stream < numStreams; stream++) { glEnableVertexAttribArray(stream); setVertexBuffer(vbIDs[stream]); VertexFormatDesc desc = formats[stream]; glVertexAttribPointer(stream, desc.size, GLVertexDataTypes[desc.type], GL_FALSE, stride, (GLvoid*)offset); offset += getDataSize(GLVertexDataTypes[desc.type]); } VertexLayoutID newID = _vertexLayouts.add(vl); _currentVertexLayout = newID; return newID; }
void OgreGeometryBuffer::syncVertexData() const { if (!d_dataAppended) return; // Make sure that our vertex buffer is large enough size_t current_size; if (!d_hwBuffer.isNull() && (current_size = d_hwBuffer->getNumVertices()) < d_vertexCount) { size_t new_size = current_size; // Reallocate the buffer to be large enough while(new_size < d_vertexCount) new_size *= 2; setVertexBuffer(new_size); } // copy vertex data into the Ogre hardware buffer if (d_vertexCount > 0) { if (d_hwBuffer.isNull()) { setVertexBuffer(d_vertexCount); } void* copy_target = d_hwBuffer->lock( Ogre::HardwareVertexBuffer::HBL_DISCARD); assert(copy_target && "Ogre vertex buffer is invalid"); std::memcpy(copy_target, &d_vertexData[0], d_vertexData.size()* sizeof(float)); d_hwBuffer->unlock(); } // Update rendering for the new vertices d_renderOp.vertexData->vertexStart = 0; d_renderOp.vertexData->vertexCount = d_vertexCount; d_dataAppended = false; }
//----------------------------------------------------------------------------- // Reset D3D device //----------------------------------------------------------------------------- void GFXPCD3D9Device::reset( D3DPRESENT_PARAMETERS &d3dpp ) { if(!mD3DDevice) return; mInitialized = false; mMultisampleType = d3dpp.MultiSampleType; mMultisampleLevel = d3dpp.MultiSampleQuality; _validateMultisampleParams(d3dpp.BackBufferFormat, mMultisampleType, mMultisampleLevel); // Clean up some commonly dangling state. This helps prevents issues with // items that are destroyed by the texture manager callbacks and recreated // later, but still left bound. setVertexBuffer(NULL); setPrimitiveBuffer(NULL); for(S32 i=0; i<getNumSamplers(); i++) setTexture(i, NULL); // Deal with the depth/stencil buffer. if(mDeviceDepthStencil) { Con::printf("GFXPCD3D9Device::reset - depthstencil %x has %d ref's", mDeviceDepthStencil, mDeviceDepthStencil->AddRef()-1); mDeviceDepthStencil->Release(); } // First release all the stuff we allocated from D3DPOOL_DEFAULT releaseDefaultPoolResources(); // reset device Con::printf( "--- Resetting D3D Device ---" ); HRESULT hres = S_OK; hres = mD3DDevice->Reset( &d3dpp ); if( FAILED( hres ) ) { while( mD3DDevice->TestCooperativeLevel() == D3DERR_DEVICELOST ) { Sleep( 100 ); } hres = mD3DDevice->Reset( &d3dpp ); } D3D9Assert( hres, "GFXD3D9Device::reset - Failed to create D3D Device!" ); mInitialized = true; // Setup default states initStates(); // Now re aquire all the resources we trashed earlier reacquireDefaultPoolResources(); // Mark everything dirty and flush to card, for sanity. updateStates(true); }
//------------------------------------------------------------------------------ //## Basic TEST_F(Test_Shader_Shader, IndependentSamplerState) { auto shader1 = Shader::create(LN_ASSETFILE("Shader/IndependentSamplerState.fx")); auto vertexDecl1 = newObject<VertexLayout>(); vertexDecl1->addElement(0, VertexElementType::Float3, VertexElementUsage::Position, 0); vertexDecl1->addElement(0, VertexElementType::Float2, VertexElementUsage::TexCoord, 0); struct Vertex { Vector3 pos; Vector2 uv; }; Vertex v[] = { { { -1, 1, 0 }, { 0, 0 }, }, // 0.5 で中央の face からサンプリングする { { 0, 1, 0 }, { 1, 0 }, }, { { -1, 0, 0 }, { 0, 1 }, }, { { 0, 0, 0 }, { 1, 1 }, }, }; auto vb1 = newObject<VertexBuffer>(sizeof(v), v, GraphicsResourceUsage::Static); auto tex1 = newObject<Texture2D>(2, 2, TextureFormat::RGBA8); auto bmp1 = tex1->map(MapMode::Write); bmp1->setPixel32(0, 0, ColorI(255, 0, 0, 255)); bmp1->setPixel32(1, 0, ColorI(255, 0, 255, 255)); bmp1->setPixel32(0, 1, ColorI(0, 255, 0, 255)); bmp1->setPixel32(1, 1, ColorI(0, 0, 255, 255)); // TODO: まだ SamplerState 直接指定をサポートしていないので Texture に対してセットする方法でテストケースだけ用意しておく。 // 後でサポートするとき、shader1->findParameter("mySamplerState")->setSamplerState(samplerState); とかに書き換える。 auto samplerState = newObject<SamplerState>(); samplerState->setFilterMode(TextureFilterMode::Linear); tex1->setSamplerState(samplerState); shader1->findParameter("_Texture")->setTexture(tex1); auto ctx = Engine::graphicsContext(); TestEnv::resetGraphicsContext(ctx); ctx->setVertexLayout(vertexDecl1); ctx->setVertexBuffer(0, vb1); ctx->setIndexBuffer(nullptr); ctx->setShaderPass(shader1->techniques()[0]->passes()[0]); // * [ ] default { ctx->clear(ClearFlags::All, Color::White, 1.0f, 0); ctx->setPrimitiveTopology(PrimitiveTopology::TriangleStrip); ctx->drawPrimitive(0, 2); ASSERT_SCREEN(LN_ASSETFILE("Shader/Result/Test_Shader_Shader-IndependentSamplerState-1.png")); } }
void mirror::setData(ID3D11Device *_m_d3d11Device,float _width, float _height, float _left, float _top) { m_d3d11Device = _m_d3d11Device; left = _left; top = _top; width = _width; height = _height; float cameraZ = 0; //********************m_backMirror_VERTEX m_backMirror_VERTEX[0].xyz.x = left; m_backMirror_VERTEX[0].xyz.y = top; m_backMirror_VERTEX[0].xyz.z = cameraZ; m_backMirror_VERTEX[0].uvw.x = 0; m_backMirror_VERTEX[0].uvw.y = 0; m_backMirror_VERTEX[0].uvw.z = 0; m_backMirror_VERTEX[1].xyz.x = m_backMirror_VERTEX[0].xyz.x + width; m_backMirror_VERTEX[1].xyz.y = m_backMirror_VERTEX[0].xyz.y; m_backMirror_VERTEX[1].xyz.z = cameraZ; m_backMirror_VERTEX[1].uvw.x = 1; m_backMirror_VERTEX[1].uvw.y = 0; m_backMirror_VERTEX[1].uvw.z = 0; m_backMirror_VERTEX[2].xyz.x = m_backMirror_VERTEX[0].xyz.x + width; m_backMirror_VERTEX[2].xyz.y = m_backMirror_VERTEX[0].xyz.y - height; m_backMirror_VERTEX[2].xyz.z = cameraZ; m_backMirror_VERTEX[2].uvw.x = 1; m_backMirror_VERTEX[2].uvw.y = 1; m_backMirror_VERTEX[2].uvw.z = 0; m_backMirror_VERTEX[3].xyz.x = m_backMirror_VERTEX[0].xyz.x; m_backMirror_VERTEX[3].xyz.y = m_backMirror_VERTEX[0].xyz.y - height; m_backMirror_VERTEX[3].xyz.z = cameraZ; m_backMirror_VERTEX[3].uvw.x = 0; m_backMirror_VERTEX[3].uvw.y = 1; m_backMirror_VERTEX[3].uvw.z = 0; for (int i = 0; i < 4; i++) { m_backMirror_VERTEX[i].nrm.x = 0; m_backMirror_VERTEX[i].nrm.y = 0; m_backMirror_VERTEX[i].nrm.z = -1; } unsigned int mirror_indicies[6] = { 0, 2, 3, 0, 1, 2 }; setVertexBuffer(m_backMirror_VERTEX, rectNumber); setIndexBuffer(mirror_indicies, rectIndexNumber); }
void mirror::setPos(ID3D11Device *_m_d3d11Device, const XMFLOAT2& topleft, const XMFLOAT2& topright, const XMFLOAT2& botright, const XMFLOAT2& botleft) { m_d3d11Device = _m_d3d11Device; float cameraZ = 0; //********************m_backMirror_VERTEX //topleft m_backMirror_VERTEX[0].xyz.x = topleft.x; m_backMirror_VERTEX[0].xyz.y = topleft.y; m_backMirror_VERTEX[0].xyz.z = cameraZ; m_backMirror_VERTEX[0].uvw.x = 0; m_backMirror_VERTEX[0].uvw.y = 0; m_backMirror_VERTEX[0].uvw.z = 0; //top right m_backMirror_VERTEX[1].xyz.x = topright.x; m_backMirror_VERTEX[1].xyz.y = topright.y; m_backMirror_VERTEX[1].xyz.z = cameraZ; m_backMirror_VERTEX[1].uvw.x = 1; m_backMirror_VERTEX[1].uvw.y = 0; m_backMirror_VERTEX[1].uvw.z = 0; //bot right m_backMirror_VERTEX[2].xyz.x = botright.x; m_backMirror_VERTEX[2].xyz.y = botright.y; m_backMirror_VERTEX[2].xyz.z = cameraZ; m_backMirror_VERTEX[2].uvw.x = 1; m_backMirror_VERTEX[2].uvw.y = 1; m_backMirror_VERTEX[2].uvw.z = 0; //bot left m_backMirror_VERTEX[3].xyz.x = botleft.x; m_backMirror_VERTEX[3].xyz.y = botleft.y; m_backMirror_VERTEX[3].xyz.z = cameraZ; m_backMirror_VERTEX[3].uvw.x = 0; m_backMirror_VERTEX[3].uvw.y = 1; m_backMirror_VERTEX[3].uvw.z = 0; for (int i = 0; i < 4; i++) { m_backMirror_VERTEX[i].nrm.x = 0; m_backMirror_VERTEX[i].nrm.y = 0; m_backMirror_VERTEX[i].nrm.z = -1; } unsigned int mirror_indicies[6] = { 0, 2, 3, 0, 1, 2 }; setVertexBuffer(m_backMirror_VERTEX, rectNumber); setIndexBuffer(mirror_indicies, rectIndexNumber); }
//------------------------------------------------------------------------------ //## MultiTechMultiTexture TEST_F(Test_Shader_Shader, MultiTechMultiTexture) { auto shader1 = Shader::create(LN_ASSETFILE("Shader/MultiTechMultiTexture-1.fx")); auto vertexDecl1 = newObject<VertexLayout>(); vertexDecl1->addElement(0, VertexElementType::Float3, VertexElementUsage::Position, 0); Vector3 v[] = { { 0, 0.5, 0 }, { 0.5, -0.25, 0 }, { -0.5, -0.25, 0 }, }; auto vb1 = newObject<VertexBuffer>(sizeof(v), v, GraphicsResourceUsage::Static); auto t1 = Texture2D::create(2, 2, TextureFormat::RGBA8); t1->clear(Color::Red); shader1->findParameter("_Texture1")->setTexture(t1); auto t2 = Texture2D::create(2, 2, TextureFormat::RGBA8); t2->clear(Color::Green); shader1->findParameter("_Texture2")->setTexture(t2); auto ctx = Engine::graphicsContext(); TestEnv::resetGraphicsContext(ctx); ctx->setVertexLayout(vertexDecl1); ctx->setVertexBuffer(0, vb1); ctx->setPrimitiveTopology(PrimitiveTopology::TriangleList); ctx->clear(ClearFlags::All, Color::White, 1.0f, 0); // _Texture1 のみ (赤) ctx->setShaderPass(shader1->techniques()[0]->passes()[0]); ctx->drawPrimitive(0, 1); ASSERT_SCREEN(LN_ASSETFILE("Shader/Result/Test_Shader_Shader-MultiTechMultiTexture-1.png")); // _Texture2 のみ (緑) ctx->setShaderPass(shader1->techniques()[1]->passes()[0]); ctx->drawPrimitive(0, 1); ASSERT_SCREEN(LN_ASSETFILE("Shader/Result/Test_Shader_Shader-MultiTechMultiTexture-2.png")); // _Texture1 + _Texture2 (黄) ctx->setShaderPass(shader1->techniques()[2]->passes()[0]); ctx->drawPrimitive(0, 1); ASSERT_SCREEN(LN_ASSETFILE("Shader/Result/Test_Shader_Shader-MultiTechMultiTexture-3.png")); }
void ShadowsDemo::onDraw() { App::onDraw(); const auto device = graphicsDevice(); device->setClearColor(0.0f, 0.0f, 0.0f, 0.0f); device->clear(ciri::ClearFlags::Color | ciri::ClearFlags::Depth); device->setRasterizerState(_rasterState); device->restoreDefaultBlendState(); if( _spotlightShader->isValid() && _directionalShader->isValid() ) { const cc::Mat4f& cameraViewProj = _camera.getProj() * _camera.getView(); bool firstLight = true; Light::Type boundLightType = Light::Type::Invalid; for( auto& light : _lights ) { // compute light matrices //const cc::Mat4f& lightView = light.view(); //const cc::Mat4f& lightProj = light.proj();//cc::math::perspectiveRH(45.0f, 1.0f, 0.1f, light.range());//light.proj(); //const cc::Mat4f lightViewProj = lightProj * lightView; if( light.type() == Light::Type::Directional ) { //light.computeViewProjFromFrustum(BoundingFrustum(cameraViewProj)); light.computeViewProjFromFrustum(BoundingFrustum(_camera.getFov(), _camera.getAspect(), _camera.getNearPlane(), _camera.getFarPlane(), _camera.getPosition(), _camera.getFpsFront(), _camera.getUp())); //light.computeViewProjOrtho(_camera.getView(), _camera.getFov(), _camera.getAspect(), _camera.getNearPlane(), _camera.getFarPlane()); } const cc::Mat4f lightViewProj = light.proj() * light.view(); if( light.castShadows() ) { device->setDepthStencilState(device->getDefaultDepthStencilDefault()); // set and clear render target ciri::IRenderTarget2D* depthTarget = _shadowTarget.get(); device->setRenderTargets(&depthTarget, 1); device->setClearColor(0.0f, 0.0f, 0.0f, 0.0f); device->clear(ciri::ClearFlags::Color | ciri::ClearFlags::Depth); // apply depth shader device->applyShader(_depthShader); // set viewport to depth size device->setViewport(ciri::Viewport(0, 0, _shadowTarget->getDepth()->getWidth(), _shadowTarget->getDepth()->getHeight())); // render all models for( auto& mdl : _models ) { _depthConstants.xform = lightViewProj * mdl->getXform().getWorld(); _depthConstantsBuffer->setData(sizeof(DepthConstants), &_depthConstants); device->setVertexBuffer(mdl->getVertexBuffer()); if( mdl->getIndexBuffer() != nullptr ) { device->setIndexBuffer(mdl->getIndexBuffer()); device->drawIndexed(ciri::PrimitiveTopology::TriangleList, mdl->getIndexBuffer()->getIndexCount()); } else { device->drawArrays(ciri::PrimitiveTopology::TriangleList, mdl->getVertexBuffer()->getVertexCount(), 0); } } // reser viewport to screen device->setViewport(ciri::Viewport(0, 0, window()->getWidth(), window()->getHeight())); // restore default render targets device->restoreDefaultRenderTargets(); } switch( light.type() ) { case Light::Type::Directional: { if( boundLightType != Light::Type::Directional || light.castShadows() ) { boundLightType = Light::Type::Directional; device->applyShader(_directionalShader); device->setTexture2D(0, _shadowTarget->getDepth(), ciri::ShaderStage::Pixel); device->setSamplerState(0, _shadowSampler, ciri::ShaderStage::Pixel); } _directionalConstants.LightDirection = light.direction(); _directionalConstants.LightColor = light.diffuseColor(); _directionalConstants.LightIntensity = light.diffuseIntensity(); _directionalConstants.campos = _camera.getPosition(); _directionalConstants.CastShadows = light.castShadows(); _directionalConstants.lightViewProj = lightViewProj; for( auto& mdl : _models ) { if( !mdl->isValid() ) { continue; } _directionalConstants.world = mdl->getXform().getWorld(); _directionalConstants.xform = cameraViewProj * _directionalConstants.world; _directionalConstantsBuffer->setData(sizeof(DirectionalConstants), &_directionalConstants); device->setVertexBuffer(mdl->getVertexBuffer()); if( mdl->getIndexBuffer() != nullptr ) { device->setIndexBuffer(mdl->getIndexBuffer()); device->drawIndexed(ciri::PrimitiveTopology::TriangleList, mdl->getIndexBuffer()->getIndexCount()); } else { device->drawArrays(ciri::PrimitiveTopology::TriangleList, mdl->getVertexBuffer()->getVertexCount(), 0); } } break; } case Light::Type::Spot: { if( boundLightType != Light::Type::Spot || light.castShadows() ) { boundLightType = Light::Type::Spot; device->applyShader(_spotlightShader); device->setTexture2D(0, _shadowTarget->getDepth(), ciri::ShaderStage::Pixel); device->setSamplerState(0, _shadowSampler, ciri::ShaderStage::Pixel); } _spotlightConstants.LightPosition = light.position(); _spotlightConstants.LightDirection = light.direction(); _spotlightConstants.LightColor = light.diffuseColor(); _spotlightConstants.LightCosInner = light.cosConeInnerAngle(true); _spotlightConstants.LightCosOuter = light.cosConeOuterAngle(true); _spotlightConstants.LightIntensity = light.diffuseIntensity(); _spotlightConstants.LightRange = light.range(); _spotlightConstants.CastShadows = light.castShadows(); _spotlightConstants.lightViewProj = lightViewProj; for( auto& mdl : _models ) { _spotlightConstants.world = mdl->getXform().getWorld(); _spotlightConstants.xform = cameraViewProj * _spotlightConstants.world; _spotlightConstantsBuffer->setData(sizeof(SpotlightConstants), &_spotlightConstants); device->setVertexBuffer(mdl->getVertexBuffer()); if( mdl->getIndexBuffer() != nullptr ) { device->setIndexBuffer(mdl->getIndexBuffer()); device->drawIndexed(ciri::PrimitiveTopology::TriangleList, mdl->getIndexBuffer()->getIndexCount()); } else { device->drawArrays(ciri::PrimitiveTopology::TriangleList, mdl->getVertexBuffer()->getVertexCount(), 0); } } break; } } if( firstLight ) { firstLight = false; device->setBlendState(_additiveBlendState); } } } device->present(); }
void Mesh::setVertexBuffer(const HardwareVertexBuffer& vertexbuffer) { auto ptr = lock(); if ( ptr ) ptr->setVertexBuffer(vertexbuffer); }