/* ================ idLight::WriteToSnapshot ================ */ void idLight::WriteToSnapshot( idBitMsgDelta &msg ) const { GetPhysics()->WriteToSnapshot( msg ); WriteBindToSnapshot( msg ); msg.WriteByte( currentLevel ); msg.WriteLong( PackColor( baseColor ) ); // msg.WriteBits( lightParent.GetEntityNum(), GENTITYNUM_BITS ); /* // only helps prediction msg.WriteLong( PackColor( fadeFrom ) ); msg.WriteLong( PackColor( fadeTo ) ); msg.WriteLong( fadeStart ); msg.WriteLong( fadeEnd ); */ // FIXME: send renderLight.shader msg.WriteFloat( renderLight.lightRadius[0], 5, 10 ); msg.WriteFloat( renderLight.lightRadius[1], 5, 10 ); msg.WriteFloat( renderLight.lightRadius[2], 5, 10 ); msg.WriteLong( PackColor( idVec4( renderLight.shaderParms[SHADERPARM_RED], renderLight.shaderParms[SHADERPARM_GREEN], renderLight.shaderParms[SHADERPARM_BLUE], renderLight.shaderParms[SHADERPARM_ALPHA] ) ) ); msg.WriteFloat( renderLight.shaderParms[SHADERPARM_TIMESCALE], 5, 10 ); msg.WriteLong( renderLight.shaderParms[SHADERPARM_TIMEOFFSET] ); //msg.WriteByte( renderLight.shaderParms[SHADERPARM_DIVERSITY] ); msg.WriteShort( renderLight.shaderParms[SHADERPARM_MODE] ); WriteColorToSnapshot( msg ); }
/* ============= idRenderSystemLocal::SetColor ============= */ void idRenderSystemLocal::SetColor( const idVec4& rgba ) { currentColorNativeBytesOrder = LittleLong( PackColor( rgba ) ); }
/* ================ idBrittleFracture::UpdateRenderEntity ================ */ bool idBrittleFracture::UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) const { int i, j, k, n, msec, numTris, numDecalTris; float fade; dword packedColor; srfTriangles_t *tris, *decalTris; modelSurface_t surface; idDrawVert *v; idPlane plane; idMat3 tangents; // this may be triggered by a model trace or other non-view related source, // to which we should look like an empty model if ( !renderView ) { return false; } // don't regenerate it if it is current if ( lastRenderEntityUpdate == gameLocal.time || !changed ) { return false; } lastRenderEntityUpdate = gameLocal.time; changed = false; numTris = 0; numDecalTris = 0; for ( i = 0; i < shards.Num(); i++ ) { n = shards[i]->winding.GetNumPoints(); if ( n > 2 ) { numTris += n - 2; } for ( k = 0; k < shards[i]->decals.Num(); k++ ) { n = shards[i]->decals[k]->GetNumPoints(); if ( n > 2 ) { numDecalTris += n - 2; } } } // FIXME: re-use model surfaces renderEntity->hModel->InitEmpty( brittleFracture_SnapshotName ); // allocate triangle surfaces for the fractures and decals tris = renderEntity->hModel->AllocSurfaceTriangles( numTris * 3, material->ShouldCreateBackSides() ? numTris * 6 : numTris * 3 ); decalTris = renderEntity->hModel->AllocSurfaceTriangles( numDecalTris * 3, decalMaterial->ShouldCreateBackSides() ? numDecalTris * 6 : numDecalTris * 3 ); for ( i = 0; i < shards.Num(); i++ ) { const idVec3 &origin = shards[i]->clipModel->GetOrigin(); const idMat3 &axis = shards[i]->clipModel->GetAxis(); fade = 1.0f; if ( shards[i]->droppedTime >= 0 ) { msec = gameLocal.time - shards[i]->droppedTime - SHARD_FADE_START; if ( msec > 0 ) { fade = 1.0f - (float) msec / ( SHARD_ALIVE_TIME - SHARD_FADE_START ); } } packedColor = PackColor( idVec4( renderEntity->shaderParms[ SHADERPARM_RED ] * fade, renderEntity->shaderParms[ SHADERPARM_GREEN ] * fade, renderEntity->shaderParms[ SHADERPARM_BLUE ] * fade, fade ) ); const idWinding &winding = shards[i]->winding; winding.GetPlane( plane ); tangents = ( plane.Normal() * axis ).ToMat3(); for ( j = 2; j < winding.GetNumPoints(); j++ ) { v = &tris->verts[tris->numVerts++]; v->Clear(); v->xyz = origin + winding[0].ToVec3() * axis; v->st[0] = winding[0].s; v->st[1] = winding[0].t; v->normal = tangents[0]; v->tangents[0] = tangents[1]; v->tangents[1] = tangents[2]; v->SetColor( packedColor ); v = &tris->verts[tris->numVerts++]; v->Clear(); v->xyz = origin + winding[j-1].ToVec3() * axis; v->st[0] = winding[j-1].s; v->st[1] = winding[j-1].t; v->normal = tangents[0]; v->tangents[0] = tangents[1]; v->tangents[1] = tangents[2]; v->SetColor( packedColor ); v = &tris->verts[tris->numVerts++]; v->Clear(); v->xyz = origin + winding[j].ToVec3() * axis; v->st[0] = winding[j].s; v->st[1] = winding[j].t; v->normal = tangents[0]; v->tangents[0] = tangents[1]; v->tangents[1] = tangents[2]; v->SetColor( packedColor ); tris->indexes[tris->numIndexes++] = tris->numVerts - 3; tris->indexes[tris->numIndexes++] = tris->numVerts - 2; tris->indexes[tris->numIndexes++] = tris->numVerts - 1; if ( material->ShouldCreateBackSides() ) { tris->indexes[tris->numIndexes++] = tris->numVerts - 2; tris->indexes[tris->numIndexes++] = tris->numVerts - 3; tris->indexes[tris->numIndexes++] = tris->numVerts - 1; } } for ( k = 0; k < shards[i]->decals.Num(); k++ ) { const idWinding &decalWinding = *shards[i]->decals[k]; for ( j = 2; j < decalWinding.GetNumPoints(); j++ ) { v = &decalTris->verts[decalTris->numVerts++]; v->Clear(); v->xyz = origin + decalWinding[0].ToVec3() * axis; v->st[0] = decalWinding[0].s; v->st[1] = decalWinding[0].t; v->normal = tangents[0]; v->tangents[0] = tangents[1]; v->tangents[1] = tangents[2]; v->SetColor( packedColor ); v = &decalTris->verts[decalTris->numVerts++]; v->Clear(); v->xyz = origin + decalWinding[j-1].ToVec3() * axis; v->st[0] = decalWinding[j-1].s; v->st[1] = decalWinding[j-1].t; v->normal = tangents[0]; v->tangents[0] = tangents[1]; v->tangents[1] = tangents[2]; v->SetColor( packedColor ); v = &decalTris->verts[decalTris->numVerts++]; v->Clear(); v->xyz = origin + decalWinding[j].ToVec3() * axis; v->st[0] = decalWinding[j].s; v->st[1] = decalWinding[j].t; v->normal = tangents[0]; v->tangents[0] = tangents[1]; v->tangents[1] = tangents[2]; v->SetColor( packedColor ); decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 3; decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 2; decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 1; if ( decalMaterial->ShouldCreateBackSides() ) { decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 2; decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 3; decalTris->indexes[decalTris->numIndexes++] = decalTris->numVerts - 1; } } } } tris->tangentsCalculated = true; decalTris->tangentsCalculated = true; SIMDProcessor->MinMax( tris->bounds[0], tris->bounds[1], tris->verts, tris->numVerts ); SIMDProcessor->MinMax( decalTris->bounds[0], decalTris->bounds[1], decalTris->verts, decalTris->numVerts ); memset( &surface, 0, sizeof( surface ) ); surface.shader = material; surface.id = 0; surface.geometry = tris; renderEntity->hModel->AddSurface( surface ); memset( &surface, 0, sizeof( surface ) ); surface.shader = decalMaterial; surface.id = 1; surface.geometry = decalTris; renderEntity->hModel->AddSurface( surface ); return true; }
static LUA_DECLARE( drawBitmap ) { Bitmap *src; double x, y; double width, height; eDrawOpType drawOp; LUA_ARGS_BEGIN; argStream.ReadClass( src, LUACLASS_BITMAP ); argStream.ReadNumber( x ); argStream.ReadNumber( y ); argStream.ReadNumber( width, 0 ); argStream.ReadNumber( height, 0 ); argStream.ReadEnumString( drawOp, DRAWOP_MODULATE ); LUA_ARGS_END; // Establish draw operation scales. double xScale, yScale; if ( width == 0 ) { xScale = 1.0f; width = src->GetWidth(); } else xScale = width / (float)src->GetWidth(); if ( height == 0 ) { yScale = 1.0f; height = src->GetHeight(); } else yScale = height / (float)src->GetHeight(); // For now; later we may support flipping of images! LUA_CHECK( width > 0 && height > 0 ); Bitmap *map = (Bitmap*)lua_getmethodtrans( L ); // Cache the bitmap types Bitmap::eDataType srcDataType = src->m_dataType; Bitmap::eDataType dstDataType = map->m_dataType; // We cannot draw us to ourselves. LUA_CHECK( map != src ); unsigned int srcWidth = src->GetWidth(); unsigned int srcHeight = src->GetHeight(); unsigned int dstWidth = map->GetWidth(); unsigned int dstHeight = map->GetHeight(); // Make sure the draw operations target valid zones double endTargetX = x + width; double endTargetY = y + height; // Is the draw zone clipping out of the target zone? // Do not render then. LUA_CHECK( endTargetX > 0 && endTargetY > 0 && x < dstWidth && y < dstHeight ); // Draw it! unsigned int ySrcPos = 0; for ( double yPos = y; yPos < endTargetY; yPos += yScale, ySrcPos++ ) { unsigned int xSrcPos = 0; for ( double xPos = x; xPos < endTargetX; xPos += xScale, xSrcPos++ ) { unsigned int pixelDstX = (unsigned int)xPos; unsigned int pixelDstY = (unsigned int)yPos; unsigned int pixelSrcX = (unsigned int)xSrcPos; unsigned int pixelSrcY = (unsigned int)ySrcPos; // Unpack the colors double srcRed; double srcGreen; double srcBlue; double srcAlpha; UnpackColor( src->m_data, pixelSrcX, pixelSrcY, srcWidth, srcDataType, srcRed, srcGreen, srcBlue, srcAlpha ); double dstRed; double dstGreen; double dstBlue; double dstAlpha; UnpackColor( map->m_data, pixelDstX, pixelDstY, dstWidth, dstDataType, dstRed, dstGreen, dstBlue, dstAlpha ); // TODO: allow blendfactor changing. // Currently it is SRC_ALPHA, ONE_MINUS_SRC_ALPHA double resRed; double resGreen; double resBlue; double resAlpha; switch( drawOp ) { case DRAWOP_MODULATE: // Alpha blend the bitmaps together resRed = SharedUtil::Min <double> ( 1.0f, ( srcRed * srcAlpha ) + ( dstRed * (1 - srcAlpha) ) ); resGreen = SharedUtil::Min <double> ( 1.0f, ( srcGreen * srcAlpha ) + ( dstGreen * (1 - srcAlpha) ) ); resBlue = SharedUtil::Min <double> ( 1.0f, ( srcBlue * srcAlpha ) + ( dstBlue * (1 - srcAlpha) ) ); resAlpha = SharedUtil::Min <double> ( 1.0f, ( srcAlpha * srcAlpha ) + ( dstAlpha * (1 - srcAlpha) ) ); break; case DRAWOP_WRITE: // We just copy data from bitmap src to dst resRed = srcRed; resGreen = srcGreen; resBlue = srcBlue; resAlpha = srcAlpha; break; default: // Unknown operation. resRed = 1.0f; resGreen = 1.0f; resBlue = 1.0f; resAlpha = 1.0f; break; } // Pack the colors again. PackColor( map->m_data, pixelDstX, pixelDstY, dstWidth, dstDataType, resRed, resGreen, resBlue, resAlpha ); } } lua_pushboolean( L, true ); return 1; }