mirror of
https://github.com/sigonasr2/hamster.git
synced 2025-04-21 07:39:40 -05:00
Lots of micro-optimizations and depth fixes for emscripten.
This commit is contained in:
parent
14296e2e63
commit
599114ca02
@ -72,9 +72,12 @@ void Checkpoint::DrawCheckpoints(TransformedView&tv){
|
|||||||
const Animate2D::Frame&frame{checkpoint.animation.GetFrame(checkpoint.internal_animState)};
|
const Animate2D::Frame&frame{checkpoint.animation.GetFrame(checkpoint.internal_animState)};
|
||||||
if(checkpoint.animation.GetState(checkpoint.internal_animState)!=AnimationState::DEFAULT){
|
if(checkpoint.animation.GetState(checkpoint.internal_animState)!=AnimationState::DEFAULT){
|
||||||
HamsterGame::Game().SetDecalMode(DecalMode::ADDITIVE);
|
HamsterGame::Game().SetDecalMode(DecalMode::ADDITIVE);
|
||||||
|
HamsterGame::Game().SetZ(0.007f);
|
||||||
tv.DrawPartialRotatedDecal(checkpoint.pos,frame.GetSourceImage()->Decal(),0.f,frame.GetSourceRect().size/2,frame.GetSourceRect().pos,frame.GetSourceRect().size,{1.1f,1.1f});
|
tv.DrawPartialRotatedDecal(checkpoint.pos,frame.GetSourceImage()->Decal(),0.f,frame.GetSourceRect().size/2,frame.GetSourceRect().pos,frame.GetSourceRect().size,{1.1f,1.1f});
|
||||||
|
HamsterGame::Game().SetZ(0.009f);
|
||||||
HamsterGame::Game().SetDecalMode(DecalMode::NORMAL);
|
HamsterGame::Game().SetDecalMode(DecalMode::NORMAL);
|
||||||
}
|
}
|
||||||
|
HamsterGame::Game().SetZ(0.009f);
|
||||||
tv.DrawPartialRotatedDecal(checkpoint.pos,frame.GetSourceImage()->Decal(),0.f,frame.GetSourceRect().size/2,frame.GetSourceRect().pos,frame.GetSourceRect().size);
|
tv.DrawPartialRotatedDecal(checkpoint.pos,frame.GetSourceImage()->Decal(),0.f,frame.GetSourceRect().size/2,frame.GetSourceRect().pos,frame.GetSourceRect().size);
|
||||||
geom2d::line<float>playerToCheckpointLine{geom2d::line<float>(Hamster::GetPlayer().GetPos(),checkpoint.pos)};
|
geom2d::line<float>playerToCheckpointLine{geom2d::line<float>(Hamster::GetPlayer().GetPos(),checkpoint.pos)};
|
||||||
|
|
||||||
|
@ -73,12 +73,13 @@ void FloatingText::Draw(TransformedView&tv){
|
|||||||
|
|
||||||
uint8_t alpha{uint8_t(util::lerp(0U,255U,lifetime/4.f))};
|
uint8_t alpha{uint8_t(util::lerp(0U,255U,lifetime/4.f))};
|
||||||
|
|
||||||
|
HamsterGame::Game().SetZ(0.014f);
|
||||||
for(int y:std::ranges::iota_view(-1,2)){
|
for(int y:std::ranges::iota_view(-1,2)){
|
||||||
for(int x:std::ranges::iota_view(-1,2)){
|
for(int x:std::ranges::iota_view(-1,2)){
|
||||||
tv.DrawRotatedStringDecal(pos+vi2d{x,y},text,0.f,strSize/2,{0,0,0,alpha},scale);
|
tv.DrawRotatedStringDecal(pos+vi2d{x,y},text,0.f,strSize/2,{0,0,0,alpha},scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HamsterGame::Game().SetZ(0.01f);
|
HamsterGame::Game().SetZ(0.015f);
|
||||||
tv.DrawRotatedStringDecal(pos,text,0.f,strSize/2,{currentCol.r,currentCol.g,currentCol.b,uint8_t(currentCol.a*(alpha/255.f))},scale);
|
tv.DrawRotatedStringDecal(pos,text,0.f,strSize/2,{currentCol.r,currentCol.g,currentCol.b,uint8_t(currentCol.a*(alpha/255.f))},scale);
|
||||||
HamsterGame::Game().SetZ(0.f);
|
HamsterGame::Game().SetZ(0.f);
|
||||||
}
|
}
|
||||||
|
@ -67,10 +67,18 @@ void Hamster::UpdateHamsters(const float fElapsedTime){
|
|||||||
h.HandleCollision();
|
h.HandleCollision();
|
||||||
switch(h.state){
|
switch(h.state){
|
||||||
case NORMAL:{
|
case NORMAL:{
|
||||||
if(h.bumpTimer<=0.f&&!h.CollectedAllCheckpoints()){
|
if(h.CanMove()){
|
||||||
if(h.IsPlayerControlled){
|
if(h.IsPlayerControlled){
|
||||||
h.HandlePlayerControls();
|
h.HandlePlayerControls();
|
||||||
}else{
|
}else{
|
||||||
|
if(!h.hamsterJet.has_value()){
|
||||||
|
h.ObtainPowerup(Powerup::JET);
|
||||||
|
Powerup tempJetPowerup{{},Powerup::JET};
|
||||||
|
tempJetPowerup.OnPowerupObtain(h);
|
||||||
|
h.SetState(FLYING);
|
||||||
|
h.lastSafeLocation.reset();
|
||||||
|
h.hamsterJet.emplace(h);
|
||||||
|
}
|
||||||
//TODO: NPC controls.
|
//TODO: NPC controls.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,17 +189,17 @@ void Hamster::DrawHamsters(TransformedView&tv){
|
|||||||
yHopAmt=-abs(sin(geom2d::pi*(animCycle/0.35f)))*12.f;
|
yHopAmt=-abs(sin(geom2d::pi*(animCycle/0.35f)))*12.f;
|
||||||
}
|
}
|
||||||
if(h.hamsterJet.has_value())h.hamsterJet.value().Draw();
|
if(h.hamsterJet.has_value())h.hamsterJet.value().Draw();
|
||||||
HamsterGame::Game().SetZ(h.z);
|
HamsterGame::Game().SetZ(h.z+0.02f);
|
||||||
tv.DrawRotatedDecal(h.pos+vf2d{0.f,h.drawingOffsetY},HamsterGame::GetGFX("shadow.png").Decal(),0.f,HamsterGame::GetGFX("shadow.png").Sprite()->Size()/2);
|
tv.DrawRotatedDecal(h.pos+vf2d{0.f,h.drawingOffsetY},HamsterGame::GetGFX("shadow.png").Decal(),0.f,HamsterGame::GetGFX("shadow.png").Sprite()->Size()/2);
|
||||||
HamsterGame::Game().SetZ(h.z+0.005f);
|
HamsterGame::Game().SetZ(h.z+0.025f);
|
||||||
tv.DrawPartialRotatedDecal(h.pos+vf2d{0.f,h.drawingOffsetY+yHopAmt},img.GetSourceImage()->Decal(),0.f,img.GetSourceRect().size/2,img.GetSourceRect().pos,img.GetSourceRect().size,vf2d{1.f,1.f}*h.imgScale*vf2d{facingXScale,1.f},PixelLerp(h.shrinkEffectColor,WHITE,h.imgScale));
|
tv.DrawPartialRotatedDecal(h.pos+vf2d{0.f,h.drawingOffsetY+yHopAmt},img.GetSourceImage()->Decal(),0.f,img.GetSourceRect().size/2,img.GetSourceRect().pos,img.GetSourceRect().size,vf2d{1.f,1.f}*h.imgScale*vf2d{facingXScale,1.f},PixelLerp(h.shrinkEffectColor,WHITE,h.imgScale));
|
||||||
HamsterGame::Game().SetZ(h.z);
|
HamsterGame::Game().SetZ(0.f);
|
||||||
}else{
|
}else{
|
||||||
if(h.hamsterJet.has_value())h.hamsterJet.value().Draw();
|
if(h.hamsterJet.has_value())h.hamsterJet.value().Draw();
|
||||||
HamsterGame::Game().SetZ(h.z);
|
HamsterGame::Game().SetZ(h.z+0.02f);
|
||||||
if(h.HasPowerup(Powerup::WHEEL))tv.DrawPartialRotatedDecal(h.pos+vf2d{0.f,h.drawingOffsetY},wheelBottomImg.GetSourceImage()->Decal(),h.rot,wheelBottomImg.GetSourceRect().size/2,wheelBottomImg.GetSourceRect().pos,wheelBottomImg.GetSourceRect().size,vf2d{1.f,1.f}*h.imgScale,PixelLerp(h.shrinkEffectColor,WHITE,h.imgScale));
|
if(h.HasPowerup(Powerup::WHEEL))tv.DrawPartialRotatedDecal(h.pos+vf2d{0.f,h.drawingOffsetY},wheelBottomImg.GetSourceImage()->Decal(),h.rot,wheelBottomImg.GetSourceRect().size/2,wheelBottomImg.GetSourceRect().pos,wheelBottomImg.GetSourceRect().size,vf2d{1.f,1.f}*h.imgScale,PixelLerp(h.shrinkEffectColor,WHITE,h.imgScale));
|
||||||
tv.DrawPartialRotatedDecal(h.pos+vf2d{0.f,h.drawingOffsetY},img.GetSourceImage()->Decal(),h.rot,img.GetSourceRect().size/2,img.GetSourceRect().pos,img.GetSourceRect().size,vf2d{1.f,1.f}*h.imgScale,PixelLerp(h.shrinkEffectColor,WHITE,h.imgScale));
|
tv.DrawPartialRotatedDecal(h.pos+vf2d{0.f,h.drawingOffsetY},img.GetSourceImage()->Decal(),h.rot,img.GetSourceRect().size/2,img.GetSourceRect().pos,img.GetSourceRect().size,vf2d{1.f,1.f}*h.imgScale,PixelLerp(h.shrinkEffectColor,WHITE,h.imgScale));
|
||||||
HamsterGame::Game().SetZ(h.z+0.01f);
|
HamsterGame::Game().SetZ(h.z+0.025f);
|
||||||
if(h.HasPowerup(Powerup::WHEEL))tv.DrawPartialRotatedDecal(h.pos+vf2d{0.f,h.drawingOffsetY},wheelTopImg.GetSourceImage()->Decal(),h.rot,wheelTopImg.GetSourceRect().size/2,wheelTopImg.GetSourceRect().pos,wheelTopImg.GetSourceRect().size,vf2d{1.f,1.f}*h.imgScale,PixelLerp(h.shrinkEffectColor,{255,255,255,192},h.imgScale));
|
if(h.HasPowerup(Powerup::WHEEL))tv.DrawPartialRotatedDecal(h.pos+vf2d{0.f,h.drawingOffsetY},wheelTopImg.GetSourceImage()->Decal(),h.rot,wheelTopImg.GetSourceRect().size/2,wheelTopImg.GetSourceRect().pos,wheelTopImg.GetSourceRect().size,vf2d{1.f,1.f}*h.imgScale,PixelLerp(h.shrinkEffectColor,{255,255,255,192},h.imgScale));
|
||||||
HamsterGame::Game().SetZ(0.f);
|
HamsterGame::Game().SetZ(0.f);
|
||||||
}
|
}
|
||||||
@ -363,7 +371,7 @@ const float Hamster::GetRadius()const{
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Terrain::TerrainType Hamster::GetTerrainStandingOn()const{
|
const Terrain::TerrainType Hamster::GetTerrainStandingOn()const{
|
||||||
if(state==FLYING)return Terrain::ROCK;
|
if(FlyingInTheAir())return Terrain::ROCK;
|
||||||
return HamsterGame::Game().GetTerrainTypeAtPos(GetPos());
|
return HamsterGame::Game().GetTerrainTypeAtPos(GetPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,7 +389,7 @@ const float Hamster::GetTimeToMaxSpeed()const{
|
|||||||
else if(!HasPowerup(Powerup::SWAMP)&&GetTerrainStandingOn()==Terrain::SWAMP)finalTimeToMaxSpd*=1.25;
|
else if(!HasPowerup(Powerup::SWAMP)&&GetTerrainStandingOn()==Terrain::SWAMP)finalTimeToMaxSpd*=1.25;
|
||||||
if(hamsterJet.has_value()){
|
if(hamsterJet.has_value()){
|
||||||
if(hamsterJet.value().GetState()==HamsterJet::LANDING)finalTimeToMaxSpd*=2.f;
|
if(hamsterJet.value().GetState()==HamsterJet::LANDING)finalTimeToMaxSpd*=2.f;
|
||||||
else if(state==FLYING)finalTimeToMaxSpd*=3.f;
|
else if(FlyingInTheAir())finalTimeToMaxSpd*=3.f;
|
||||||
}
|
}
|
||||||
return finalTimeToMaxSpd;
|
return finalTimeToMaxSpd;
|
||||||
}
|
}
|
||||||
@ -417,7 +425,7 @@ const float Hamster::GetMaxSpeed()const{
|
|||||||
if(HasPowerup(Powerup::WHEEL))finalMaxSpd*=1.5f;
|
if(HasPowerup(Powerup::WHEEL))finalMaxSpd*=1.5f;
|
||||||
if(hamsterJet.has_value()){
|
if(hamsterJet.has_value()){
|
||||||
if(hamsterJet.value().GetState()==HamsterJet::LANDING)finalMaxSpd*=1.5f;
|
if(hamsterJet.value().GetState()==HamsterJet::LANDING)finalMaxSpd*=1.5f;
|
||||||
else if(state==FLYING)finalMaxSpd*=8.f;
|
else if(FlyingInTheAir())finalMaxSpd*=8.f;
|
||||||
}
|
}
|
||||||
return finalMaxSpd;
|
return finalMaxSpd;
|
||||||
}
|
}
|
||||||
@ -427,7 +435,7 @@ const float Hamster::GetFriction()const{
|
|||||||
else if(!HasPowerup(Powerup::SWAMP)&&GetTerrainStandingOn()==Terrain::SWAMP)finalFriction*=0.6f;
|
else if(!HasPowerup(Powerup::SWAMP)&&GetTerrainStandingOn()==Terrain::SWAMP)finalFriction*=0.6f;
|
||||||
if(hamsterJet.has_value()){
|
if(hamsterJet.has_value()){
|
||||||
if(hamsterJet.value().GetState()==HamsterJet::LANDING)finalFriction*=1.5f;
|
if(hamsterJet.value().GetState()==HamsterJet::LANDING)finalFriction*=1.5f;
|
||||||
else if(state==FLYING)finalFriction*=8.f;
|
else if(FlyingInTheAir())finalFriction*=8.f;
|
||||||
}
|
}
|
||||||
return finalFriction;
|
return finalFriction;
|
||||||
}
|
}
|
||||||
@ -589,3 +597,10 @@ const Hamster::HamsterState&Hamster::GetState()const{
|
|||||||
const bool Hamster::BurnedOrDrowned()const{
|
const bool Hamster::BurnedOrDrowned()const{
|
||||||
return GetState()==WAIT;
|
return GetState()==WAIT;
|
||||||
}
|
}
|
||||||
|
const bool Hamster::CanMove()const{
|
||||||
|
return bumpTimer<=0.f&&!CollectedAllCheckpoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool Hamster::FlyingInTheAir()const{
|
||||||
|
return GetState()==FLYING&&hamsterJet.value().GetZ()>0.5f&&GetZ()>0.5f;
|
||||||
|
}
|
@ -162,4 +162,6 @@ public:
|
|||||||
static const std::vector<Hamster>&GetHamsters();
|
static const std::vector<Hamster>&GetHamsters();
|
||||||
const HamsterState&GetState()const;
|
const HamsterState&GetState()const;
|
||||||
const bool BurnedOrDrowned()const;
|
const bool BurnedOrDrowned()const;
|
||||||
|
const bool CanMove()const;
|
||||||
|
const bool FlyingInTheAir()const;
|
||||||
};
|
};
|
@ -32,7 +32,7 @@ bool HamsterGame::OnUserCreate(){
|
|||||||
|
|
||||||
renderer.SetProjection(90.0f, (float)SCREEN_FRAME.size.x/(float)SCREEN_FRAME.size.y, 0.1f, 1000.0f, 0, SCREEN_FRAME.pos.y, 512, SCREEN_FRAME.size.y);
|
renderer.SetProjection(90.0f, (float)SCREEN_FRAME.size.x/(float)SCREEN_FRAME.size.y, 0.1f, 1000.0f, 0, SCREEN_FRAME.pos.y, 512, SCREEN_FRAME.size.y);
|
||||||
std::vector<vf2d>radarCircle;
|
std::vector<vf2d>radarCircle;
|
||||||
for(int i=360;i>=0;i-=4){
|
for(int i=360;i>=0;i-=20){
|
||||||
float angle=util::degToRad(float(i))-geom2d::pi/2;
|
float angle=util::degToRad(float(i))-geom2d::pi/2;
|
||||||
if(i==360){radarCircle.push_back(vf2d{cos(angle),sin(angle)}*43+vf2d{43,44});}
|
if(i==360){radarCircle.push_back(vf2d{cos(angle),sin(angle)}*43+vf2d{43,44});}
|
||||||
radarCircle.push_back(vf2d{cos(angle),sin(angle)}*43+vf2d{43,44});
|
radarCircle.push_back(vf2d{cos(angle),sin(angle)}*43+vf2d{43,44});
|
||||||
@ -184,11 +184,12 @@ void HamsterGame::UpdateGame(const float fElapsedTime){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void HamsterGame::DrawGame(){
|
void HamsterGame::DrawGame(){
|
||||||
SetZ(-0.001f);
|
SetZ(-0.01f);
|
||||||
tv.DrawPartialDecal({-3200,-3200},currentMap.value().GetData().GetMapData().MapSize*16+vf2d{6400,6400},animatedWaterTile.Decal(),{0,0},currentMap.value().GetData().GetMapData().MapSize*16+vf2d{6400,6400});
|
tv.DrawPartialDecal({-3200,-3200},currentMap.value().GetData().GetMapData().MapSize*16+vf2d{6400,6400},animatedWaterTile.Decal(),{0,0},currentMap.value().GetData().GetMapData().MapSize*16+vf2d{6400,6400});
|
||||||
SetZ(0.f);
|
SetZ(-0.0005f);
|
||||||
DrawLevelTiles();
|
DrawLevelTiles();
|
||||||
Checkpoint::DrawCheckpoints(tv);
|
Checkpoint::DrawCheckpoints(tv);
|
||||||
|
SetZ(0.01f);
|
||||||
Powerup::DrawPowerups(tv);
|
Powerup::DrawPowerups(tv);
|
||||||
Hamster::DrawHamsters(tv);
|
Hamster::DrawHamsters(tv);
|
||||||
SetZ(3.f);
|
SetZ(3.f);
|
||||||
@ -322,11 +323,9 @@ bool HamsterGame::OnUserUpdate(float fElapsedTime){
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Renderable&HamsterGame::GetGFX(const std::string&img){
|
const Renderable&HamsterGame::GetGFX(const std::string&img){
|
||||||
if(!GFX.count(img))throw std::runtime_error{std::format("Image {} does not exist!",img)};
|
|
||||||
return GFX[img];
|
return GFX[img];
|
||||||
}
|
}
|
||||||
const Animate2D::Animation<AnimationState::AnimationState>&HamsterGame::GetAnimations(const std::string&img){
|
const Animate2D::Animation<AnimationState::AnimationState>&HamsterGame::GetAnimations(const std::string&img){
|
||||||
if(!ANIMATIONS.count(img))throw std::runtime_error{std::format("Animations for {} does not exist!",img)};
|
|
||||||
return ANIMATIONS[img];
|
return ANIMATIONS[img];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,25 +432,38 @@ void HamsterGame::Apply3DTransform(std::vector<DecalInstance>&decals){
|
|||||||
|
|
||||||
renderer.SetTransform(matWorld);
|
renderer.SetTransform(matWorld);
|
||||||
|
|
||||||
|
float zIncrementer{0.f};
|
||||||
|
|
||||||
for(DecalInstance&decal:oldDecals){
|
for(DecalInstance&decal:oldDecals){
|
||||||
SetDecalMode(decal.mode);
|
SetDecalMode(decal.mode);
|
||||||
if(decal.transform==GFX3DTransform::NO_TRANSFORM)foregroundDecals.emplace_back(decal);
|
if(decal.transform==GFX3DTransform::NO_TRANSFORM){
|
||||||
|
foregroundDecals.emplace_back(decal);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
if(decal.points==3){
|
if(decal.points==3){
|
||||||
GFX3D::triangle tri{{{decal.pos[0].x,decal.pos[0].y,decal.z[0],1.f},{decal.pos[1].x,decal.pos[1].y,decal.z[1],1.f},{decal.pos[2].x,decal.pos[2].y,decal.z[2],1.f}},{{decal.uv[0].x,decal.uv[0].y,0.f},{decal.uv[1].x,decal.uv[1].y,0.f},{decal.uv[2].x,decal.uv[2].y,0.f}},{decal.tint[0],decal.tint[1],decal.tint[2]}};
|
GFX3D::triangle tri{{{decal.pos[0].x,decal.pos[0].y,decal.z[0],1.f},{decal.pos[1].x,decal.pos[1].y,decal.z[1],1.f},{decal.pos[2].x,decal.pos[2].y,decal.z[2],1.f}},{{decal.uv[0].x,decal.uv[0].y,0.f},{decal.uv[1].x,decal.uv[1].y,0.f},{decal.uv[2].x,decal.uv[2].y,0.f}},{decal.tint[0],decal.tint[1],decal.tint[2]}};
|
||||||
|
tri.p[0].z+=zIncrementer;
|
||||||
|
tri.p[1].z+=zIncrementer;
|
||||||
|
tri.p[2].z+=zIncrementer;
|
||||||
renderer.Render({tri},decal.decal,GFX3D::RENDER_TEXTURED|GFX3D::RENDER_DEPTH);
|
renderer.Render({tri},decal.decal,GFX3D::RENDER_TEXTURED|GFX3D::RENDER_DEPTH);
|
||||||
if(decal.z[0]>0.1f||decal.z[1]>0.1f||decal.z[2]>0.1f){
|
if(decal.z[0]>0.1f||decal.z[1]>0.1f||decal.z[2]>0.1f){
|
||||||
tri.col[0]=tri.col[1]=tri.col[2]={0,0,0,uint8_t(util::lerp(0,160,(1/std::pow(decal.z[0]/10.f+1,4))))};
|
tri.col[0]=tri.col[1]=tri.col[2]={0,0,0,uint8_t(util::lerp(0,160,(1/std::pow(decal.z[0]/10.f+1,4))))};
|
||||||
tri.p[0].z=tri.p[1].z=tri.p[2].z=0.1f;
|
tri.p[0].z=tri.p[1].z=tri.p[2].z=0.1f+zIncrementer;
|
||||||
renderer.Render({tri},decal.decal,GFX3D::RENDER_TEXTURED|GFX3D::RENDER_DEPTH);
|
renderer.Render({tri},decal.decal,GFX3D::RENDER_TEXTURED|GFX3D::RENDER_DEPTH);
|
||||||
}
|
}
|
||||||
}else if(decal.points==4){
|
}else if(decal.points==4){
|
||||||
GFX3D::triangle tri{{{decal.pos[0].x,decal.pos[0].y,decal.z[0],1.f},{decal.pos[1].x,decal.pos[1].y,decal.z[1],1.f},{decal.pos[2].x,decal.pos[2].y,decal.z[2],1.f}},{{decal.uv[0].x,decal.uv[0].y,0.f},{decal.uv[1].x,decal.uv[1].y,0.f},{decal.uv[2].x,decal.uv[2].y,0.f}},{decal.tint[0],decal.tint[1],decal.tint[2]}};
|
GFX3D::triangle tri{{{decal.pos[0].x,decal.pos[0].y,decal.z[0],1.f},{decal.pos[1].x,decal.pos[1].y,decal.z[1],1.f},{decal.pos[2].x,decal.pos[2].y,decal.z[2],1.f}},{{decal.uv[0].x,decal.uv[0].y,0.f},{decal.uv[1].x,decal.uv[1].y,0.f},{decal.uv[2].x,decal.uv[2].y,0.f}},{decal.tint[0],decal.tint[1],decal.tint[2]}};
|
||||||
GFX3D::triangle tri2{{{decal.pos[0].x,decal.pos[0].y,decal.z[0],1.f},{decal.pos[2].x,decal.pos[2].y,decal.z[2],1.f},{decal.pos[3].x,decal.pos[3].y,decal.z[3],1.f}},{{decal.uv[0].x,decal.uv[0].y,0.f},{decal.uv[2].x,decal.uv[2].y,0.f},{decal.uv[3].x,decal.uv[3].y,0.f}},{decal.tint[0],decal.tint[2],decal.tint[3]}};
|
GFX3D::triangle tri2{{{decal.pos[0].x,decal.pos[0].y,decal.z[0],1.f},{decal.pos[2].x,decal.pos[2].y,decal.z[2],1.f},{decal.pos[3].x,decal.pos[3].y,decal.z[3],1.f}},{{decal.uv[0].x,decal.uv[0].y,0.f},{decal.uv[2].x,decal.uv[2].y,0.f},{decal.uv[3].x,decal.uv[3].y,0.f}},{decal.tint[0],decal.tint[2],decal.tint[3]}};
|
||||||
|
tri.p[0].z+=zIncrementer;
|
||||||
|
tri.p[1].z+=zIncrementer;
|
||||||
|
tri.p[2].z+=zIncrementer;
|
||||||
|
tri2.p[0].z+=zIncrementer;
|
||||||
|
tri2.p[1].z+=zIncrementer;
|
||||||
|
tri2.p[2].z+=zIncrementer;
|
||||||
renderer.Render({tri,tri2},decal.decal,GFX3D::RENDER_TEXTURED|GFX3D::RENDER_DEPTH);
|
renderer.Render({tri,tri2},decal.decal,GFX3D::RENDER_TEXTURED|GFX3D::RENDER_DEPTH);
|
||||||
if(decal.decal!=GetGFX("dot.png").Decal()&&(decal.z[0]>0.1f||decal.z[1]>0.1f||decal.z[2]>0.1f||decal.z[3]>0.1f)){
|
if(decal.decal!=GetGFX("dot.png").Decal()&&(decal.z[0]>0.1f||decal.z[1]>0.1f||decal.z[2]>0.1f||decal.z[3]>0.1f)){
|
||||||
tri.col[0]=tri.col[1]=tri.col[2]=tri2.col[0]=tri2.col[1]=tri2.col[2]={0,0,0,uint8_t(util::lerp(0,160,(1/std::pow(decal.z[0]/10.f+1,4))))};
|
tri.col[0]=tri.col[1]=tri.col[2]=tri2.col[0]=tri2.col[1]=tri2.col[2]={0,0,0,uint8_t(util::lerp(0,160,(1/std::pow(decal.z[0]/10.f+1,4))))};
|
||||||
tri.p[0].z=tri.p[1].z=tri.p[2].z=tri2.p[0].z=tri2.p[1].z=tri2.p[2].z=0.1f;
|
tri.p[0].z=tri.p[1].z=tri.p[2].z=tri2.p[0].z=tri2.p[1].z=tri2.p[2].z=0.1f+zIncrementer;
|
||||||
renderer.Render({tri,tri2},decal.decal,GFX3D::RENDER_TEXTURED|GFX3D::RENDER_DEPTH);
|
renderer.Render({tri,tri2},decal.decal,GFX3D::RENDER_TEXTURED|GFX3D::RENDER_DEPTH);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
@ -462,10 +474,13 @@ void HamsterGame::Apply3DTransform(std::vector<DecalInstance>&decals){
|
|||||||
if(decal.points%3!=0)throw std::runtime_error{std::format("WARNING! Number of decal structure points is not a multiple of 3! Points provided: {}. THIS SHOULD NOT BE HAPPENING!",decal.points)};
|
if(decal.points%3!=0)throw std::runtime_error{std::format("WARNING! Number of decal structure points is not a multiple of 3! Points provided: {}. THIS SHOULD NOT BE HAPPENING!",decal.points)};
|
||||||
for(int i{0};i<decal.points;i+=3){
|
for(int i{0};i<decal.points;i+=3){
|
||||||
GFX3D::triangle tri{{{decal.pos[i+0].x,decal.pos[i+0].y,decal.z[i+0],1.f},{decal.pos[i+1].x,decal.pos[i+1].y,decal.z[i+1],1.f},{decal.pos[i+2].x,decal.pos[i+2].y,decal.z[i+2],1.f}},{{decal.uv[i+0].x,decal.uv[i+0].y,0.f},{decal.uv[i+1].x,decal.uv[i+1].y,0.f},{decal.uv[i+2].x,decal.uv[i+2].y,0.f}},{decal.tint[i+0],decal.tint[i+1],decal.tint[i+2]}};
|
GFX3D::triangle tri{{{decal.pos[i+0].x,decal.pos[i+0].y,decal.z[i+0],1.f},{decal.pos[i+1].x,decal.pos[i+1].y,decal.z[i+1],1.f},{decal.pos[i+2].x,decal.pos[i+2].y,decal.z[i+2],1.f}},{{decal.uv[i+0].x,decal.uv[i+0].y,0.f},{decal.uv[i+1].x,decal.uv[i+1].y,0.f},{decal.uv[i+2].x,decal.uv[i+2].y,0.f}},{decal.tint[i+0],decal.tint[i+1],decal.tint[i+2]}};
|
||||||
|
tri.p[0].z+=zIncrementer;
|
||||||
|
tri.p[1].z+=zIncrementer;
|
||||||
|
tri.p[2].z+=zIncrementer;
|
||||||
tris.emplace_back(tri);
|
tris.emplace_back(tri);
|
||||||
if(decal.z[i+0]>0||decal.z[i+1]>0||decal.z[i+2]>0){
|
if(decal.z[i+0]>0.1f||decal.z[i+1]>0.1f||decal.z[i+2]>0.1f){
|
||||||
tri.col[0]=tri.col[1]=tri.col[2]={0,0,0,uint8_t(util::lerp(0,160,(1/std::pow(decal.z[0]/10.f+1,4))))};
|
tri.col[0]=tri.col[1]=tri.col[2]={0,0,0,uint8_t(util::lerp(0,160,(1/std::pow(decal.z[0]/10.f+1,4))))};
|
||||||
tri.p[0].z=tri.p[1].z=tri.p[2].z=0.1f;
|
tri.p[0].z=tri.p[1].z=tri.p[2].z=0.1f+zIncrementer;
|
||||||
shadowTris.emplace_back(tri);
|
shadowTris.emplace_back(tri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -475,6 +490,7 @@ void HamsterGame::Apply3DTransform(std::vector<DecalInstance>&decals){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetDecalMode(DecalMode::NORMAL);
|
SetDecalMode(DecalMode::NORMAL);
|
||||||
|
zIncrementer+=0.000001f;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(decals.begin(),decals.end(),[](const DecalInstance&d1,const DecalInstance&d2){return d1.z[0]>d2.z[0];});
|
std::sort(decals.begin(),decals.end(),[](const DecalInstance&d1,const DecalInstance&d2){return d1.z[0]>d2.z[0];});
|
||||||
@ -533,22 +549,27 @@ void HamsterGame::DrawRadar(){
|
|||||||
{HAMSTER,{{16.f*9,0.f},{16.f,16.f}}},
|
{HAMSTER,{{16.f*9,0.f},{16.f,16.f}}},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const auto DeferRenderingBasedOnPosition=[this,&icon](const vf2d&pos,const IconType powerupIcon,const uint8_t iconAlpha){
|
||||||
|
if(geom2d::intersects(geom2d::circle<float>{{43.f+5.f,44.f+8.f},43},geom2d::rect<float>{pos-vf2d{16.f,16.f},{32.f,32.f}}).size()>0)radar.DrawPartialRotatedDecal(pos,GetGFX("radaricons.png").Decal(),0.f,{8.f,8.f},icon.at(powerupIcon).pos,icon.at(powerupIcon).size,{1.f,1.f},{255,255,255,iconAlpha});
|
||||||
|
else if(geom2d::contains(geom2d::circle<float>{{43.f+5.f,44.f+8.f},43},geom2d::rect<float>{pos-vf2d{8.f,8.f},{16.f,16.f}}))DrawPartialRotatedDecal(pos+vf2d{5.f,8.f},GetGFX("radaricons.png").Decal(),0.f,{8.f,8.f},icon.at(powerupIcon).pos,icon.at(powerupIcon).size,{1.f,1.f},{255,255,255,iconAlpha});
|
||||||
|
};
|
||||||
|
|
||||||
for(const Powerup&powerup:Powerup::GetPowerups()){
|
for(const Powerup&powerup:Powerup::GetPowerups()){
|
||||||
IconType powerupIcon{IconType(int(powerup.GetType())+1)};
|
IconType powerupIcon{IconType(int(powerup.GetType())+1)};
|
||||||
uint8_t iconAlpha{255U};
|
uint8_t iconAlpha{255U};
|
||||||
if(Hamster::GetPlayer().HasPowerup(powerup.GetType()))iconAlpha=64U;
|
if(Hamster::GetPlayer().HasPowerup(powerup.GetType()))iconAlpha=64U;
|
||||||
radar.DrawPartialRotatedDecal(WorldToRadar(powerup.GetPos()),GetGFX("radaricons.png").Decal(),0.f,{8.f,8.f},icon.at(powerupIcon).pos,icon.at(powerupIcon).size,{1.f,1.f},{255,255,255,iconAlpha});
|
DeferRenderingBasedOnPosition(WorldToRadar(powerup.GetPos()),powerupIcon,iconAlpha);
|
||||||
}
|
}
|
||||||
for(const Checkpoint&cp:Checkpoint::GetCheckpoints()){
|
for(const Checkpoint&cp:Checkpoint::GetCheckpoints()){
|
||||||
uint8_t iconAlpha{255U};
|
uint8_t iconAlpha{255U};
|
||||||
if(Hamster::GetPlayer().HasCollectedCheckpoint(cp))iconAlpha=64U;
|
if(Hamster::GetPlayer().HasCollectedCheckpoint(cp))iconAlpha=64U;
|
||||||
radar.DrawPartialRotatedDecal(WorldToRadar(cp.GetPos()),GetGFX("radaricons.png").Decal(),0.f,{8.f,8.f},icon.at(CHECKPOINT).pos,icon.at(CHECKPOINT).size,{1.f,1.f},{255,255,255,iconAlpha});
|
DeferRenderingBasedOnPosition(WorldToRadar(cp.GetPos()),CHECKPOINT,iconAlpha);
|
||||||
}
|
}
|
||||||
for(const Hamster&h:Hamster::GetHamsters()){
|
for(const Hamster&h:Hamster::GetHamsters()){
|
||||||
if(&h==&Hamster::GetPlayer())continue;
|
if(&h==&Hamster::GetPlayer())continue;
|
||||||
uint8_t iconAlpha{255U};
|
uint8_t iconAlpha{255U};
|
||||||
if(h.BurnedOrDrowned())iconAlpha=64U;
|
if(h.BurnedOrDrowned())iconAlpha=64U;
|
||||||
radar.DrawPartialRotatedDecal(WorldToRadar(h.GetPos()),GetGFX("radaricons.png").Decal(),0.f,{8.f,8.f},icon.at(HAMSTER).pos,icon.at(HAMSTER).size,{1.f,1.f},{255,255,255,iconAlpha});
|
DeferRenderingBasedOnPosition(WorldToRadar(h.GetPos()),HAMSTER,iconAlpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,10 +52,14 @@ void HamsterJet::Update(const float fElapsedTime){
|
|||||||
lastTappedSpace+=fElapsedTime;
|
lastTappedSpace+=fElapsedTime;
|
||||||
switch(state){
|
switch(state){
|
||||||
case SWOOP_DOWN:{
|
case SWOOP_DOWN:{
|
||||||
HamsterGame::Game().SetZoom(1.5f);
|
if(hamster.IsPlayerControlled)HamsterGame::Game().SetZoom(1.5f);
|
||||||
z=util::lerp(0.f,3.f,std::pow(timer/3.f,2));
|
z=util::lerp(0.f,3.f,std::pow(timer/3.f,2));
|
||||||
vf2d originalPos{hamster.GetPos().x-128.f,hamster.GetPos().y+32.f};
|
vf2d originalPos{hamster.GetPos().x-128.f,hamster.GetPos().y+32.f};
|
||||||
if(timer<=0.4f){
|
if(timer<=0.4f){
|
||||||
|
if(!setHamsterOriginalPos){
|
||||||
|
setHamsterOriginalPos=true;
|
||||||
|
hamsterOriginalPos=hamster.GetPos();
|
||||||
|
}
|
||||||
hamster.SetPos(hamsterOriginalPos-vf2d{0.f,sin(float(geom2d::pi)*timer/0.4f)*8.f});
|
hamster.SetPos(hamsterOriginalPos-vf2d{0.f,sin(float(geom2d::pi)*timer/0.4f)*8.f});
|
||||||
hamster.SetZ(sin(float(geom2d::pi)*timer/0.4f)*0.2f);
|
hamster.SetZ(sin(float(geom2d::pi)*timer/0.4f)*0.2f);
|
||||||
jetState[TOP_LEFT]=jetState[BOTTOM_LEFT]=jetState[BOTTOM_RIGHT]=jetState[TOP_RIGHT]=OFF;
|
jetState[TOP_LEFT]=jetState[BOTTOM_LEFT]=jetState[BOTTOM_RIGHT]=jetState[TOP_RIGHT]=OFF;
|
||||||
@ -80,22 +84,29 @@ void HamsterJet::Update(const float fElapsedTime){
|
|||||||
hamster.SetZ(z+0.03f);
|
hamster.SetZ(z+0.03f);
|
||||||
if(timer<=0.f){
|
if(timer<=0.f){
|
||||||
state=HAMSTER_CONTROL;
|
state=HAMSTER_CONTROL;
|
||||||
HamsterGame::Game().SetZoom(0.6f);
|
if(hamster.IsPlayerControlled)HamsterGame::Game().SetZoom(0.6f);
|
||||||
easeInTimer=0.6f;
|
easeInTimer=0.6f;
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
case HAMSTER_CONTROL:{
|
case HAMSTER_CONTROL:{
|
||||||
easeInTimer=std::max(0.f,easeInTimer-fElapsedTime);
|
easeInTimer=std::max(0.f,easeInTimer-fElapsedTime);
|
||||||
jetState[TOP_LEFT]=jetState[BOTTOM_LEFT]=jetState[BOTTOM_RIGHT]=jetState[TOP_RIGHT]=OFF;
|
jetState[TOP_LEFT]=jetState[BOTTOM_LEFT]=jetState[BOTTOM_RIGHT]=jetState[TOP_RIGHT]=OFF;
|
||||||
HandleJetControls();
|
if(hamster.CanMove()){
|
||||||
|
if(hamster.IsPlayerControlled)HandleJetControls();
|
||||||
|
else{
|
||||||
|
//TODO: AI controls here!
|
||||||
|
}
|
||||||
|
}
|
||||||
}break;
|
}break;
|
||||||
case LANDING:{
|
case LANDING:{
|
||||||
easeInTimer=std::min(0.6f,easeInTimer+fElapsedTime);
|
easeInTimer=std::min(0.6f,easeInTimer+fElapsedTime);
|
||||||
jetState[TOP_LEFT]=jetState[BOTTOM_LEFT]=jetState[BOTTOM_RIGHT]=jetState[TOP_RIGHT]=OFF;
|
jetState[TOP_LEFT]=jetState[BOTTOM_LEFT]=jetState[BOTTOM_RIGHT]=jetState[TOP_RIGHT]=OFF;
|
||||||
|
if(hamster.CanMove()){
|
||||||
if(hamster.IsPlayerControlled)HandleJetControls();
|
if(hamster.IsPlayerControlled)HandleJetControls();
|
||||||
else{
|
else{
|
||||||
//TODO: AI controls here!
|
//TODO: AI controls here!
|
||||||
}
|
}
|
||||||
|
}
|
||||||
pos=hamster.GetPos();
|
pos=hamster.GetPos();
|
||||||
hamster.SetZ(hamster.GetZ()-fallSpd*fElapsedTime);
|
hamster.SetZ(hamster.GetZ()-fallSpd*fElapsedTime);
|
||||||
z=hamster.GetZ();
|
z=hamster.GetZ();
|
||||||
@ -103,7 +114,7 @@ void HamsterJet::Update(const float fElapsedTime){
|
|||||||
hamster.SetZ(0.f);
|
hamster.SetZ(0.f);
|
||||||
state=COMPLETE_LANDING;
|
state=COMPLETE_LANDING;
|
||||||
hamster.SetState(Hamster::NORMAL);
|
hamster.SetState(Hamster::NORMAL);
|
||||||
HamsterGame::Game().SetZoom(1.f);
|
if(hamster.IsPlayerControlled)HamsterGame::Game().SetZoom(1.f);
|
||||||
timer=3.f;
|
timer=3.f;
|
||||||
originalPos=hamster.GetPos();
|
originalPos=hamster.GetPos();
|
||||||
targetPos={hamster.GetPos().x+128.f,hamster.GetPos().y+32.f};
|
targetPos={hamster.GetPos().x+128.f,hamster.GetPos().y+32.f};
|
||||||
@ -221,3 +232,7 @@ Terrain::CrashSpeed HamsterJet::GetLandingSpeed()const{
|
|||||||
if(fallSpd>2.f)return Terrain::MEDIUM;
|
if(fallSpd>2.f)return Terrain::MEDIUM;
|
||||||
else return Terrain::LIGHT;
|
else return Terrain::LIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float HamsterJet::GetZ()const{
|
||||||
|
return z;
|
||||||
|
}
|
@ -39,11 +39,9 @@ All rights reserved.
|
|||||||
|
|
||||||
#include "olcUTIL_Geometry2D.h"
|
#include "olcUTIL_Geometry2D.h"
|
||||||
#include "SpecialRenderable.h"
|
#include "SpecialRenderable.h"
|
||||||
|
#include "Terrain.h"
|
||||||
|
|
||||||
class Hamster;
|
class Hamster;
|
||||||
namespace Terrain{
|
|
||||||
enum CrashSpeed;
|
|
||||||
};
|
|
||||||
|
|
||||||
class HamsterJet{
|
class HamsterJet{
|
||||||
public:
|
public:
|
||||||
@ -80,6 +78,7 @@ private:
|
|||||||
float timer{};
|
float timer{};
|
||||||
std::array<JetState,4>jetState{};
|
std::array<JetState,4>jetState{};
|
||||||
float lastTappedSpace{};
|
float lastTappedSpace{};
|
||||||
|
bool setHamsterOriginalPos{false};
|
||||||
public:
|
public:
|
||||||
HamsterJet(Hamster&hamster);
|
HamsterJet(Hamster&hamster);
|
||||||
void Update(const float fElapsedTime);
|
void Update(const float fElapsedTime);
|
||||||
@ -89,4 +88,5 @@ public:
|
|||||||
const State GetState()const;
|
const State GetState()const;
|
||||||
void SetPos(const vf2d pos);
|
void SetPos(const vf2d pos);
|
||||||
Terrain::CrashSpeed GetLandingSpeed()const;
|
Terrain::CrashSpeed GetLandingSpeed()const;
|
||||||
|
const float GetZ()const;
|
||||||
};
|
};
|
@ -976,88 +976,12 @@ namespace olc
|
|||||||
line2 = GFX3D::Math::Vec_Sub(triTransformed.p[2], triTransformed.p[0]);
|
line2 = GFX3D::Math::Vec_Sub(triTransformed.p[2], triTransformed.p[0]);
|
||||||
normal = GFX3D::Math::Vec_CrossProduct(line1, line2);
|
normal = GFX3D::Math::Vec_CrossProduct(line1, line2);
|
||||||
normal = GFX3D::Math::Vec_Normalise(normal);
|
normal = GFX3D::Math::Vec_Normalise(normal);
|
||||||
|
triangle triProjected = triTransformed;
|
||||||
// Cull triangles that face away from viewer
|
|
||||||
if (flags & RENDER_CULL_CW && GFX3D::Math::Vec_DotProduct(normal, triTransformed.p[0]) > 0.0f) continue;
|
|
||||||
if (flags & RENDER_CULL_CCW && GFX3D::Math::Vec_DotProduct(normal, triTransformed.p[0]) < 0.0f) continue;
|
|
||||||
|
|
||||||
// If Lighting, calculate shading
|
|
||||||
if (flags & RENDER_LIGHTS)
|
|
||||||
{
|
|
||||||
olc::Pixel ambient_clamp = { 0,0,0 };
|
|
||||||
olc::Pixel light_combined = { 0,0,0 };
|
|
||||||
uint32_t nLightSources = 0;
|
|
||||||
float nLightR = 0, nLightG = 0, nLightB = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
switch (lights[i].type)
|
|
||||||
{
|
|
||||||
case LIGHT_DISABLED:
|
|
||||||
break;
|
|
||||||
case LIGHT_AMBIENT:
|
|
||||||
ambient_clamp = lights[i].col;
|
|
||||||
break;
|
|
||||||
case LIGHT_DIRECTIONAL:
|
|
||||||
{
|
|
||||||
nLightSources++;
|
|
||||||
GFX3D::vec3d light_dir = GFX3D::Math::Vec_Normalise(lights[i].dir);
|
|
||||||
float light = GFX3D::Math::Vec_DotProduct(light_dir, normal);
|
|
||||||
if (light > 0)
|
|
||||||
{
|
|
||||||
int j = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
light = std::max(light, 0.0f);
|
|
||||||
nLightR += light * (lights[i].col.r/255.0f);
|
|
||||||
nLightG += light * (lights[i].col.g/255.0f);
|
|
||||||
nLightB += light * (lights[i].col.b/255.0f);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case LIGHT_POINT:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//nLightR /= nLightSources;
|
|
||||||
//nLightG /= nLightSources;
|
|
||||||
//nLightB /= nLightSources;
|
|
||||||
|
|
||||||
nLightR = std::max(nLightR, ambient_clamp.r / 255.0f);
|
|
||||||
nLightG = std::max(nLightG, ambient_clamp.g / 255.0f);
|
|
||||||
nLightB = std::max(nLightB, ambient_clamp.b / 255.0f);
|
|
||||||
|
|
||||||
triTransformed.col[0] = olc::Pixel(uint8_t(nLightR * triTransformed.col[0].r), uint8_t(nLightG * triTransformed.col[0].g), uint8_t(nLightB * triTransformed.col[0].b));
|
|
||||||
triTransformed.col[1] = olc::Pixel(uint8_t(nLightR * triTransformed.col[1].r), uint8_t(nLightG * triTransformed.col[1].g), uint8_t(nLightB * triTransformed.col[1].b));
|
|
||||||
triTransformed.col[2] = olc::Pixel(uint8_t(nLightR * triTransformed.col[2].r), uint8_t(nLightG * triTransformed.col[2].g), uint8_t(nLightB * triTransformed.col[2].b));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*GFX3D::vec3d light_dir = { 1,1,1 };
|
|
||||||
light_dir = GFX3D::Math::Vec_Normalise(light_dir);
|
|
||||||
float light = GFX3D::Math::Vec_DotProduct(light_dir, normal);
|
|
||||||
if (light < 0) light = 0;
|
|
||||||
triTransformed.col[0] = olc::Pixel(light * 255.0f, light * 255.0f, light * 255.0f);
|
|
||||||
triTransformed.col[1] = olc::Pixel(light * 255.0f, light * 255.0f, light * 255.0f);
|
|
||||||
triTransformed.col[2] = olc::Pixel(light * 255.0f, light * 255.0f, light * 255.0f);*/
|
|
||||||
}
|
|
||||||
//else
|
|
||||||
// triTransformed.col = olc::WHITE;
|
|
||||||
|
|
||||||
// Clip triangle against near plane
|
|
||||||
int nClippedTriangles = 0;
|
|
||||||
GFX3D::triangle clipped[2];
|
|
||||||
nClippedTriangles = GFX3D::Math::Triangle_ClipAgainstPlane({ 0.0f, 0.0f, 0.1f }, { 0.0f, 0.0f, 1.0f }, triTransformed, clipped[0], clipped[1]);
|
|
||||||
|
|
||||||
// This may yield two new triangles
|
|
||||||
for (int n = 0; n < nClippedTriangles; n++)
|
|
||||||
{
|
|
||||||
triangle triProjected = clipped[n];
|
|
||||||
|
|
||||||
// Project new triangle
|
// Project new triangle
|
||||||
triProjected.p[0] = GFX3D::Math::Mat_MultiplyVector(matProj, clipped[n].p[0]);
|
triProjected.p[0] = GFX3D::Math::Mat_MultiplyVector(matProj, triTransformed.p[0]);
|
||||||
triProjected.p[1] = GFX3D::Math::Mat_MultiplyVector(matProj, clipped[n].p[1]);
|
triProjected.p[1] = GFX3D::Math::Mat_MultiplyVector(matProj, triTransformed.p[1]);
|
||||||
triProjected.p[2] = GFX3D::Math::Mat_MultiplyVector(matProj, clipped[n].p[2]);
|
triProjected.p[2] = GFX3D::Math::Mat_MultiplyVector(matProj, triTransformed.p[2]);
|
||||||
|
|
||||||
// Apply Projection to Verts
|
// Apply Projection to Verts
|
||||||
triProjected.p[0].x = triProjected.p[0].x / triProjected.p[0].w;
|
triProjected.p[0].x = triProjected.p[0].x / triProjected.p[0].w;
|
||||||
@ -1084,114 +1008,59 @@ namespace olc
|
|||||||
triProjected.t[0].z = 1.0f / triProjected.p[0].w;
|
triProjected.t[0].z = 1.0f / triProjected.p[0].w;
|
||||||
triProjected.t[1].z = 1.0f / triProjected.p[1].w;
|
triProjected.t[1].z = 1.0f / triProjected.p[1].w;
|
||||||
triProjected.t[2].z = 1.0f / triProjected.p[2].w;
|
triProjected.t[2].z = 1.0f / triProjected.p[2].w;
|
||||||
|
|
||||||
// Clip against viewport in screen space
|
|
||||||
// Clip triangles against all four screen edges, this could yield
|
|
||||||
// a bunch of triangles, so create a queue that we traverse to
|
|
||||||
// ensure we only test new triangles generated against planes
|
|
||||||
GFX3D::triangle sclipped[2];
|
|
||||||
std::list<GFX3D::triangle> listTriangles;
|
|
||||||
|
|
||||||
|
|
||||||
// Add initial triangle
|
|
||||||
listTriangles.push_back(triProjected);
|
|
||||||
int nNewTriangles = 1;
|
|
||||||
|
|
||||||
for (int p = 0; p < 4; p++)
|
|
||||||
{
|
|
||||||
int nTrisToAdd = 0;
|
|
||||||
while (nNewTriangles > 0)
|
|
||||||
{
|
|
||||||
// Take triangle from front of queue
|
|
||||||
triangle test = listTriangles.front();
|
|
||||||
listTriangles.pop_front();
|
|
||||||
nNewTriangles--;
|
|
||||||
|
|
||||||
// Clip it against a plane. We only need to test each
|
|
||||||
// subsequent plane, against subsequent new triangles
|
|
||||||
// as all triangles after a plane clip are guaranteed
|
|
||||||
// to lie on the inside of the plane. I like how this
|
|
||||||
// comment is almost completely and utterly justified
|
|
||||||
switch (p)
|
|
||||||
{
|
|
||||||
case 0: nTrisToAdd = GFX3D::Math::Triangle_ClipAgainstPlane({ 0.0f, -1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, test, sclipped[0], sclipped[1]); break;
|
|
||||||
case 1: nTrisToAdd = GFX3D::Math::Triangle_ClipAgainstPlane({ 0.0f, +1.0f, 0.0f }, { 0.0f, -1.0f, 0.0f }, test, sclipped[0], sclipped[1]); break;
|
|
||||||
case 2: nTrisToAdd = GFX3D::Math::Triangle_ClipAgainstPlane({ -1.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, test, sclipped[0], sclipped[1]); break;
|
|
||||||
case 3: nTrisToAdd = GFX3D::Math::Triangle_ClipAgainstPlane({ +1.0f, 0.0f, 0.0f }, { -1.0f, 0.0f, 0.0f }, test, sclipped[0], sclipped[1]); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Clipping may yield a variable number of triangles, so
|
|
||||||
// add these new ones to the back of the queue for subsequent
|
|
||||||
// clipping against next planes
|
|
||||||
for (int w = 0; w < nTrisToAdd; w++)
|
|
||||||
listTriangles.push_back(sclipped[w]);
|
|
||||||
}
|
|
||||||
nNewTriangles = listTriangles.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto &triRaster : listTriangles)
|
|
||||||
{
|
|
||||||
// Scale to viewport
|
// Scale to viewport
|
||||||
/*triRaster.p[0].x *= -1.0f;
|
/*triRaster.p[0].x *= -1.0f;
|
||||||
triRaster.p[1].x *= -1.0f;
|
triRaster.p[1].x *= -1.0f;
|
||||||
triRaster.p[2].x *= -1.0f;
|
triRaster.p[2].x *= -1.0f;
|
||||||
triRaster.p[0].y *= -1.0f;
|
triRaster.p[0].y *= -1.0f;
|
||||||
triRaster.p[1].y *= -1.0f;
|
triRaster.p[1].y *= -1.0f;
|
||||||
triRaster.p[2].y *= -1.0f;*/
|
triTransformed.p[2].y *= -1.0f;*/
|
||||||
vec3d vOffsetView = { 1,1,0 };
|
vec3d vOffsetView = { 1,1,0 };
|
||||||
triRaster.p[0] = Math::Vec_Add(triRaster.p[0], vOffsetView);
|
triProjected.p[0] = Math::Vec_Add(triProjected.p[0], vOffsetView);
|
||||||
triRaster.p[1] = Math::Vec_Add(triRaster.p[1], vOffsetView);
|
triProjected.p[1] = Math::Vec_Add(triProjected.p[1], vOffsetView);
|
||||||
triRaster.p[2] = Math::Vec_Add(triRaster.p[2], vOffsetView);
|
triProjected.p[2] = Math::Vec_Add(triProjected.p[2], vOffsetView);
|
||||||
triRaster.p[0].x *= 0.5f * fViewW;
|
triProjected.p[0].x *= 0.5f * fViewW;
|
||||||
triRaster.p[0].y *= 0.5f * fViewH;
|
triProjected.p[0].y *= 0.5f * fViewH;
|
||||||
triRaster.p[1].x *= 0.5f * fViewW;
|
triProjected.p[1].x *= 0.5f * fViewW;
|
||||||
triRaster.p[1].y *= 0.5f * fViewH;
|
triProjected.p[1].y *= 0.5f * fViewH;
|
||||||
triRaster.p[2].x *= 0.5f * fViewW;
|
triProjected.p[2].x *= 0.5f * fViewW;
|
||||||
triRaster.p[2].y *= 0.5f * fViewH;
|
triProjected.p[2].y *= 0.5f * fViewH;
|
||||||
vOffsetView = { fViewX,fViewY,0 };
|
vOffsetView = { fViewX,fViewY,0 };
|
||||||
triRaster.p[0] = Math::Vec_Add(triRaster.p[0], vOffsetView);
|
triProjected.p[0] = Math::Vec_Add(triProjected.p[0], vOffsetView);
|
||||||
triRaster.p[1] = Math::Vec_Add(triRaster.p[1], vOffsetView);
|
triProjected.p[1] = Math::Vec_Add(triProjected.p[1], vOffsetView);
|
||||||
triRaster.p[2] = Math::Vec_Add(triRaster.p[2], vOffsetView);
|
triProjected.p[2] = Math::Vec_Add(triProjected.p[2], vOffsetView);
|
||||||
|
|
||||||
// For now, just draw triangle
|
// For now, just draw triangle
|
||||||
|
|
||||||
//if (flags & RENDER_TEXTURED)
|
//if (flags & RENDER_TEXTURED)
|
||||||
//{/*
|
//{/*
|
||||||
// TexturedTriangle(
|
// TexturedTriangle(
|
||||||
// triRaster.p[0].x, triRaster.p[0].y, triRaster.t[0].x, triRaster.t[0].y, triRaster.t[0].z,
|
// triProjected.p[0].x, triProjected.p[0].y, triProjected.t[0].x, triProjected.t[0].y, triProjected.t[0].z,
|
||||||
// triRaster.p[1].x, triRaster.p[1].y, triRaster.t[1].x, triRaster.t[1].y, triRaster.t[1].z,
|
// triProjected.p[1].x, triProjected.p[1].y, triProjected.t[1].x, triProjected.t[1].y, triProjected.t[1].z,
|
||||||
// triRaster.p[2].x, triRaster.p[2].y, triRaster.t[2].x, triRaster.t[2].y, triRaster.t[2].z,
|
// triProjected.p[2].x, triProjected.p[2].y, triProjected.t[2].x, triProjected.t[2].y, triProjected.t[2].z,
|
||||||
// sprTexture);*/
|
// sprTexture);*/
|
||||||
|
|
||||||
// RasterTriangle(
|
// RasterTriangle(
|
||||||
// triRaster.p[0].x, triRaster.p[0].y, triRaster.t[0].x, triRaster.t[0].y, triRaster.t[0].z, triRaster.col,
|
// triProjected.p[0].x, triProjected.p[0].y, triProjected.t[0].x, triProjected.t[0].y, triProjected.t[0].z, triProjected.col,
|
||||||
// triRaster.p[1].x, triRaster.p[1].y, triRaster.t[1].x, triRaster.t[1].y, triRaster.t[1].z, triRaster.col,
|
// triProjected.p[1].x, triProjected.p[1].y, triProjected.t[1].x, triProjected.t[1].y, triProjected.t[1].z, triProjected.col,
|
||||||
// triRaster.p[2].x, triRaster.p[2].y, triRaster.t[2].x, triRaster.t[2].y, triRaster.t[2].z, triRaster.col,
|
// triProjected.p[2].x, triProjected.p[2].y, triProjected.t[2].x, triProjected.t[2].y, triProjected.t[2].z, triProjected.col,
|
||||||
// sprTexture, nFlags);
|
// sprTexture, nFlags);
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if (flags & RENDER_WIRE)
|
if (flags & RENDER_WIRE)
|
||||||
{
|
{
|
||||||
DrawTriangleWire(triRaster, olc::RED);
|
DrawTriangleWire(triProjected, olc::RED);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RasterTriangle(
|
RasterTriangle(
|
||||||
triRaster.p[0].x,triRaster.p[0].y,triRaster.p[0].z, triRaster.t[0].x, triRaster.t[0].y, triRaster.t[0].z, triRaster.col[0],
|
triProjected.p[0].x,triProjected.p[0].y,triProjected.p[0].z, triProjected.t[0].x, triProjected.t[0].y, triProjected.t[0].z, triProjected.col[0],
|
||||||
triRaster.p[1].x,triRaster.p[1].y,triRaster.p[1].z, triRaster.t[1].x, triRaster.t[1].y, triRaster.t[1].z, triRaster.col[1],
|
triProjected.p[1].x,triProjected.p[1].y,triProjected.p[1].z, triProjected.t[1].x, triProjected.t[1].y, triProjected.t[1].z, triProjected.col[1],
|
||||||
triRaster.p[2].x,triRaster.p[2].y,triRaster.p[2].z, triRaster.t[2].x, triRaster.t[2].y, triRaster.t[2].z, triRaster.col[2],
|
triProjected.p[2].x,triProjected.p[2].y,triProjected.p[2].z, triProjected.t[2].x, triProjected.t[2].y, triProjected.t[2].z, triProjected.col[2],
|
||||||
dec, flags);
|
dec, flags);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nTriangleDrawnCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nTriangleDrawnCount;
|
return nTriangleDrawnCount;
|
||||||
|
@ -156,7 +156,7 @@ olc::ViewPort::ViewPort(std::vector<vf2d> vertices, olc::vf2d offset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void olc::ViewPort::addPoint(vf2d point) {
|
void olc::ViewPort::addPoint(vf2d point) {
|
||||||
clipVertices.push_back(point);
|
clipVertices.emplace_back(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
void olc::ViewPort::clear() {
|
void olc::ViewPort::clear() {
|
||||||
@ -600,17 +600,17 @@ void olc::ViewPort::drawClippedDecal(Decal *decal,
|
|||||||
|
|
||||||
if (bDirection <= 0) {
|
if (bDirection <= 0) {
|
||||||
if (aDirection > 0) {
|
if (aDirection > 0) {
|
||||||
outputList.push_back(intersectionPoint);
|
outputList.emplace_back(intersectionPoint);
|
||||||
outputUvs.push_back(intersectionUv);
|
outputUvs.emplace_back(intersectionUv);
|
||||||
outputCols.push_back(intersectionCol);
|
outputCols.emplace_back(intersectionCol);
|
||||||
}
|
}
|
||||||
outputList.push_back(polygonB);
|
outputList.emplace_back(polygonB);
|
||||||
outputUvs.push_back(uvB);
|
outputUvs.emplace_back(uvB);
|
||||||
outputCols.push_back(colB);
|
outputCols.emplace_back(colB);
|
||||||
} else if (aDirection <= 0) {
|
} else if (aDirection <= 0) {
|
||||||
outputList.push_back(intersectionPoint);
|
outputList.emplace_back(intersectionPoint);
|
||||||
outputUvs.push_back(intersectionUv);
|
outputUvs.emplace_back(intersectionUv);
|
||||||
outputCols.push_back(intersectionCol);
|
outputCols.emplace_back(intersectionCol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -670,17 +670,17 @@ void olc::ViewPort::drawClippedPolygonDecal(Decal *decal,
|
|||||||
|
|
||||||
if (bDirection <= 0) {
|
if (bDirection <= 0) {
|
||||||
if (aDirection > 0) {
|
if (aDirection > 0) {
|
||||||
outputList.push_back(intersectionPoint);
|
outputList.emplace_back(intersectionPoint);
|
||||||
outputUvs.push_back(intersectionUv);
|
outputUvs.emplace_back(intersectionUv);
|
||||||
outputDepths.push_back(intersectionDepth);
|
outputDepths.emplace_back(intersectionDepth);
|
||||||
}
|
}
|
||||||
outputList.push_back(polygonB);
|
outputList.emplace_back(polygonB);
|
||||||
outputUvs.push_back(uvB);
|
outputUvs.emplace_back(uvB);
|
||||||
outputDepths.push_back(Wb);
|
outputDepths.emplace_back(Wb);
|
||||||
} else if (aDirection <= 0) {
|
} else if (aDirection <= 0) {
|
||||||
outputList.push_back(intersectionPoint);
|
outputList.emplace_back(intersectionPoint);
|
||||||
outputUvs.push_back(intersectionUv);
|
outputUvs.emplace_back(intersectionUv);
|
||||||
outputDepths.push_back(intersectionDepth);
|
outputDepths.emplace_back(intersectionDepth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4596,19 +4596,6 @@ namespace olc
|
|||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decal.depth)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Render as 3D Spatial Entity
|
|
||||||
for (uint32_t n = 0; n < decal.points; n++)
|
|
||||||
{
|
|
||||||
glColor4ub(decal.tint[n].r, decal.tint[n].g, decal.tint[n].b, decal.tint[n].a);
|
|
||||||
glTexCoord4f(decal.uv[n].x, decal.uv[n].y, 0.0f, decal.w[n]);
|
|
||||||
glVertex3f(decal.pos[n].x, decal.pos[n].y, decal.z[n]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Render as 2D Spatial entity
|
// Render as 2D Spatial entity
|
||||||
for (uint32_t n = 0; n < decal.points; n++)
|
for (uint32_t n = 0; n < decal.points; n++)
|
||||||
{
|
{
|
||||||
@ -4616,7 +4603,6 @@ namespace olc
|
|||||||
glTexCoord4f(decal.uv[n].x, decal.uv[n].y, 0.0f, decal.w[n]);
|
glTexCoord4f(decal.uv[n].x, decal.uv[n].y, 0.0f, decal.w[n]);
|
||||||
glVertex2f(decal.pos[n].x, decal.pos[n].y);
|
glVertex2f(decal.pos[n].x, decal.pos[n].y);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user