Пример #1
0
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();
	}
}
Пример #2
0
	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);
	}
Пример #3
0
	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(&currentBuffer->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
	}