protected void _renderWithGPUInstancing(SSRenderConfig renderConfig) { if (renderConfig.drawingShadowMap && renderConfig.drawingPssm) { renderConfig.instancePssmShader.Activate(); renderConfig.instancePssmShader.UniObjectWorldTransform = this.worldMat; } else { // texture binding and world mat setup renderConfig.instanceShader.Activate(); base.setDefaultShaderState(renderConfig.instanceShader, renderConfig); } ISSInstancableShaderProgram instanceShader = renderConfig.ActiveInstanceShader; // prepare attribute arrays for draw GL.PushClientAttrib(ClientAttribMask.ClientAllAttribBits); _prepareAttribute(_posBuffer, instanceShader.AttrInstancePos, instanceData.positions); _prepareAttribute(_orientationXYBuffer, instanceShader.AttrInstanceOrientationXY, instanceData.orientationsXY); _prepareAttribute(_orientationZBuffer, instanceShader.AttrInstanceOrientationZ, instanceData.orientationsZ); _prepareAttribute(_masterScaleBuffer, instanceShader.AttrInstanceMasterScale, instanceData.masterScales); _prepareAttribute(_componentScaleXYBuffer, instanceShader.AttrInstanceComponentScaleXY, instanceData.componentScalesXY); _prepareAttribute(_componentScaleZBuffer, instanceShader.AttrInstanceComponentScaleZ, instanceData.componentScalesZ); _prepareAttribute(_colorBuffer, instanceShader.AttrInstanceColor, instanceData.colors); //prepareAttribute(m_spriteIndexBuffer, instanceShader.AttrInstanceSpriteIndex, m_ps.SpriteIndices); _prepareAttribute(_spriteOffsetUBuffer, instanceShader.AttrInstanceSpriteOffsetU, instanceData.spriteOffsetsU); _prepareAttribute(_spriteOffsetVBuffer, instanceShader.AttrInstanceSpriteOffsetV, instanceData.spriteOffsetsV); _prepareAttribute(_spriteSizeUBuffer, instanceShader.AttrInstanceSpriteSizeU, instanceData.spriteSizesU); _prepareAttribute(_spriteSizeVBuffer, instanceShader.AttrInstanceSpriteSizeV, instanceData.spriteSizesV); // do the draw mesh.drawInstanced(renderConfig, instanceData.activeBlockLength, this.primType); GL.PopClientAttrib(); //this.boundingSphere.Render(ref renderConfig); }
public static void PrepareTexCoord(SSRenderConfig renderConfig, int stride, IntPtr offset) { ISSInstancableShaderProgram isp = renderConfig.ActiveInstanceShader; if (isp == null) // no instancing // this is the "transitional" GLSL 120 way of assigning buffer contents // http://www.opentk.com/node/80?page=1 { GL.EnableClientState(ArrayCap.TextureCoordArray); GL.TexCoordPointer(2, TexCoordPointerType.Float, stride, offset); } else // instancing { preparePerVertexAttribute(stride, offset, isp.AttrTexCoord, 2); } }
public override void Render(SSRenderConfig renderConfig) { Matrix4 modelView = this.worldMat * renderConfig.invCameraViewMatrix; // allow particle system to react to camera/worldview particleSystem.updateCamera(ref modelView, ref renderConfig.projectionMatrix); // do we have anything to draw? if (particleSystem.activeBlockLength <= 0) { return; } base.Render(renderConfig); // select either instance shader or instance pssm shader ISSInstancableShaderProgram instanceShader = renderConfig.instanceShader; if (renderConfig.drawingShadowMap) { if (renderConfig.drawingPssm) { renderConfig.instancePssmShader.Activate(); renderConfig.instancePssmShader.UniObjectWorldTransform = this.worldMat; instanceShader = renderConfig.instancePssmShader; } } else { if (!globalBillboarding && base.alphaBlendingEnabled) { // Must be called before updating buffers particleSystem.sortByDepth(ref modelView); // Fixes flicker issues for particles with "fighting" view depth values // Also assumes the particle system is the last to be drawn in a scene GL.DepthFunc(DepthFunction.Lequal); } if (depthRead) { GL.Enable(EnableCap.DepthTest); } else { GL.Disable(EnableCap.DepthTest); } GL.DepthMask(depthWrite); // texture binding setup renderConfig.instanceShader.Activate(); renderConfig.instanceShader.UniObjectWorldTransform = this.worldMat; if (base.textureMaterial != null) { renderConfig.instanceShader.SetupTextures(base.textureMaterial); } } if (globalBillboarding) { // Setup "global" billboarding. (entire particle system is rendered as a camera-facing // billboard and will show the same position of particles from all angles) modelView = OpenTKHelper.BillboardMatrix(ref modelView); GL.MatrixMode(MatrixMode.Modelview); GL.LoadMatrix(ref modelView); } instanceShader.Activate(); // prepare attribute arrays for draw GL.PushClientAttrib(ClientAttribMask.ClientAllAttribBits); prepareAttribute(_posBuffer, instanceShader.AttrInstancePos, particleSystem.positions); prepareAttribute(_orientationXYBuffer, instanceShader.AttrInstanceOrientationXY, particleSystem.orientationsXY); prepareAttribute(_orientationZBuffer, instanceShader.AttrInstanceOrientationZ, particleSystem.orientationsZ); prepareAttribute(_masterScaleBuffer, instanceShader.AttrInstanceMasterScale, particleSystem.masterScales); prepareAttribute(_componentScaleXYBuffer, instanceShader.AttrInstanceComponentScaleXY, particleSystem.componentScalesXY); prepareAttribute(_componentScaleZBuffer, instanceShader.AttrInstanceComponentScaleZ, particleSystem.componentScalesZ); prepareAttribute(_colorBuffer, instanceShader.AttrInstanceColor, particleSystem.colors); //prepareAttribute(m_spriteIndexBuffer, instanceShader.AttrInstanceSpriteIndex, m_ps.SpriteIndices); prepareAttribute(_spriteOffsetUBuffer, instanceShader.AttrInstanceSpriteOffsetU, particleSystem.spriteOffsetsU); prepareAttribute(_spriteOffsetVBuffer, instanceShader.AttrInstanceSpriteOffsetV, particleSystem.SpriteOffsetsV); prepareAttribute(_spriteSizeUBuffer, instanceShader.AttrInstanceSpriteSizeU, particleSystem.SpriteSizesU); prepareAttribute(_spriteSizeVBuffer, instanceShader.AttrInstanceSpriteSizeV, particleSystem.SpriteSizesV); // do the draw mesh.renderInstanced(renderConfig, particleSystem.activeBlockLength, PrimitiveType.Triangles); GL.PopClientAttrib(); //this.boundingSphere.Render(ref renderConfig); }