void SPK_PLQuadRenderer::UpdateVertexBuffer(const SPK::Group &group) { // Get the vertex buffer instance from m_pSPK_PLBuffer and lock it VertexBuffer *pVertexBuffer = m_pSPK_PLBuffer->GetVertexBuffer(); if (pVertexBuffer->Lock(Lock::WriteOnly)) { // Get particle renderer to use void (SPK_PLQuadRenderer::*pRenderParticle)(const SPK::Particle&); // Pointer to the right render method switch (texturingMode) { case SPK::TEXTURE_2D: if (group.getModel()->isEnabled(SPK::PARAM_TEXTURE_INDEX)) pRenderParticle = group.getModel()->isEnabled(SPK::PARAM_ANGLE) ? &SPK_PLQuadRenderer::Render2DAtlasRot : &SPK_PLQuadRenderer::Render2DAtlas; else pRenderParticle = group.getModel()->isEnabled(SPK::PARAM_ANGLE) ? &SPK_PLQuadRenderer::Render2DRot : &SPK_PLQuadRenderer::Render2D; break; case SPK::TEXTURE_3D: pRenderParticle = group.getModel()->isEnabled(SPK::PARAM_ANGLE) ? &SPK_PLQuadRenderer::Render3DRot : &SPK_PLQuadRenderer::Render3D; break; case SPK::TEXTURE_NONE: pRenderParticle = group.getModel()->isEnabled(SPK::PARAM_ANGLE) ? &SPK_PLQuadRenderer::Render2DRot : &SPK_PLQuadRenderer::Render2D; break; default: pRenderParticle = nullptr; break; } // Get current vertex buffer data m_nCurrentVertexSize = pVertexBuffer->GetVertexSize(); m_pfCurrentPosition = static_cast<float*>(pVertexBuffer->GetData(0, VertexBuffer::Position)); m_pfCurrentTexCoord = static_cast<float*>(pVertexBuffer->GetData(0, VertexBuffer::TexCoord)); m_pCurrentVertexBuffer = pVertexBuffer; m_nCurrentVertex = 0; // Calculate the current orientation const bool bGlobalOrientation = precomputeOrientation3D( group, SPK::Vector3D(-m_mWorldViewInverse.fM[8], -m_mWorldViewInverse.fM[9], -m_mWorldViewInverse.fM[10]), SPK::Vector3D( m_mWorldViewInverse.fM[4], m_mWorldViewInverse.fM[5], m_mWorldViewInverse.fM[6]), SPK::Vector3D( m_mWorldViewInverse.fM[12], m_mWorldViewInverse.fM[13], m_mWorldViewInverse.fM[14])); if (pRenderParticle) { if (bGlobalOrientation) { computeGlobalOrientation3D(); for (size_t i=0; i<group.getNbParticles(); i++) (this->*pRenderParticle)(group.getParticle(i)); } else { for (size_t i=0; i<group.getNbParticles(); i++) { const SPK::Particle &cParticle = group.getParticle(i); computeSingleOrientation3D(cParticle); (this->*pRenderParticle)(cParticle); } } } // Unlock the vertex buffer pVertexBuffer->Unlock(); } }
void GLQuadRenderer::render(const Group& group) { if (!prepareBuffers(group)) return; float oldModelView[16]; for (int i = 0; i < 16; ++i) oldModelView[i] = modelView[i]; glGetFloatv(GL_MODELVIEW_MATRIX,modelView); for (int i = 0; i < 16; ++i) if (oldModelView[i] != modelView[i]) { invertModelView(); break; } initBlending(); initRenderingHints(); glShadeModel(GL_FLAT); switch(texturingMode) { case TEXTURE_2D : if (getTexture3DGLExt() == SUPPORTED) glDisable(GL_TEXTURE_3D); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,textureIndex); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,getTextureBlending()); if (!group.getModel()->isEnabled(PARAM_TEXTURE_INDEX)) { if (!group.getModel()->isEnabled(PARAM_ANGLE)) renderParticle = &GLQuadRenderer::render2D; else renderParticle = &GLQuadRenderer::render2DRot; } else { if (!group.getModel()->isEnabled(PARAM_ANGLE)) renderParticle = &GLQuadRenderer::render2DAtlas; else renderParticle = &GLQuadRenderer::render2DAtlasRot; } break; case TEXTURE_3D : glDisable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_3D); glBindTexture(GL_TEXTURE_3D,textureIndex); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,getTextureBlending()); if (!group.getModel()->isEnabled(PARAM_ANGLE)) renderParticle = &GLQuadRenderer::render3D; else renderParticle = &GLQuadRenderer::render3DRot; break; case TEXTURE_NONE : glDisable(GL_TEXTURE_2D); if (getTexture3DGLExt() == SUPPORTED) glDisable(GL_TEXTURE_3D); if (!group.getModel()->isEnabled(PARAM_ANGLE)) renderParticle = &GLQuadRenderer::render2D; else renderParticle = &GLQuadRenderer::render2DRot; break; } bool globalOrientation = precomputeOrientation3D( group, Vector3D(-invModelView[8],-invModelView[9],-invModelView[10]), Vector3D(invModelView[4],invModelView[5],invModelView[6]), Vector3D(invModelView[12],invModelView[13],invModelView[14])); if (globalOrientation) { computeGlobalOrientation3D(); for (size_t i = 0; i < group.getNbParticles(); ++i) (this->*renderParticle)(group.getParticle(i)); } else { for (size_t i = 0; i < group.getNbParticles(); ++i) { const Particle& particle = group.getParticle(i); computeSingleOrientation3D(particle); (this->*renderParticle)(particle); } } glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); if (texturingMode == TEXTURE_2D) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2,GL_FLOAT,0,textureBuffer); } else if (texturingMode == TEXTURE_3D) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(3,GL_FLOAT,0,textureBuffer); } // interleaves vertex and color data glVertexPointer(3,GL_FLOAT,7 * sizeof(float),gpuBuffer); glColorPointer(4,GL_FLOAT,7 * sizeof(float),gpuBuffer + 3); glDrawArrays(GL_QUADS,0,group.getNbParticles() << 2); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); if (texturingMode != TEXTURE_NONE) glDisableClientState(GL_TEXTURE_COORD_ARRAY); }
void GLQuadRenderer::render(const Group& group,const DataSet* dataSet,RenderBuffer* renderBuffer) const { SPK_ASSERT(renderBuffer != NULL,"GLQuadRenderer::render(const Group&,const DataSet*,RenderBuffer*) - renderBuffer must not be NULL"); GLBuffer& buffer = static_cast<GLBuffer&>(*renderBuffer); buffer.positionAtStart(); // Repositions all the buffers at the start float oldModelView[16]; for (int i = 0; i < 16; ++i) oldModelView[i] = modelView[i]; glGetFloatv(GL_MODELVIEW_MATRIX,modelView); for (int i = 0; i < 16; ++i) if (oldModelView[i] != modelView[i]) { invertModelView(); break; } initBlending(); initRenderingOptions(); glShadeModel(GL_FLAT); switch(texturingMode) { case TEXTURE_MODE_2D : // Creates and inits the 2D TexCoord buffer if necessary if (buffer.getNbTexCoords() != 2) { buffer.setNbTexCoords(2); if (!group.isEnabled(PARAM_TEXTURE_INDEX)) { float t[8] = {1.0f,0.0f,0.0f,0.0f,0.0f,1.0f,1.0f,1.0f}; for (size_t i = 0; i < group.getCapacity() << 3; ++i) buffer.setNextTexCoord(t[i & 7]); } } // Binds the texture #ifndef SPK_GL_NO_EXT if (SPK_GL_CHECK_EXTENSION(SPK_GL_TEXTURE_3D_EXT)) glDisable(GL_TEXTURE_3D_EXT); #endif glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,textureIndex); // Selects the correct function if (!group.isEnabled(PARAM_TEXTURE_INDEX)) { if (!group.isEnabled(PARAM_ANGLE)) renderParticle = &GLQuadRenderer::render2D; else renderParticle = &GLQuadRenderer::render2DRot; } else { if (!group.isEnabled(PARAM_ANGLE)) renderParticle = &GLQuadRenderer::render2DAtlas; else renderParticle = &GLQuadRenderer::render2DAtlasRot; } break; case TEXTURE_MODE_3D : // Creates and inits the 3D TexCoord buffer if necessery if (buffer.getNbTexCoords() != 3) { buffer.setNbTexCoords(3); float t[12] = {1.0f,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,1.0f,1.0f,0.0f}; for (size_t i = 0; i < group.getCapacity() * 12; ++i) buffer.setNextTexCoord(t[i % 12]); } // Binds the texture glDisable(GL_TEXTURE_2D); #ifndef SPK_GL_NO_EXT glEnable(GL_TEXTURE_3D_EXT); glBindTexture(GL_TEXTURE_3D_EXT,textureIndex); #endif // Selects the correct function if (!group.isEnabled(PARAM_ANGLE)) renderParticle = &GLQuadRenderer::render3D; else renderParticle = &GLQuadRenderer::render3DRot; break; case TEXTURE_MODE_NONE : if (buffer.getNbTexCoords() != 0) buffer.setNbTexCoords(0); glDisable(GL_TEXTURE_2D); // Selects the correct function #ifndef SPK_GL_NO_EXT if (SPK_GL_CHECK_EXTENSION(SPK_GL_TEXTURE_3D_EXT)) glDisable(GL_TEXTURE_3D_EXT); #endif if (!group.isEnabled(PARAM_ANGLE)) renderParticle = &GLQuadRenderer::render2D; else renderParticle = &GLQuadRenderer::render2DRot; break; } bool globalOrientation = precomputeOrientation3D( group, Vector3D(-invModelView[8],-invModelView[9],-invModelView[10]), Vector3D(invModelView[4],invModelView[5],invModelView[6]), Vector3D(invModelView[12],invModelView[13],invModelView[14])); // Fills the buffers if (globalOrientation) { computeGlobalOrientation3D(group); for (ConstGroupIterator particleIt(group); !particleIt.end(); ++particleIt) (this->*renderParticle)(*particleIt,buffer); } else { for (ConstGroupIterator particleIt(group); !particleIt.end(); ++particleIt) { computeSingleOrientation3D(*particleIt); (this->*renderParticle)(*particleIt,buffer); } } buffer.render(GL_QUADS,group.getNbParticles() << 2); }
void IRRQuadRenderer::render(const Group& group) { if (!prepareBuffers(group)) return; irr::video::IVideoDriver* driver = device->getVideoDriver(); // Computes the inverse model view irr::core::matrix4 invModelView; { irr::core::matrix4 modelView(driver->getTransform(irr::video::ETS_VIEW)); modelView *= driver->getTransform(irr::video::ETS_WORLD); modelView.getInversePrimitive(invModelView); // wont work for odd modelview matrices (but should happen in very special cases) } // Saves the renderer texture irr::video::ITexture* savedTexture = material.TextureLayer[0].Texture; if (texturingMode == TEXTURE_NONE) material.TextureLayer[0].Texture = NULL; if ((texturingMode == TEXTURE_2D)&&(group.getModel()->isEnabled(PARAM_TEXTURE_INDEX))) { if (group.getModel()->isEnabled(PARAM_ANGLE)) renderParticle = &IRRQuadRenderer::renderAtlasRot; else renderParticle = &IRRQuadRenderer::renderAtlas; } else { if (group.getModel()->isEnabled(PARAM_ANGLE)) renderParticle = &IRRQuadRenderer::renderRot; else renderParticle = &IRRQuadRenderer::renderBasic; } // At the first frame we pass the full buffer so that VBOs are correctly initialised // Then at next frames we pass only what is needed to be rendered if (currentBuffer->areVBOInitialized()) currentBuffer->setUsed(group.getNbParticles()); else currentBuffer->setUsed(group.getParticles().getNbReserved()); bool globalOrientation = precomputeOrientation3D( group, Vector3D(invModelView[8],invModelView[9],invModelView[10]), Vector3D(invModelView[4],invModelView[5],invModelView[6]), Vector3D(invModelView[12],invModelView[13],invModelView[14])); if (globalOrientation) { computeGlobalOrientation3D(); for (size_t t = 0; t < group.getNbParticles(); ++t) (this->*renderParticle)(group.getParticle(t)); } else { for (size_t t = 0; t < group.getNbParticles(); ++t) { const Particle& particle = group.getParticle(t); computeSingleOrientation3D(particle); (this->*renderParticle)(particle); } } currentBuffer->getMeshBuffer().setDirty(irr::scene::EBT_VERTEX); driver->setMaterial(material); driver->drawMeshBuffer(¤tBuffer->getMeshBuffer()); // this draw call is used in order to be able to use VBOs currentBuffer->setVBOInitialized(true); material.TextureLayer[0].Texture = savedTexture; // Restores the texture }