Exemple #1
0
void FrameGraphRenderable::fillHardwareBuffers()
{
    Ogre::HardwareVertexBufferSharedPtr vbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(0);
    Ogre::Real *vertices = static_cast<Ogre::Real*>(vbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));

    Ogre::HardwareVertexBufferSharedPtr vcbuf = mRenderOp.vertexData->vertexBufferBinding->getBuffer(1);
    Ogre::RGBA* pColours = static_cast<Ogre::RGBA*>(vcbuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));

    Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem();
    uint16_t index = 0;
    for (uint16_t i = 0; i < mNumFrames; i++) {
        float x = i * mLineSpace - 1.0f;

        // OgreTime line
        vertices[index +  0] = x;
        vertices[index +  1] = -1;
        vertices[index +  2] = 0;	// Vertex
        rs->convertColourValue(Ogre::ColourValue(1.0f, 0.0f, 0.0f), pColours++);		// Color
        vertices[index +  3] = x;
        vertices[index +  4] = -1;
        vertices[index +  5] = 0;	// Vertex
        rs->convertColourValue(Ogre::ColourValue(1.0f, 0.0f, 0.0f), pColours++);		// Color

        // BulletTime line
        vertices[index +  6] = x;
        vertices[index +  7] = -1;
        vertices[index +  8] = 0;	// Vertex
        rs->convertColourValue(Ogre::ColourValue(0.0f, 1.0f, 0.0f), pColours++);		// Color
        vertices[index +  9] = x;
        vertices[index + 10] = -1;
        vertices[index + 11] = 0;	// Vertex
        rs->convertColourValue(Ogre::ColourValue(0.0f, 1.0f, 0.0f), pColours++);		// Color

        // WorldTime line
        vertices[index + 12] = x;
        vertices[index + 13] = -1;
        vertices[index + 14] = 0;	// Vertex
        rs->convertColourValue(Ogre::ColourValue(0.0f, 0.0f, 1.0f), pColours++);		// Color
        vertices[index + 15] = x;
        vertices[index + 16] = -1;
        vertices[index + 17] = 0;	// Vertex
        rs->convertColourValue(Ogre::ColourValue(0.0f, 0.0f, 1.0f), pColours++);		// Color

        // UnknownTime line
        vertices[index + 18] = x;
        vertices[index + 19] = -1;
        vertices[index + 20] = 0;	// Vertex
        rs->convertColourValue(Ogre::ColourValue(1.0f, 1.0f, 1.0f), pColours++);		// Color
        vertices[index + 21] = x;
        vertices[index + 22] = -1;
        vertices[index + 23] = 0;	// Vertex
        rs->convertColourValue(Ogre::ColourValue(1.0f, 1.0f, 1.0f), pColours++);		// Color

        index += ValuesPerGraphLine;
    }
    vcbuf->unlock();
    vbuf->unlock();

    mBox.setInfinite();
}
void CDynamicLineDrawer::FillHardwareBuffers()
{
	int Size = int(Points.size());

	PrepareHardwareBuffers(Size);

	if (!Size) {
		mBox.setExtents( Ogre::Vector3::ZERO, Ogre::Vector3::ZERO );
		Dirty = false;
		return;
	}

	Ogre::Vector3 AABMin = Points[0];
	Ogre::Vector3 AABMax = Points[0];

	Ogre::HardwareVertexBufferSharedPtr VBuf =
		mRenderOp.vertexData->vertexBufferBinding->getBuffer(0);

	Ogre::HardwareVertexBufferSharedPtr CBuf =
		mRenderOp.vertexData->vertexBufferBinding->getBuffer(1);

	// get rendersystem to pack colours
	Ogre::RenderSystem* RS = Ogre::Root::getSingleton().getRenderSystem();

	Ogre::Real* VPrPos = static_cast<Ogre::Real*>(VBuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
	Ogre::RGBA* CPrPos = static_cast<Ogre::RGBA*>(CBuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
	for(int i = 0; i < Size; i++)
	{
		*VPrPos++ = Points[i].x;
		*VPrPos++ = Points[i].y;
		*VPrPos++ = Points[i].z;

		Ogre::RGBA color;
		RS->convertColourValue(Colours[i], &color);
		*CPrPos++ = color;
		//*CPrPos++ = unsigned int(Colours[i].g);
		//*CPrPos++ = unsigned int(Colours[i].b);

		if(Points[i].x < AABMin.x)
			AABMin.x = Points[i].x;
		if(Points[i].y < AABMin.y)
			AABMin.y = Points[i].y;
		if(Points[i].z < AABMin.z)
			AABMin.z = Points[i].z;

		if(Points[i].x > AABMax.x)
			AABMax.x = Points[i].x;
		if(Points[i].y > AABMax.y)
			AABMax.y = Points[i].y;
		if(Points[i].z > AABMax.z)
			AABMax.z = Points[i].z;
	}
	VBuf->unlock();
	CBuf->unlock();

	mBox.setExtents(AABMin, AABMax);

	Dirty = false;
}
Exemple #3
0
void
MeshExtractor( const MeshData& mesh_data, const Ogre::String& material_name, File* file, int offset_to_data, VectorTexForGen& textures, const Ogre::MeshPtr& mesh, const Ogre::String& name, int bone_id )
{
    int offset_to_vertex     = offset_to_data;
    int offset_to_triangle_t = offset_to_vertex + 0x04 + file->GetU32LE( offset_to_vertex );
    int number_of_triangle_t = file->GetU16LE( offset_to_triangle_t );
    u16 tpage  = file->GetU16LE( offset_to_triangle_t + 0x02 );
    int offset_to_quad_t     = offset_to_triangle_t + 0x04 + number_of_triangle_t * 0x10;
    int number_of_quad_t     = file->GetU16LE( offset_to_quad_t );
    int offset_to_triangle   = offset_to_quad_t + 0x4 + number_of_quad_t * 0x14;
    int number_of_triangle   = file->GetU16LE( offset_to_triangle );
    int offset_to_quad       = offset_to_triangle + 0x4 + number_of_triangle * 0x14;
    int number_of_quad       = file->GetU16LE( offset_to_quad );

    Ogre::SubMesh* sub_mesh = mesh->createSubMesh( name );
    sub_mesh->setMaterialName( material_name );
    sub_mesh->useSharedVertices = false;
    sub_mesh->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;

    // Allocate and prepare vertex data
    sub_mesh->vertexData = new Ogre::VertexData();
    sub_mesh->vertexData->vertexStart = 0;
    sub_mesh->vertexData->vertexCount = static_cast< size_t >( number_of_triangle_t * 3 + number_of_quad_t * 6 + number_of_triangle * 3 + number_of_quad * 6 );

    sub_mesh->indexData = new Ogre::IndexData();
    sub_mesh->indexData->indexStart = 0;
    sub_mesh->indexData->indexCount = sub_mesh->vertexData->vertexCount;
    sub_mesh->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
        Ogre::HardwareIndexBuffer::IT_16BIT,
        sub_mesh->indexData->indexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    u16* idata = static_cast< u16* >( sub_mesh->indexData->indexBuffer->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
    u32 cur_index = 0;

    Ogre::VertexDeclaration* decl = sub_mesh->vertexData->vertexDeclaration;
    Ogre::VertexBufferBinding* bind = sub_mesh->vertexData->vertexBufferBinding;
    // 1st buffer
    decl->addElement( POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
    Ogre::HardwareVertexBufferSharedPtr vbuf0 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( POSITION_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    bind->setBinding( POSITION_BINDING, vbuf0 );

    // 2nd buffer
    decl->addElement( COLOUR_BINDING, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE );
    Ogre::HardwareVertexBufferSharedPtr vbuf1 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( COLOUR_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    // Set vertex buffer binding so buffer 1 is bound to our colour buffer
    bind->setBinding( COLOUR_BINDING, vbuf1 );

    // 3rd buffer
    decl->addElement( TEXTURE_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0 );
    Ogre::HardwareVertexBufferSharedPtr vbuf2 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( TEXTURE_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    bind->setBinding( TEXTURE_BINDING, vbuf2 );

    float* pPos   = static_cast< float* >( vbuf0->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
    float* tPos   = static_cast< float* >( vbuf2->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );

    Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem();
    Ogre::RGBA colours[ sub_mesh->vertexData->vertexCount ];



    // add textured triangle
    for (int j = 0; j < number_of_triangle_t; ++j)
    {
        int offset_a = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x0);
        int offset_b = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x2);
        int offset_c = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0x4);

        Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04));
        Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04));
        Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04));
        a /= 512;
        b /= 512;
        c /= 512;

        u16 clut = file->GetU16LE(offset_to_triangle_t + 0x4 + j * 0x10 + 0xa);
        int clut_x = (clut & 0x003f) << 3;
        int clut_y = (clut & 0xffc0) >> 6;
        int bpp    = (tpage >> 0x7) & 0x3;
        int vram_x = (tpage & 0xf) * 64;
        int vram_y = ((tpage & 0x10) >> 4) * 256;
        TexForGen texture;
        texture.palette_x = clut_x;
        texture.palette_y = clut_y;
        texture.texture_x = vram_x;
        texture.texture_y = vram_y;
        texture.bpp = ( BPP )bpp;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at(0, 0);
        Ogre::Vector2 bt(0, 0);
        Ogre::Vector2 ct(0, 0);

        int x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x8) + texture.start_x;
        at.x = x / (float)mesh_data.tex_width;
        int y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x9) + texture.start_y;
        at.y = y / (float)mesh_data.tex_height;
        x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xc) + texture.start_x;
        bt.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xd) + texture.start_y;
        bt.y = y / (float)mesh_data.tex_height;
        x = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xe) + texture.start_x;
        ct.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0xf) + texture.start_y;
        ct.y = y / (float)mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;

        Ogre::ColourValue colour = Ogre::ColourValue(file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f,
                                                     file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f,
                                                     file->GetU8(offset_to_triangle_t + 0x4 + j * 0x10 + 0x6) / 256.0f,
                                                     1.0f);

        rs->convertColourValue(colour, colours + cur_index + 0);
        rs->convertColourValue(colour, colours + cur_index + 1);
        rs->convertColourValue(colour, colours + cur_index + 2);

        idata[cur_index + 0] = cur_index + 0;
        idata[cur_index + 1] = cur_index + 1;
        idata[cur_index + 2] = cur_index + 2;

        cur_index += 3;
    }



    // add textured quad
    for (int j = 0; j < number_of_quad_t; ++j)
    {
        int offset_a = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x0);
        int offset_b = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x2);
        int offset_c = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x4);
        int offset_d = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0x6);

        Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04));
        Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04));
        Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04));
        Ogre::Vector3 d((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 04));
        a /= 512;
        b /= 512;
        c /= 512;
        d /= 512;

        u16 clut = file->GetU16LE(offset_to_quad_t + 0x4 + j * 0x14 + 0xa);
        int clut_x = (clut & 0x003f) << 3;
        int clut_y = (clut & 0xffc0) >> 6;
        int bpp    = (tpage >> 0x7) & 0x3;
        int vram_x = (tpage & 0xf) * 64;
        int vram_y = ((tpage & 0x10) >> 4) * 256;
        TexForGen texture;
        texture.palette_x = clut_x;
        texture.palette_y = clut_y;
        texture.texture_x = vram_x;
        texture.texture_y = vram_y;
        texture.bpp = ( BPP )bpp;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at(0, 0);
        Ogre::Vector2 bt(0, 0);
        Ogre::Vector2 ct(0, 0);
        Ogre::Vector2 dt(0, 0);

        int x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x8) + texture.start_x;
        at.x = x / (float)mesh_data.tex_width;
        int y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x9) + texture.start_y;
        at.y = y / (float)mesh_data.tex_height;

        x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xc) + texture.start_x;
        bt.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xd) + texture.start_y;
        bt.y = y / (float)mesh_data.tex_height;

        x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xe) + texture.start_x;
        ct.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0xf) + texture.start_y;
        ct.y = y / (float)mesh_data.tex_height;

        x = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x10) + texture.start_x;
        dt.x = x / (float)mesh_data.tex_width;
        y = file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x11) + texture.start_y;
        dt.y = y / (float)mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = dt.x; *tPos++ = dt.y;

        Ogre::ColourValue colour = Ogre::ColourValue(file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f,
                                                     file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f,
                                                     file->GetU8(offset_to_quad_t + 0x4 + j * 0x14 + 0x12) / 256.0f,
                                                     1.0f);

        rs->convertColourValue(colour, colours + cur_index + 0);
        rs->convertColourValue(colour, colours + cur_index + 1);
        rs->convertColourValue(colour, colours + cur_index + 2);
        rs->convertColourValue(colour, colours + cur_index + 3);
        rs->convertColourValue(colour, colours + cur_index + 4);
        rs->convertColourValue(colour, colours + cur_index + 5);

        idata[cur_index + 0] = cur_index + 0;
        idata[cur_index + 1] = cur_index + 1;
        idata[cur_index + 2] = cur_index + 2;
        idata[cur_index + 3] = cur_index + 3;
        idata[cur_index + 4] = cur_index + 4;
        idata[cur_index + 5] = cur_index + 5;

        cur_index += 6;
    }



    // add color triangle
    for (int j = 0; j < number_of_triangle; ++j)
    {
        int offset_a = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x0);
        int offset_b = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x2);
        int offset_c = file->GetU16LE(offset_to_triangle + 0x4 + j * 0x14 + 0x4);

        Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04));
        Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04));
        Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04));
        a /= 512;
        b /= 512;
        c /= 512;

        TexForGen texture;
        texture.palette_x = 0;
        texture.palette_y = 0;
        texture.texture_x = 0;
        texture.texture_y = 0;
        texture.bpp = BPP_BLACK;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at(0, 0);
        Ogre::Vector2 bt(0, 0);
        Ogre::Vector2 ct(0, 0);

        at.x = bt.x = ct.x = texture.start_x / (float)mesh_data.tex_width;
        at.y = bt.y = ct.y = texture.start_y / (float)mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;

        Ogre::ColourValue a_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x08) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x09) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0a) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0b) / 256.0f);
        Ogre::ColourValue b_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0c) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0d) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0e) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x0f) / 256.0f);
        Ogre::ColourValue c_colour = Ogre::ColourValue(file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x10) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x11) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x12) / 256.0f,
                                                       file->GetU8(offset_to_triangle + 0x4 + j * 0x14 + 0x13) / 256.0f);

        rs->convertColourValue(a_colour, colours + cur_index + 0);
        rs->convertColourValue(c_colour, colours + cur_index + 1);
        rs->convertColourValue(b_colour, colours + cur_index + 2);

        idata[cur_index + 0] = cur_index + 0;
        idata[cur_index + 1] = cur_index + 1;
        idata[cur_index + 2] = cur_index + 2;

        cur_index += 3;
    }



    // add color quad
    for (int j = 0; j < number_of_quad; ++j)
    {
        int offset_a = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x0);
        int offset_b = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x2);
        int offset_c = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x4);
        int offset_d = file->GetU16LE(offset_to_quad + 0x4 + j * 0x18 + 0x6);

        Ogre::Vector3 a((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_a + 04));
        Ogre::Vector3 b((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_b + 04));
        Ogre::Vector3 c((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_c + 04));
        Ogre::Vector3 d((s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 00),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 02),
                        (s16)file->GetU16LE(offset_to_vertex + 0x04 + offset_d + 04));
        a /= 512;
        b /= 512;
        c /= 512;
        d /= 512;

        TexForGen texture;
        texture.palette_x = 0;
        texture.palette_y = 0;
        texture.texture_x = 0;
        texture.texture_y = 0;
        texture.bpp = BPP_BLACK;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at(0, 0);
        Ogre::Vector2 bt(0, 0);
        Ogre::Vector2 ct(0, 0);
        Ogre::Vector2 dt(0, 0);

        at.x = bt.x = ct.x = dt.x = texture.start_x / (float)mesh_data.tex_width;
        at.y = bt.y = ct.y = dt.y = texture.start_y / (float)mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = dt.x; *tPos++ = dt.y;

        Ogre::ColourValue a_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x08) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x09) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0a) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0b) / 256.0f);
        Ogre::ColourValue b_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0c) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0d) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0e) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x0f) / 256.0f);
        Ogre::ColourValue c_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x10) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x11) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x12) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x13) / 256.0f);
        Ogre::ColourValue d_colour = Ogre::ColourValue(file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x14) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x15) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x16) / 256.0f,
                                                       file->GetU8(offset_to_quad + 0x4 + j * 0x18 + 0x17) / 256.0f);

        rs->convertColourValue(a_colour, colours + cur_index + 0);
        rs->convertColourValue(c_colour, colours + cur_index + 1);
        rs->convertColourValue(b_colour, colours + cur_index + 2);
        rs->convertColourValue(b_colour, colours + cur_index + 3);
        rs->convertColourValue(c_colour, colours + cur_index + 4);
        rs->convertColourValue(d_colour, colours + cur_index + 5);

        idata[cur_index + 0] = cur_index + 0;
        idata[cur_index + 1] = cur_index + 1;
        idata[cur_index + 2] = cur_index + 2;
        idata[cur_index + 3] = cur_index + 3;
        idata[cur_index + 4] = cur_index + 4;
        idata[cur_index + 5] = cur_index + 5;

        cur_index += 6;
    }

    vbuf0->unlock();
    vbuf1->writeData(0, vbuf1->getSizeInBytes(), colours, true);
    vbuf2->unlock();

    sub_mesh->indexData->indexBuffer->unlock();
    // Optimize index data
    sub_mesh->indexData->optimiseVertexCacheTriList();

    if (bone_id != -1)
    {
        LOGGER->Log("Assign bones to vertexes\n");

        int vertex_number = sub_mesh->vertexData->vertexCount;
        for( int i = 0; i < vertex_number; ++i )
        {
            Ogre::VertexBoneAssignment vba;
            vba.vertexIndex = i;
            vba.boneIndex = bone_id;
            vba.weight = 1.0f;
            sub_mesh->addBoneAssignment( vba );
        }
    }
}
Exemple #4
0
void NIFMeshLoader::createSubMesh(Ogre::Mesh *mesh, const Nif::NiTriShape *shape)
{
    const Nif::NiTriShapeData *data = shape->data.getPtr();
    const Nif::NiSkinInstance *skin = (shape->skin.empty() ? NULL : shape->skin.getPtr());
    std::vector<Ogre::Vector3> srcVerts = data->vertices;
    std::vector<Ogre::Vector3> srcNorms = data->normals;
    Ogre::HardwareBuffer::Usage vertUsage = Ogre::HardwareBuffer::HBU_STATIC;
    bool vertShadowBuffer = false;

    bool geomMorpherController = false;
    if(!shape->controller.empty())
    {
        Nif::ControllerPtr ctrl = shape->controller;
        do {
            if(ctrl->recType == Nif::RC_NiGeomMorpherController)
            {
                vertUsage = Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY;
                vertShadowBuffer = true;
                geomMorpherController = true;
                break;
            }
        } while(!(ctrl=ctrl->next).empty());
    }

    if(skin != NULL)
    {
        vertUsage = Ogre::HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY;
        vertShadowBuffer = true;

        // Only set a skeleton when skinning. Unskinned meshes with a skeleton will be
        // explicitly attached later.
        mesh->setSkeletonName(mName);

        // Convert vertices and normals to bone space from bind position. It would be
        // better to transform the bones into bind position, but there doesn't seem to
        // be a reliable way to do that.
        std::vector<Ogre::Vector3> newVerts(srcVerts.size(), Ogre::Vector3(0.0f));
        std::vector<Ogre::Vector3> newNorms(srcNorms.size(), Ogre::Vector3(0.0f));

        const Nif::NiSkinData *data = skin->data.getPtr();
        const Nif::NodeList &bones = skin->bones;
        for(size_t b = 0;b < bones.length();b++)
        {
            Ogre::Matrix4 mat;
            mat.makeTransform(data->bones[b].trafo.trans, Ogre::Vector3(data->bones[b].trafo.scale),
                              Ogre::Quaternion(data->bones[b].trafo.rotation));
            mat = bones[b]->getWorldTransform() * mat;

            const std::vector<Nif::NiSkinData::VertWeight> &weights = data->bones[b].weights;
            for(size_t i = 0;i < weights.size();i++)
            {
                size_t index = weights[i].vertex;
                float weight = weights[i].weight;

                newVerts.at(index) += (mat*srcVerts[index]) * weight;
                if(newNorms.size() > index)
                {
                    Ogre::Vector4 vec4(srcNorms[index][0], srcNorms[index][1], srcNorms[index][2], 0.0f);
                    vec4 = mat*vec4 * weight;
                    newNorms[index] += Ogre::Vector3(&vec4[0]);
                }
            }
        }

        srcVerts = newVerts;
        srcNorms = newNorms;
    }
    else
    {
        Ogre::SkeletonManager *skelMgr = Ogre::SkeletonManager::getSingletonPtr();
        if(skelMgr->getByName(mName).isNull())
        {
            // No skinning and no skeleton, so just transform the vertices and
            // normals into position.
            Ogre::Matrix4 mat4 = shape->getWorldTransform();
            for(size_t i = 0;i < srcVerts.size();i++)
            {
                Ogre::Vector4 vec4(srcVerts[i].x, srcVerts[i].y, srcVerts[i].z, 1.0f);
                vec4 = mat4*vec4;
                srcVerts[i] = Ogre::Vector3(&vec4[0]);
            }
            for(size_t i = 0;i < srcNorms.size();i++)
            {
                Ogre::Vector4 vec4(srcNorms[i].x, srcNorms[i].y, srcNorms[i].z, 0.0f);
                vec4 = mat4*vec4;
                srcNorms[i] = Ogre::Vector3(&vec4[0]);
            }
        }
    }

    // Set the bounding box first
    BoundsFinder bounds;
    bounds.add(&srcVerts[0][0], srcVerts.size());
    if(!bounds.isValid())
    {
        float v[3] = { 0.0f, 0.0f, 0.0f };
        bounds.add(&v[0], 1);
    }

    mesh->_setBounds(Ogre::AxisAlignedBox(bounds.minX()-0.5f, bounds.minY()-0.5f, bounds.minZ()-0.5f,
                                          bounds.maxX()+0.5f, bounds.maxY()+0.5f, bounds.maxZ()+0.5f));
    mesh->_setBoundingSphereRadius(bounds.getRadius());

    // This function is just one long stream of Ogre-barf, but it works
    // great.
    Ogre::HardwareBufferManager *hwBufMgr = Ogre::HardwareBufferManager::getSingletonPtr();
    Ogre::HardwareVertexBufferSharedPtr vbuf;
    Ogre::HardwareIndexBufferSharedPtr ibuf;
    Ogre::VertexBufferBinding *bind;
    Ogre::VertexDeclaration *decl;
    int nextBuf = 0;

    Ogre::SubMesh *sub = mesh->createSubMesh();

    // Add vertices
    sub->useSharedVertices = false;
    sub->vertexData = new Ogre::VertexData();
    sub->vertexData->vertexStart = 0;
    sub->vertexData->vertexCount = srcVerts.size();

    decl = sub->vertexData->vertexDeclaration;
    bind = sub->vertexData->vertexBufferBinding;
    if(srcVerts.size())
    {
        vbuf = hwBufMgr->createVertexBuffer(Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3),
                                            srcVerts.size(), vertUsage, vertShadowBuffer);
        vbuf->writeData(0, vbuf->getSizeInBytes(), &srcVerts[0][0], true);

        decl->addElement(nextBuf, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
        bind->setBinding(nextBuf++, vbuf);
    }

    // Vertex normals
    if(srcNorms.size())
    {
        vbuf = hwBufMgr->createVertexBuffer(Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3),
                                            srcNorms.size(), vertUsage, vertShadowBuffer);
        vbuf->writeData(0, vbuf->getSizeInBytes(), &srcNorms[0][0], true);

        decl->addElement(nextBuf, 0, Ogre::VET_FLOAT3, Ogre::VES_NORMAL);
        bind->setBinding(nextBuf++, vbuf);
    }

    // Vertex colors
    const std::vector<Ogre::Vector4> &colors = data->colors;
    if(colors.size())
    {
        Ogre::RenderSystem *rs = Ogre::Root::getSingleton().getRenderSystem();
        std::vector<Ogre::RGBA> colorsRGB(colors.size());
        for(size_t i = 0;i < colorsRGB.size();i++)
        {
            Ogre::ColourValue clr(colors[i][0], colors[i][1], colors[i][2], colors[i][3]);
            rs->convertColourValue(clr, &colorsRGB[i]);
        }
        vbuf = hwBufMgr->createVertexBuffer(Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR),
                                            colorsRGB.size(), Ogre::HardwareBuffer::HBU_STATIC);
        vbuf->writeData(0, vbuf->getSizeInBytes(), &colorsRGB[0], true);
        decl->addElement(nextBuf, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
        bind->setBinding(nextBuf++, vbuf);
    }

    // Texture UV coordinates
    size_t numUVs = data->uvlist.size();
    if (numUVs)
    {
        size_t elemSize = Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);

        for(size_t i = 0; i < numUVs; i++)
            decl->addElement(nextBuf, elemSize*i, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, i);

        vbuf = hwBufMgr->createVertexBuffer(decl->getVertexSize(nextBuf), srcVerts.size(),
                                            Ogre::HardwareBuffer::HBU_STATIC);

        std::vector<Ogre::Vector2> allUVs;
        allUVs.reserve(srcVerts.size()*numUVs);
        for (size_t vert = 0; vert<srcVerts.size(); ++vert)
            for(size_t i = 0; i < numUVs; i++)
                allUVs.push_back(data->uvlist[i][vert]);

        vbuf->writeData(0, elemSize*srcVerts.size()*numUVs, &allUVs[0], true);

        bind->setBinding(nextBuf++, vbuf);
    }

    // Triangle faces
    const std::vector<short> &srcIdx = data->triangles;
    if(srcIdx.size())
    {
        ibuf = hwBufMgr->createIndexBuffer(Ogre::HardwareIndexBuffer::IT_16BIT, srcIdx.size(),
                                           Ogre::HardwareBuffer::HBU_STATIC);
        ibuf->writeData(0, ibuf->getSizeInBytes(), &srcIdx[0], true);
        sub->indexData->indexBuffer = ibuf;
        sub->indexData->indexCount = srcIdx.size();
        sub->indexData->indexStart = 0;
    }

    // Assign bone weights for this TriShape
    if(skin != NULL)
    {
        Ogre::SkeletonPtr skel = Ogre::SkeletonManager::getSingleton().getByName(mName);

        const Nif::NiSkinData *data = skin->data.getPtr();
        const Nif::NodeList &bones = skin->bones;
        for(size_t i = 0;i < bones.length();i++)
        {
            Ogre::VertexBoneAssignment boneInf;
            boneInf.boneIndex = skel->getBone(bones[i]->name)->getHandle();

            const std::vector<Nif::NiSkinData::VertWeight> &weights = data->bones[i].weights;
            for(size_t j = 0;j < weights.size();j++)
            {
                boneInf.vertexIndex = weights[j].vertex;
                boneInf.weight = weights[j].weight;
                sub->addBoneAssignment(boneInf);
            }
        }
    }

    const Nif::NiTexturingProperty *texprop = NULL;
    const Nif::NiMaterialProperty *matprop = NULL;
    const Nif::NiAlphaProperty *alphaprop = NULL;
    const Nif::NiVertexColorProperty *vertprop = NULL;
    const Nif::NiZBufferProperty *zprop = NULL;
    const Nif::NiSpecularProperty *specprop = NULL;
    const Nif::NiWireframeProperty *wireprop = NULL;
    bool needTangents = false;

    shape->getProperties(texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop);
    std::string matname = NIFMaterialLoader::getMaterial(data, mesh->getName(), mGroup,
                                                         texprop, matprop, alphaprop,
                                                         vertprop, zprop, specprop,
                                                         wireprop, needTangents);
    if(matname.length() > 0)
        sub->setMaterialName(matname);

    // build tangents if the material needs them
    if (needTangents)
    {
        unsigned short src,dest;
        if (!mesh->suggestTangentVectorBuildParams(Ogre::VES_TANGENT, src,dest))
            mesh->buildTangentVectors(Ogre::VES_TANGENT, src,dest);
    }

    // Create a dummy vertex animation track if there's a geom morpher controller
    // This is required to make Ogre create the buffers we will use for software vertex animation
    if (srcVerts.size() && geomMorpherController)
        mesh->createAnimation("dummy", 0)->createVertexTrack(1, sub->vertexData, Ogre::VAT_MORPH);
}
void GPUBillboardSet::createVertexDataForVertexAndGeometryShaders(const std::vector<PhotoSynth::Vertex>& vertices)
{
	// Setup render operation
	mRenderOp.operationType = Ogre::RenderOperation::OT_POINT_LIST; 
	mRenderOp.vertexData = OGRE_NEW Ogre::VertexData();
	mRenderOp.vertexData->vertexCount = vertices.size(); 
	mRenderOp.vertexData->vertexStart = 0; 
	mRenderOp.useIndexes = false; 
	mRenderOp.indexData = 0;

	// Vertex format declaration
	unsigned short sourceBufferIdx = 0;
    Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
    size_t currOffset = 0;
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR);

	// Create vertex buffer
	Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
		decl->getVertexSize(sourceBufferIdx),
		mRenderOp.vertexData->vertexCount,
		Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    // Bind vertex buffer
    Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
	bind->setBinding(sourceBufferIdx, vbuf);

	// Fill vertex buffer (see http://www.ogre3d.org/docs/manual/manual_59.html#SEC287)
	Ogre::RenderSystem* renderSystem = Ogre::Root::getSingletonPtr()->getRenderSystem();
	unsigned char* pVert = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
	Ogre::Real* pReal;
	Ogre::RGBA* pRGBA;
	Ogre::VertexDeclaration::VertexElementList elems = decl->findElementsBySource(sourceBufferIdx);
	Ogre::VertexDeclaration::VertexElementList::iterator itr;
	for (unsigned int i=0; i<vertices.size(); ++i )
	{
		const PhotoSynth::Vertex& vertex = vertices[i];
		for (itr=elems.begin(); itr!=elems.end(); ++itr)
		{
			Ogre::VertexElement& elem = *itr;
			if (elem.getSemantic() == Ogre::VES_POSITION)
			{
				elem.baseVertexPointerToElement(pVert, &pReal);
				*pReal = vertex.position.x; *pReal++;
				*pReal = vertex.position.y; *pReal++;
				*pReal = vertex.position.z; *pReal++;
			}
			else if (elem.getSemantic() == Ogre::VES_DIFFUSE)
			{
				elem.baseVertexPointerToElement(pVert, &pRGBA);
				renderSystem->convertColourValue(vertex.color, pRGBA);
			}
		}
		// Go to next vertex 
		pVert += vbuf->getVertexSize();
	}
	vbuf->unlock();

    // Set material
    this->setMaterial("GPUBillboardWithGS");
}
void GPUBillboardSet::createVertexDataForVertexShaderOnly(const std::vector<PhotoSynth::Vertex>& vertices)
{
	// Setup render operation
	mRenderOp.operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST; 
	mRenderOp.vertexData = OGRE_NEW Ogre::VertexData();
	mRenderOp.vertexData->vertexCount = vertices.size() * 4; 
	mRenderOp.vertexData->vertexStart = 0; 
	mRenderOp.useIndexes = true; 
	mRenderOp.indexData = OGRE_NEW Ogre::IndexData();
	mRenderOp.indexData->indexCount = vertices.size() * 6;
	mRenderOp.indexData->indexStart = 0;

	// Vertex format declaration
	unsigned short sourceBufferIdx = 0;
	Ogre::VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
    size_t currOffset = 0;
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_FLOAT3, Ogre::VES_POSITION);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT3);
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_COLOUR);
	decl->addElement(sourceBufferIdx, currOffset, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0);
	currOffset += Ogre::VertexElement::getTypeSize(Ogre::VET_FLOAT2);

	// Create vertex buffer
    Ogre::HardwareVertexBufferSharedPtr vbuf = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
		decl->getVertexSize(sourceBufferIdx),
        mRenderOp.vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY);

    // Bind vertex buffer
    Ogre::VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
	bind->setBinding(sourceBufferIdx, vbuf);

	// Fill vertex buffer (see http://www.ogre3d.org/docs/manual/manual_59.html#SEC287)
	Ogre::RenderSystem* renderSystem = Ogre::Root::getSingletonPtr()->getRenderSystem();
	unsigned char* pVert = static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_DISCARD));
	Ogre::Real* pReal;
	Ogre::RGBA* pRGBA;
	Ogre::VertexDeclaration::VertexElementList elems = decl->findElementsBySource(sourceBufferIdx);
	Ogre::VertexDeclaration::VertexElementList::iterator itr;

	const Ogre::Vector2 uvs[4] = {	Ogre::Vector2( -1.f, 1.f ),
									Ogre::Vector2( -1.f, -1.f ),
									Ogre::Vector2( 1.f, -1.f ),
									Ogre::Vector2( 1.f, 1.f ) };
	for (unsigned int i=0; i<vertices.size(); ++i )
	{
		const PhotoSynth::Vertex& vertex = vertices[i];
		for ( unsigned int j=0; j<4; j++ )
		{
			for (itr=elems.begin(); itr!=elems.end(); ++itr)
			{
				Ogre::VertexElement& elem = *itr;
				if (elem.getSemantic() == Ogre::VES_POSITION)
				{
					elem.baseVertexPointerToElement(pVert, &pReal);
					*pReal = vertex.position.x; *pReal++;
					*pReal = vertex.position.y; *pReal++;
					*pReal = vertex.position.z; *pReal++;
				}
				else if (elem.getSemantic() == Ogre::VES_DIFFUSE)
				{
					elem.baseVertexPointerToElement(pVert, &pRGBA);
					renderSystem->convertColourValue(vertex.color, pRGBA);
				}
				else if (elem.getSemantic() == Ogre::VES_TEXTURE_COORDINATES && elem.getIndex() == 0)
				{
					elem.baseVertexPointerToElement(pVert, &pReal);
					*pReal = uvs[j].x; *pReal++;
					*pReal = uvs[j].y; *pReal++;
				}
			}
			// Go to next vertex 
			pVert += vbuf->getVertexSize();
		}
	}
	vbuf->unlock();

	// Create index buffer
	if (mRenderOp.indexData->indexCount>=65536)
	{
		Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer( 
			Ogre::HardwareIndexBuffer::IT_32BIT, 
			mRenderOp.indexData->indexCount, 
			Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);

		mRenderOp.indexData->indexBuffer = ibuf;
		Ogre::uint32* indices = static_cast<Ogre::uint32*>(ibuf->lock( Ogre::HardwareBuffer::HBL_DISCARD));

		Ogre::uint32 indexFirstVertex = 0;
		const Ogre::uint32 inds[6] = {	0, 1, 2, 3, 0, 2 };
		for (unsigned int i=0; i<vertices.size(); ++i)
		{
			for (unsigned int j=0; j<6; ++j)
			{
				*indices = indexFirstVertex + inds[j];
				indices++;
			}
			indexFirstVertex +=4;
		}
		ibuf->unlock();
	}
	else
	{
		Ogre::HardwareIndexBufferSharedPtr ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
			Ogre::HardwareIndexBuffer::IT_16BIT, 
			mRenderOp.indexData->indexCount, 
			Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY, false);

		mRenderOp.indexData->indexBuffer = ibuf;
		Ogre::uint16* indices = static_cast<Ogre::uint16*>( ibuf->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );

		Ogre::uint32 indexFirstVertex = 0;
		const Ogre::uint16 inds[6] = {	0, 1, 2, 3, 0, 2 };
		for ( unsigned int i=0; i<vertices.size(); ++i )
		{
			for ( unsigned int j=0; j<6; ++j )
			{
				*indices = indexFirstVertex + inds[j];
				indices++;
			}
			indexFirstVertex +=4;
		}
		ibuf->unlock();
	}

    // Set material
    this->setMaterial("GPUBillboard");
}
Exemple #7
0
void
MeshExtractor( const MeshData& mesh_data, const Ogre::String& material_name, File* file, int offset_to_data, VectorTexForGen& textures, const Ogre::MeshPtr& mesh )
{
    File* file12 = new File( "./data/field/5/1b/1/12/1" );
    u32 offset_to_clut_tex = 4 + file12->GetU32LE( 4 + 4 ) & 0x00ffffff;
    LOGGER->Log( "offset_to_clut_tex = \"" + HexToString( offset_to_clut_tex, 8, '0' ) + "\".\n" );
    u32 offset_to_tx_ty = offset_to_clut_tex + file12->GetU8( 4 + 7 ) * 4;
    LOGGER->Log( "offset_to_tx_ty = \"" + HexToString( offset_to_tx_ty, 8, '0' ) + "\".\n" );



    int number_of_monochrome_textured_quads = file->GetU16LE( offset_to_data + 0x02 );
    int number_of_monochrome_textured_triangles = file->GetU16LE( offset_to_data + 0x04 );
    int number_of_shaded_textured_quads = file->GetU16LE( offset_to_data + 0x06 );
    int number_of_shaded_textured_triangles = file->GetU16LE( offset_to_data + 0x08 );
    int number_of_gradated_quads = file->GetU16LE( offset_to_data + 0x0a );
    int number_of_gradated_triangles = file->GetU16LE( offset_to_data + 0x0c );
    int number_of_monochrome_quads = file->GetU16LE( offset_to_data + 0x0e );
    int number_of_monochrome_triangles = file->GetU16LE( offset_to_data + 0x10 );

    u32 pointer_to_vertex_groups = file->GetU32LE( offset_to_data + 0x14 );
    u32 pointer_to_vertex_data = file->GetU32LE( offset_to_data + 0x18 );
    u32 pointer_to_mesh_data = file->GetU32LE( offset_to_data + 0x1c );
    u32 pointer_to_texture_data = file->GetU32LE( offset_to_data + 0x20 );



    Ogre::SubMesh* sub_mesh = mesh->createSubMesh(/* name */);
    sub_mesh->setMaterialName( material_name );
    sub_mesh->useSharedVertices = false;
    sub_mesh->operationType = Ogre::RenderOperation::OT_TRIANGLE_LIST;

    // Allocate and prepare vertex data
    sub_mesh->vertexData = new Ogre::VertexData();
    sub_mesh->vertexData->vertexStart = 0;
    sub_mesh->vertexData->vertexCount = static_cast< size_t >(
        number_of_monochrome_textured_quads * 6 +
        number_of_monochrome_textured_triangles * 3/* +
        number_of_shaded_textured_quads * 6 +
        number_of_shaded_textured_triangles * 3 +
        number_of_gradated_quads * 6 +
        number_of_gradated_triangles * 3 +
        number_of_monochrome_quads * 6 +
        number_of_monochrome_triangles * 3*/ );

    sub_mesh->indexData = new Ogre::IndexData();
    sub_mesh->indexData->indexStart = 0;
    sub_mesh->indexData->indexCount = sub_mesh->vertexData->vertexCount;
    sub_mesh->indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
        Ogre::HardwareIndexBuffer::IT_16BIT,
        sub_mesh->indexData->indexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    u16* idata = static_cast< u16* >( sub_mesh->indexData->indexBuffer->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
    u32 cur_index = 0;

    Ogre::VertexDeclaration* decl = sub_mesh->vertexData->vertexDeclaration;
    Ogre::VertexBufferBinding* bind = sub_mesh->vertexData->vertexBufferBinding;
    // 1st buffer
    decl->addElement( POSITION_BINDING, 0, Ogre::VET_FLOAT3, Ogre::VES_POSITION );
    Ogre::HardwareVertexBufferSharedPtr vbuf0 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( POSITION_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    bind->setBinding( POSITION_BINDING, vbuf0 );

    // 2nd buffer
    decl->addElement( COLOUR_BINDING, 0, Ogre::VET_COLOUR, Ogre::VES_DIFFUSE );
    Ogre::HardwareVertexBufferSharedPtr vbuf1 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( COLOUR_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    // Set vertex buffer binding so buffer 1 is bound to our colour buffer
    bind->setBinding( COLOUR_BINDING, vbuf1 );

    // 3rd buffer
    decl->addElement( TEXTURE_BINDING, 0, Ogre::VET_FLOAT2, Ogre::VES_TEXTURE_COORDINATES, 0 );
    Ogre::HardwareVertexBufferSharedPtr vbuf2 = Ogre::HardwareBufferManager::getSingleton().createVertexBuffer(
        decl->getVertexSize( TEXTURE_BINDING ),
        sub_mesh->vertexData->vertexCount,
        Ogre::HardwareBuffer::HBU_STATIC_WRITE_ONLY );
    bind->setBinding( TEXTURE_BINDING, vbuf2 );

    float* pPos   = static_cast< float* >( vbuf0->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );
    float* tPos   = static_cast< float* >( vbuf2->lock( Ogre::HardwareBuffer::HBL_DISCARD ) );

    Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem();
    
    std::vector<Ogre::RGBA> coloursVec(sub_mesh->vertexData->vertexCount);

    Ogre::RGBA* colours = coloursVec.data();



    for( int i = 0; i < number_of_monochrome_textured_quads; ++i )
    {
        int index_a = file->GetU16LE( pointer_to_mesh_data + 0x0 );
        int index_b = file->GetU16LE( pointer_to_mesh_data + 0x2 );
        int index_c = file->GetU16LE( pointer_to_mesh_data + 0x4 );
        int index_d = file->GetU16LE( pointer_to_mesh_data + 0x6 );

        Ogre::Vector3 a( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x4 ) );
        Ogre::Vector3 b( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x4 ) );
        Ogre::Vector3 c( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x4 ) );
        Ogre::Vector3 d( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_d * 0x8 + 0x4 ) );
        a /= 512;
        b /= 512;
        c /= 512;
        d /= 512;




        int image_id = file->GetU8( pointer_to_mesh_data + 0x13 );
        u16 blend = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 0 );
        u16 clut = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 2 );
        LOGGER->Log( "image_id = \"" + HexToString( image_id, 2, '0' ) + "\", clut = \"" + HexToString( clut, 4, '0' ) + "\", blend = \"" + HexToString( blend, 4, '0' ) + "\".\n" );
/*
        int clut_x = (clut & 0x003f) << 3;
        int clut_y = (clut & 0xffc0) >> 6;
        int bpp    = (tpage >> 0x7) & 0x3;
        int vram_x = (tpage & 0xf) * 64;
        int vram_y = ((tpage & 0x10) >> 4) * 256;
*/
        TexForGen texture;
        texture.palette_x = 128/*clut_x*/;
        texture.palette_y = 224/*clut_y*/;
        if( image_id == 1 )
        {
            texture.texture_x = 768/*vram_x*/;
        }
        else
        {
            texture.texture_x = 832/*vram_x*/;
        }
        texture.texture_y = 256/*vram_y*/;
        texture.bpp = BPP_8/*bpp*/;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at( 0, 0 );
        Ogre::Vector2 bt( 0, 0 );
        Ogre::Vector2 ct( 0, 0 );
        Ogre::Vector2 dt( 0, 0 );

        u16 vertex1_uv = file->GetU16LE( pointer_to_mesh_data + 0x8 );
        at.x = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        at.y = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex2_uv = file->GetU16LE( pointer_to_mesh_data + 0xa );
        bt.x = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        bt.y = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex3_uv = file->GetU16LE( pointer_to_mesh_data + 0xc );
        ct.x = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        ct.y = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex4_uv = file->GetU16LE( pointer_to_mesh_data + 0xe );
        dt.x = ( file->GetU8( pointer_to_texture_data + vertex4_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        dt.y = ( file->GetU8( pointer_to_texture_data + vertex4_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = d.x; *pPos++ = d.y; *pPos++ = d.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = bt.x; *tPos++ = bt.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = dt.x; *tPos++ = dt.y;

        Ogre::ColourValue colour = Ogre::ColourValue( file->GetU8( pointer_to_mesh_data + 0x10 ) / 256.0f,
                                                      file->GetU8( pointer_to_mesh_data + 0x11 ) / 256.0f,
                                                      file->GetU8( pointer_to_mesh_data + 0x12 ) / 256.0f,
                                                      1.0f );

        rs->convertColourValue( colour, colours + cur_index + 0 );
        rs->convertColourValue( colour, colours + cur_index + 1 );
        rs->convertColourValue( colour, colours + cur_index + 2 );
        rs->convertColourValue( colour, colours + cur_index + 3 );
        rs->convertColourValue( colour, colours + cur_index + 4 );
        rs->convertColourValue( colour, colours + cur_index + 5 );

        idata[ cur_index + 0 ] = cur_index + 0;
        idata[ cur_index + 1 ] = cur_index + 1;
        idata[ cur_index + 2 ] = cur_index + 2;
        idata[ cur_index + 3 ] = cur_index + 3;
        idata[ cur_index + 4 ] = cur_index + 4;
        idata[ cur_index + 5 ] = cur_index + 5;

        Ogre::VertexBoneAssignment vba;
        vba.weight = 1.0f;

        vba.vertexIndex = cur_index + 0;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_a * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 1;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 2;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 3;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 4;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 5;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_d * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );



        cur_index += 6;
        pointer_to_mesh_data += 0x18;
    }



    for( int i = 0; i < number_of_monochrome_textured_triangles; ++i )
    {
        int index_a = file->GetU16LE( pointer_to_mesh_data + 0x0 );
        int index_b = file->GetU16LE( pointer_to_mesh_data + 0x2 );
        int index_c = file->GetU16LE( pointer_to_mesh_data + 0x4 );

        Ogre::Vector3 a( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_a * 0x8 + 0x4 ) );
        Ogre::Vector3 b( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_b * 0x8 + 0x4 ) );
        Ogre::Vector3 c( ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x0 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x2 ),
                         ( s16 )file->GetU16LE( pointer_to_vertex_data + index_c * 0x8 + 0x4 ) );
        a /= 512;
        b /= 512;
        c /= 512;

        int image_id = file->GetU8( pointer_to_mesh_data + 0x6 );
        u16 blend = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 0 );
        u16 clut = file12->GetU16LE( offset_to_clut_tex + image_id * 4 + 2 );
        LOGGER->Log( "image_id = \"" + HexToString( image_id, 2, '0' ) + "\", clut = \"" + HexToString( clut, 4, '0' ) + "\", blend = \"" + HexToString( blend, 4, '0' ) + "\".\n" );
/*
        int clut_x = (clut & 0x003f) << 3;
        int clut_y = (clut & 0xffc0) >> 6;
        int bpp    = (tpage >> 0x7) & 0x3;
        int vram_x = (tpage & 0xf) * 64;
        int vram_y = ((tpage & 0x10) >> 4) * 256;
*/

        TexForGen texture;
        texture.palette_x = 128/*clut_x*/;
        texture.palette_y = 224/*clut_y*/;
        if( image_id == 1 )
        {
            texture.texture_x = 768/*vram_x*/;
        }
        else
        {
            texture.texture_x = 832/*vram_x*/;
        }
        texture.texture_y = 256/*vram_y*/;
        texture.bpp = BPP_8/*bpp*/;
        AddTexture( texture, mesh_data, textures, LOGGER );

        Ogre::Vector2 at( 0, 0 );
        Ogre::Vector2 bt( 0, 0 );
        Ogre::Vector2 ct( 0, 0 );

        u16 vertex1_uv = file->GetU16LE( pointer_to_mesh_data + 0xc );
        at.x = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        at.y = ( file->GetU8( pointer_to_texture_data + vertex1_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex2_uv = file->GetU16LE( pointer_to_mesh_data + 0xe );
        bt.x = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        bt.y = ( file->GetU8( pointer_to_texture_data + vertex2_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        u16 vertex3_uv = file->GetU16LE( pointer_to_mesh_data + 0x10 );
        ct.x = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x0 ) + texture.start_x ) / ( float )mesh_data.tex_width;
        ct.y = ( file->GetU8( pointer_to_texture_data + vertex3_uv * 2 + 0x1 ) + texture.start_y ) / ( float )mesh_data.tex_height;

        *pPos++ = a.x; *pPos++ = a.y; *pPos++ = a.z;
        *pPos++ = c.x; *pPos++ = c.y; *pPos++ = c.z;
        *pPos++ = b.x; *pPos++ = b.y; *pPos++ = b.z;

        *tPos++ = at.x; *tPos++ = at.y;
        *tPos++ = ct.x; *tPos++ = ct.y;
        *tPos++ = bt.x; *tPos++ = bt.y;

        Ogre::ColourValue colour = Ogre::ColourValue( file->GetU8( pointer_to_mesh_data + 0x08 ) / 256.0f,
                                                      file->GetU8( pointer_to_mesh_data + 0x09 ) / 256.0f,
                                                      file->GetU8( pointer_to_mesh_data + 0x0a ) / 256.0f,
                                                      1.0f );

        rs->convertColourValue( colour, colours + cur_index + 0 );
        rs->convertColourValue( colour, colours + cur_index + 1 );
        rs->convertColourValue( colour, colours + cur_index + 2 );

        idata[ cur_index + 0 ] = cur_index + 0;
        idata[ cur_index + 1 ] = cur_index + 1;
        idata[ cur_index + 2 ] = cur_index + 2;

        Ogre::VertexBoneAssignment vba;
        vba.weight = 1.0f;

        vba.vertexIndex = cur_index + 0;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_a * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 1;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_c * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );
        vba.vertexIndex = cur_index + 2;
        vba.boneIndex = file->GetU8( pointer_to_vertex_data + index_b * 0x8 + 0x6 ) * 2 + 3;
        sub_mesh->addBoneAssignment( vba );

        cur_index += 3;
        pointer_to_mesh_data += 0x14;
    }



    vbuf0->unlock();
    vbuf1->writeData( 0, vbuf1->getSizeInBytes(), colours, true );
    vbuf2->unlock();

    sub_mesh->indexData->indexBuffer->unlock();
    // Optimize index data
    sub_mesh->indexData->optimiseVertexCacheTriList();



    delete file12;
}