Fix ViewPort PGEX. Added Draw String functions from PGE to ViewPort.
This commit is contained in:
parent
c11417d8a0
commit
4bab1397dc
@ -344,6 +344,7 @@
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="olcPGEX_ViewPort.h" />
|
||||
<ClInclude Include="olcPixelGameEngine.h" />
|
||||
<ClInclude Include="olcUTIL_Animate2D.h" />
|
||||
<ClInclude Include="olcUTIL_Camera2D.h" />
|
||||
|
@ -297,6 +297,9 @@
|
||||
<ClInclude Include="EquipSlotButton.h">
|
||||
<Filter>Header Files\Interface</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="olcPGEX_ViewPort.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Player.cpp">
|
||||
|
@ -197,6 +197,14 @@ bool MenuComponent::PointWithinParent(MenuComponent*child,vi2d drawPos){
|
||||
}
|
||||
}
|
||||
|
||||
bool MenuComponent::PointWithinParent(MenuComponent*child,geom2d::rect<float> drawRect){
|
||||
if(parentComponent!=nullptr){
|
||||
return parentComponent->PointWithinParent(child,drawRect);
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool MenuComponent::HandleOutsideDisabledButtonSelection(MenuComponent*disabledButton){
|
||||
return false;
|
||||
};
|
||||
|
@ -104,6 +104,8 @@ protected:
|
||||
virtual void AfterCreate(); //Called after the creation of all menus finish.
|
||||
//CALL THIS FOR A PARENT to check a child's DrawDecal validity!
|
||||
virtual bool PointWithinParent(MenuComponent*child,vi2d drawPos);
|
||||
//CALL THIS FOR A PARENT to check a child's DrawDecal validity!
|
||||
virtual bool PointWithinParent(MenuComponent*child,geom2d::rect<float> drawRect);
|
||||
public:
|
||||
MenuType parentMenu=MenuType::ENUM_END;
|
||||
MenuComponent*parentComponent=nullptr;
|
||||
|
@ -157,7 +157,8 @@ protected:
|
||||
vf2d quantityTextScale=rect.size/48.f;
|
||||
vf2d textSize=vf2d(game->GetTextSizeProp(quantityText))*quantityTextScale;
|
||||
vf2d drawPos=parentPos+rect.pos+rect.size-textSize;
|
||||
if(PointWithinParent(this,drawPos)){
|
||||
geom2d::rect<float>boundingBox={drawPos,textSize};
|
||||
if(PointWithinParent(this,boundingBox)){
|
||||
game->DrawShadowStringDecal(drawPos,quantityText,WHITE,BLACK,quantityTextScale,quantityTextScale.x);
|
||||
}
|
||||
}
|
||||
|
@ -141,7 +141,8 @@ protected:
|
||||
vf2d quantityTextScale=rect.size/48.f;
|
||||
vf2d textSize=vf2d(game->GetTextSizeProp(quantityText))*quantityTextScale;
|
||||
vf2d drawPos=Menu::menus[parentMenu]->pos+parentPos+rect.pos+rect.size-textSize;
|
||||
if(PointWithinParent(this,drawPos)){
|
||||
geom2d::rect<float>boundingBox={drawPos,textSize};
|
||||
if(PointWithinParent(this,boundingBox)){
|
||||
game->DrawShadowStringDecal(drawPos,quantityText,WHITE,BLACK,quantityTextScale,quantityTextScale.x);
|
||||
}
|
||||
}
|
||||
|
@ -260,6 +260,9 @@ public:
|
||||
virtual inline bool PointWithinParent(MenuComponent*child,vi2d drawPos)override{
|
||||
return geom2d::overlaps(geom2d::rect<float>{Menu::menus[parentMenu]->pos+rect.pos,rect.size},drawPos);
|
||||
}
|
||||
virtual inline bool PointWithinParent(MenuComponent*child,geom2d::rect<float> drawRect)override{
|
||||
return geom2d::overlaps(geom2d::rect<float>{Menu::menus[parentMenu]->pos+rect.pos,rect.size},drawRect);
|
||||
}
|
||||
virtual inline bool HandleOutsideDisabledButtonSelection(MenuComponent*disabledButton)override{
|
||||
//Set the offset so the center is highlighted by this button.
|
||||
V(A::SCROLL_OFFSET).y=-(disabledButton->rect.pos.y-disabledButton->rect.size.y/2);
|
||||
|
@ -50,6 +50,7 @@ void State_GameRun::OnStateChange(GameState*prevState){
|
||||
Menu::CloseAllMenus();
|
||||
}
|
||||
game->GetPlayer()->SetState(State::NORMAL);
|
||||
port=ViewPort::rectViewPort({0,0},{72,100},{75,100});
|
||||
}
|
||||
void State_GameRun::OnUserUpdate(Crawler*game){
|
||||
game->bossDisplayTimer=std::max(0.f,game->bossDisplayTimer-game->GetElapsedTime());
|
||||
@ -79,16 +80,16 @@ void State_GameRun::Draw(Crawler*game){
|
||||
}
|
||||
|
||||
void State_GameRun::FontTest(){
|
||||
game->DrawStringDecal({8,8},"#000000This is a #000066test of hex");
|
||||
game->DrawStringDecal({8,16},"#FF0000This is a #BFA6F9test of hex");
|
||||
game->DrawStringDecal({8,24},"#00FF00This is a #E9A6F9test of hex");
|
||||
game->DrawStringDecal({8,32},"#0000FFThis is a #F9E8A6test of hex");
|
||||
game->DrawShadowStringDecal({8,40},"#000000This is a #000066test of hex");
|
||||
game->DrawShadowStringDecal({8,48},"#FF0000This is a #BFA6F9test of hex");
|
||||
game->DrawShadowStringDecal({8,56},"#00FF00This is a #E9A6F9test of hex");
|
||||
game->DrawShadowStringDecal({8,64},"#0000FFThis is a #F9E8A6test of hex");
|
||||
game->DrawShadowStringDecal(VisualNovel::font,{8,72},U"#000000This is a #000066test of hex");
|
||||
game->DrawShadowStringDecal(VisualNovel::font,{8,80},U"#FF0000This is a #BFA6F9test of hex");
|
||||
game->DrawShadowStringDecal(VisualNovel::font,{8,88},U"#00FF00This is a #E9A6F9test of hex");
|
||||
game->DrawShadowStringDecal(VisualNovel::font,{8,96},U"#0000FFThis is a #F9E8A6test of hex");
|
||||
port.DrawStringDecal({8,8},"#FFFFFFThis is a #000066test of hex");
|
||||
port.DrawStringDecal({8,16},"#FF0000This is a #BFA6F9test of hex");
|
||||
port.DrawStringDecal({8,24},"#00FF00This is a #E9A6F9test of hex");
|
||||
port.DrawStringDecal({8,32},"#0000FFThis is a #F9E8A6test of hex");
|
||||
port.DrawShadowStringDecal({8,40},"#FFFFFFThis is a #000066test of hex");
|
||||
port.DrawShadowStringDecal({8,48},"#FF0000This is a #BFA6F9test of hex");
|
||||
port.DrawShadowStringDecal({8,56},"#00FF00This is a #E9A6F9test of hex");
|
||||
port.DrawShadowStringDecal({8,64},"#0000FFThis is a #F9E8A6test of hex");
|
||||
port.DrawShadowStringDecal(VisualNovel::font,{8,72},U"#FFFFFFThis is a #000066test of hex");
|
||||
port.DrawShadowStringDecal(VisualNovel::font,{8,80},U"#FF0000This is a #BFA6F9test of hex");
|
||||
port.DrawShadowStringDecal(VisualNovel::font,{8,88},U"#00FF00This is a #E9A6F9test of hex");
|
||||
port.DrawShadowStringDecal(VisualNovel::font,{8,96},U"#0000FFThis is a #F9E8A6test of hex");
|
||||
}
|
@ -37,8 +37,10 @@ All rights reserved.
|
||||
#pragma endregion
|
||||
#pragma once
|
||||
#include "GameState.h"
|
||||
#include "olcPGEX_ViewPort.h"
|
||||
|
||||
class State_GameRun:public GameState{
|
||||
ViewPort port;
|
||||
virtual void OnStateChange(GameState*prevState)override final;
|
||||
virtual void OnUserUpdate(Crawler*game)override final;
|
||||
virtual void Draw(Crawler*game)override final;
|
||||
|
@ -35,7 +35,6 @@ Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
||||
All rights reserved.
|
||||
*/
|
||||
#pragma endregion
|
||||
#include "State_OverworldMap.h"
|
||||
#include "Crawler.h"
|
||||
#include "DEFINES.h"
|
||||
#include "Menu.h"
|
||||
@ -46,6 +45,7 @@ All rights reserved.
|
||||
#include "MenuLabel.h"
|
||||
#include "EncountersSpawnListScrollableWindowComponent.h"
|
||||
#include "VisualNovel.h"
|
||||
#include "State_OverworldMap.h"
|
||||
|
||||
INCLUDE_MONSTER_LIST
|
||||
INCLUDE_game
|
||||
|
@ -38,6 +38,7 @@ All rights reserved.
|
||||
#pragma once
|
||||
#include "GameState.h"
|
||||
#include "ConnectionPoint.h"
|
||||
#include "olcPGEX_ViewPort.h"
|
||||
|
||||
class State_OverworldMap:public GameState{
|
||||
friend class Crawler;
|
||||
|
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_PATCH 1
|
||||
#define VERSION_BUILD 3827
|
||||
#define VERSION_BUILD 3862
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
775
Crawler/olcPGEX_ViewPort.h
Normal file
775
Crawler/olcPGEX_ViewPort.h
Normal file
@ -0,0 +1,775 @@
|
||||
#pragma once
|
||||
|
||||
#include "olcPixelGameEngine.h"
|
||||
#include "olcPGEX_TTF.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
// Declarations
|
||||
namespace olc {
|
||||
class ViewPort : public olc::PGEX {
|
||||
public:
|
||||
ViewPort();
|
||||
ViewPort(std::vector<vf2d> vertices, vf2d offset = {0, 0});
|
||||
virtual ~ViewPort();
|
||||
void addPoint(vf2d point);
|
||||
void clear();
|
||||
void drawEdges();
|
||||
void setOffset(vf2d offset);
|
||||
|
||||
static ViewPort rectViewPort(vf2d topLeft,
|
||||
vf2d size,
|
||||
olc::vf2d offset = {0, 0});
|
||||
|
||||
void DrawDecal(const olc::vf2d &pos,
|
||||
olc::Decal *decal,
|
||||
const olc::vf2d &scale = {1.0f, 1.0f},
|
||||
const olc::Pixel &tint = olc::WHITE) const;
|
||||
void DrawPartialDecal(const olc::vf2d &pos,
|
||||
olc::Decal *decal,
|
||||
const olc::vf2d &source_pos,
|
||||
const olc::vf2d &source_size,
|
||||
const olc::vf2d &scale = {1.0f, 1.0f},
|
||||
const olc::Pixel &tint = olc::WHITE) const;
|
||||
void DrawPartialDecal(const vf2d &pos,
|
||||
const vf2d &size,
|
||||
Decal *decal,
|
||||
const vf2d source_pos,
|
||||
const vf2d &source_size,
|
||||
const Pixel &tint = olc::WHITE) const;
|
||||
void DrawExplicitDecal(olc::Decal *decal,
|
||||
const olc::vf2d *pos,
|
||||
const olc::vf2d *uv,
|
||||
const olc::Pixel *col,
|
||||
uint32_t elements = 4) const;
|
||||
void DrawWarpedDecal(Decal *decal,
|
||||
const vf2d (&pos)[4],
|
||||
const Pixel &tint = WHITE) const;
|
||||
void DrawWarpedDecal(Decal *decal,
|
||||
const vf2d *pos,
|
||||
const Pixel &tint = WHITE) const;
|
||||
void DrawWarpedDecal(Decal *decal,
|
||||
const std::array<vf2d, 4> &pos,
|
||||
const Pixel &tint = WHITE) const;
|
||||
void DrawPartialWarpedDecal(Decal *decal,
|
||||
const vf2d (&pos)[4],
|
||||
const vf2d &source_pos,
|
||||
const vf2d &source_size,
|
||||
const Pixel &tint = WHITE) const;
|
||||
void DrawPartialWarpedDecal(Decal *decal,
|
||||
const vf2d *pos,
|
||||
const vf2d &source_pos,
|
||||
const vf2d &source_size,
|
||||
const Pixel &tint = WHITE) const;
|
||||
void DrawPartialWarpedDecal(Decal *decal,
|
||||
const std::array<vf2d, 4> &pos,
|
||||
const vf2d &source_pos,
|
||||
const vf2d &source_size,
|
||||
const Pixel &tint = WHITE) const;
|
||||
void DrawRotatedDecal(const vf2d &pos,
|
||||
Decal *decal,
|
||||
const float fAngle,
|
||||
const vf2d ¢er = {0.0f, 0.0f},
|
||||
const vf2d &scale = {1.0f, 1.0f},
|
||||
const Pixel &tint = WHITE) const;
|
||||
void DrawPartialRotatedDecal(const vf2d &pos,
|
||||
Decal *decal,
|
||||
const float fAngle,
|
||||
const vf2d ¢er,
|
||||
const vf2d &source_pos,
|
||||
const vf2d &source_size,
|
||||
const vf2d &scale = {1.0f, 1.0f},
|
||||
const Pixel &tint = WHITE) const;
|
||||
void FillRectDecal(const vf2d &pos,
|
||||
const vf2d &size,
|
||||
const Pixel col = WHITE) const;
|
||||
void GradientFillRectDecal(const vf2d &pos,
|
||||
const vf2d &size,
|
||||
const Pixel colTL,
|
||||
const Pixel colBL,
|
||||
const Pixel colBR,
|
||||
const Pixel colTR) const;
|
||||
void DrawPolygonDecal(Decal *decal,
|
||||
const std::vector<vf2d> &pos,
|
||||
const std::vector<vf2d> &uv,
|
||||
const Pixel tint = WHITE) const;
|
||||
void DrawPolygonDecal(Decal *decal,
|
||||
const std::vector<vf2d> &pos,
|
||||
const std::vector<float> &depth,
|
||||
const std::vector<vf2d> &uv,
|
||||
const Pixel tint = WHITE) const;
|
||||
void DrawPolygonDecal(Decal *decal,
|
||||
const std::vector<vf2d> &pos,
|
||||
const std::vector<vf2d> &uv,
|
||||
const std::vector<Pixel> &tint) const;
|
||||
void DrawLineDecal(const vf2d &pos1,
|
||||
const vf2d &pos2,
|
||||
Pixel p = WHITE) const;
|
||||
// Draws a multiline string as a decal, with tinting and scaling
|
||||
void DrawStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||
void DrawStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||
void DrawStringPropDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||
void DrawShadowStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
|
||||
void DrawShadowStringPropDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
|
||||
void DrawShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f },const float shadowSizeFactor=1);
|
||||
void DrawDropShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col = olc::WHITE, const Pixel shadowCol = olc::BLACK, const olc::vf2d& scale = { 1.0f, 1.0f });
|
||||
|
||||
private:
|
||||
void drawClippedDecal(Decal *decal,
|
||||
const vf2d *points,
|
||||
const vf2d *uvs,
|
||||
const Pixel *col,
|
||||
uint32_t elements = 0) const;
|
||||
|
||||
static float lineSegmentIntersect(vf2d lineA,
|
||||
vf2d lineB,
|
||||
vf2d segmentA,
|
||||
vf2d segmentB);
|
||||
static float directionFromLine(vf2d lineA, vf2d lineB, vf2d point);
|
||||
|
||||
std::vector<vf2d> clipVertices;
|
||||
olc::vf2d offset;
|
||||
};
|
||||
} // namespace olc
|
||||
|
||||
// Definitions
|
||||
|
||||
#ifdef OLC_PGEX_VIEWPORT
|
||||
#undef OLC_PGEX_VIEWPORT
|
||||
|
||||
olc::ViewPort::ViewPort() {
|
||||
}
|
||||
olc::ViewPort::~ViewPort() {
|
||||
}
|
||||
|
||||
olc::ViewPort::ViewPort(std::vector<vf2d> vertices, olc::vf2d offset)
|
||||
: clipVertices{vertices},
|
||||
offset{offset} {
|
||||
}
|
||||
|
||||
void olc::ViewPort::addPoint(vf2d point) {
|
||||
clipVertices.push_back(point);
|
||||
}
|
||||
|
||||
void olc::ViewPort::clear() {
|
||||
clipVertices.clear();
|
||||
}
|
||||
|
||||
void olc::ViewPort::drawEdges() {
|
||||
for (auto i = 0u; i < clipVertices.size(); i++) {
|
||||
auto current = clipVertices[i] + offset;
|
||||
auto next = clipVertices[(i + 1) % clipVertices.size()] + offset;
|
||||
|
||||
pge->DrawLineDecal(current, next, olc::RED);
|
||||
}
|
||||
}
|
||||
|
||||
void olc::ViewPort::setOffset(vf2d offset) {
|
||||
this->offset = offset;
|
||||
}
|
||||
|
||||
olc::ViewPort
|
||||
olc::ViewPort::rectViewPort(vf2d topLeft, vf2d size, olc::vf2d offset) {
|
||||
return {{
|
||||
topLeft,
|
||||
{topLeft.x, topLeft.y + size.y},
|
||||
topLeft + size,
|
||||
{topLeft.x + size.x, topLeft.y},
|
||||
},
|
||||
offset};
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawDecal(const olc::vf2d &pos,
|
||||
olc::Decal *decal,
|
||||
const olc::vf2d &scale,
|
||||
const olc::Pixel &tint) const {
|
||||
std::vector<olc::vf2d> points{
|
||||
pos,
|
||||
{pos.x, pos.y + decal->sprite->height * scale.y},
|
||||
{pos.x + decal->sprite->width * scale.x,
|
||||
pos.y + decal->sprite->height * scale.y},
|
||||
{pos.x + decal->sprite->width * scale.x, pos.y},
|
||||
};
|
||||
DrawWarpedDecal(decal, points.data(), tint);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawPartialDecal(const olc::vf2d &pos,
|
||||
olc::Decal *decal,
|
||||
const olc::vf2d &source_pos,
|
||||
const olc::vf2d &source_size,
|
||||
const olc::vf2d &scale,
|
||||
const olc::Pixel &tint) const {
|
||||
DrawPartialDecal(pos, source_size * scale, decal, source_pos, source_size, tint);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawPartialDecal(const vf2d &pos,
|
||||
const vf2d &size,
|
||||
Decal *decal,
|
||||
const vf2d source_pos,
|
||||
const vf2d &source_size,
|
||||
const Pixel &tint) const {
|
||||
std::vector<vf2d> points{
|
||||
pos,
|
||||
{pos.x, pos.y + size.y},
|
||||
pos + size,
|
||||
{pos.x + size.x, pos.y},
|
||||
};
|
||||
DrawPartialWarpedDecal(decal, points.data(), source_pos, source_size, tint);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawExplicitDecal(olc::Decal *decal,
|
||||
const olc::vf2d *pos,
|
||||
const olc::vf2d *uv,
|
||||
const olc::Pixel *col,
|
||||
uint32_t elements) const {
|
||||
drawClippedDecal(decal, pos, uv, col, elements);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawWarpedDecal(Decal *decal,
|
||||
const vf2d (&pos)[4],
|
||||
const Pixel &tint) const {
|
||||
DrawWarpedDecal(decal, (const vf2d *)pos, tint);
|
||||
}
|
||||
void olc::ViewPort::DrawWarpedDecal(Decal *decal,
|
||||
const vf2d *pos,
|
||||
const Pixel &tint) const {
|
||||
std::vector<vf2d> uvs{
|
||||
{0, 0},
|
||||
{0, 1},
|
||||
{1, 1},
|
||||
{1, 0},
|
||||
};
|
||||
std::vector<Pixel> cols{
|
||||
tint,
|
||||
tint,
|
||||
tint,
|
||||
tint,
|
||||
};
|
||||
|
||||
drawClippedDecal(decal, pos, uvs.data(), cols.data(), 4);
|
||||
}
|
||||
void olc::ViewPort::DrawWarpedDecal(Decal *decal,
|
||||
const std::array<vf2d, 4> &pos,
|
||||
const Pixel &tint) const {
|
||||
DrawWarpedDecal(decal, pos.data(), tint);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawPartialWarpedDecal(Decal *decal,
|
||||
const vf2d (&pos)[4],
|
||||
const vf2d &source_pos,
|
||||
const vf2d &source_size,
|
||||
const Pixel &tint) const {
|
||||
DrawPartialWarpedDecal(decal,
|
||||
(const vf2d *)pos,
|
||||
source_pos,
|
||||
source_size,
|
||||
tint);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawPartialWarpedDecal(Decal *decal,
|
||||
const vf2d *pos,
|
||||
const vf2d &source_pos,
|
||||
const vf2d &source_size,
|
||||
const Pixel &tint) const {
|
||||
olc::vf2d sourceUvPos =
|
||||
source_pos
|
||||
/ olc::vf2d{static_cast<float>(decal->sprite->width),
|
||||
static_cast<float>(decal->sprite->height)};
|
||||
olc::vf2d sourceUvSize =
|
||||
source_size
|
||||
/ olc::vf2d{static_cast<float>(decal->sprite->width),
|
||||
static_cast<float>(decal->sprite->height)};
|
||||
std::vector<vf2d> uvs{
|
||||
sourceUvPos,
|
||||
{sourceUvPos.x, sourceUvPos.y + sourceUvSize.y},
|
||||
sourceUvPos + sourceUvSize,
|
||||
{sourceUvPos.x + sourceUvSize.x, sourceUvPos.y},
|
||||
};
|
||||
std::vector<Pixel> cols{
|
||||
tint,
|
||||
tint,
|
||||
tint,
|
||||
tint,
|
||||
};
|
||||
|
||||
drawClippedDecal(decal, pos, uvs.data(), cols.data(), 4);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawPartialWarpedDecal(Decal *decal,
|
||||
const std::array<vf2d, 4> &pos,
|
||||
const vf2d &source_pos,
|
||||
const vf2d &source_size,
|
||||
const Pixel &tint) const {
|
||||
DrawPartialWarpedDecal(decal, pos.data(), source_pos, source_size, tint);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawRotatedDecal(const vf2d &pos,
|
||||
Decal *decal,
|
||||
const float fAngle,
|
||||
const vf2d ¢er,
|
||||
const vf2d &scale,
|
||||
const Pixel &tint) const {
|
||||
auto sin = std::sin(fAngle);
|
||||
auto cos = std::cos(fAngle);
|
||||
|
||||
std::vector<vf2d> points{
|
||||
-center * scale,
|
||||
olc::vf2d{-center.x, decal->sprite->height - center.y} * scale,
|
||||
olc::vf2d{decal->sprite->width - center.x,
|
||||
decal->sprite->height - center.y}
|
||||
* scale,
|
||||
olc::vf2d{decal->sprite->width - center.x, -center.y} * scale,
|
||||
};
|
||||
|
||||
for (auto i = 0u; i < points.size(); i++) {
|
||||
points[i] = pos
|
||||
+ olc::vf2d{points[i].x * cos - points[i].y * sin,
|
||||
points[i].x * sin + points[i].y * cos};
|
||||
}
|
||||
|
||||
DrawWarpedDecal(decal, points.data(), tint);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawPartialRotatedDecal(const vf2d &pos,
|
||||
Decal *decal,
|
||||
const float fAngle,
|
||||
const vf2d ¢er,
|
||||
const vf2d &source_pos,
|
||||
const vf2d &source_size,
|
||||
const vf2d &scale,
|
||||
const Pixel &tint) const {
|
||||
auto sin = std::sin(fAngle);
|
||||
auto cos = std::cos(fAngle);
|
||||
|
||||
std::vector<vf2d> points{
|
||||
-center * scale,
|
||||
olc::vf2d{-center.x, source_size.y - center.y} * scale,
|
||||
(source_size - center) * scale,
|
||||
olc::vf2d{source_size.x - center.x, -center.y} * scale,
|
||||
};
|
||||
|
||||
for (auto i = 0u; i < points.size(); i++) {
|
||||
points[i] = pos
|
||||
+ olc::vf2d{points[i].x * cos - points[i].y * sin,
|
||||
points[i].x * sin + points[i].y * cos};
|
||||
}
|
||||
|
||||
DrawPartialWarpedDecal(decal, points.data(), source_pos, source_size, tint);
|
||||
}
|
||||
|
||||
void olc::ViewPort::FillRectDecal(const vf2d &pos,
|
||||
const vf2d &size,
|
||||
const Pixel col) const {
|
||||
std::vector<vf2d> points{
|
||||
pos,
|
||||
{pos.x, pos.y + size.y},
|
||||
pos + size,
|
||||
{pos.x + size.y, pos.y},
|
||||
};
|
||||
std::vector<vf2d> uvs{
|
||||
{0, 0},
|
||||
{0, 1},
|
||||
{1, 1},
|
||||
{1, 0},
|
||||
};
|
||||
|
||||
DrawPolygonDecal(nullptr, points, uvs, col);
|
||||
}
|
||||
|
||||
void olc::ViewPort::GradientFillRectDecal(const vf2d &pos,
|
||||
const vf2d &size,
|
||||
const Pixel colTL,
|
||||
const Pixel colBL,
|
||||
const Pixel colBR,
|
||||
const Pixel colTR) const {
|
||||
std::vector<vf2d> points{
|
||||
pos,
|
||||
{pos.x, pos.y + size.y},
|
||||
pos + size,
|
||||
{pos.x + size.y, pos.y},
|
||||
};
|
||||
|
||||
std::vector<vf2d> uvs{
|
||||
{0, 0},
|
||||
{0, 1},
|
||||
{1, 1},
|
||||
{1, 0},
|
||||
};
|
||||
|
||||
std::vector<Pixel> colors{
|
||||
colTL,
|
||||
colBL,
|
||||
colBR,
|
||||
colTR,
|
||||
};
|
||||
|
||||
drawClippedDecal(nullptr, points.data(), uvs.data(), colors.data(), points.size());
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawPolygonDecal(Decal *decal,
|
||||
const std::vector<vf2d> &pos,
|
||||
const std::vector<vf2d> &uv,
|
||||
const Pixel tint) const {
|
||||
std::vector<Pixel> colors;
|
||||
colors.resize(pos.size());
|
||||
for (auto i = 0u; i < colors.size(); i++) {
|
||||
colors[i] = tint;
|
||||
}
|
||||
|
||||
drawClippedDecal(decal, pos.data(), uv.data(), colors.data(), pos.size());
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawPolygonDecal(Decal *decal,
|
||||
const std::vector<vf2d> &pos,
|
||||
const std::vector<float> &,
|
||||
const std::vector<vf2d> &uv,
|
||||
const Pixel tint) const {
|
||||
DrawPolygonDecal(decal, pos, uv, tint);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawPolygonDecal(Decal *decal,
|
||||
const std::vector<vf2d> &pos,
|
||||
const std::vector<vf2d> &uv,
|
||||
const std::vector<Pixel> &tint) const {
|
||||
drawClippedDecal(decal, pos.data(), uv.data(), tint.data(), pos.size());
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawLineDecal(const vf2d &pos1,
|
||||
const vf2d &pos2,
|
||||
Pixel p) const {
|
||||
vf2d posA = pos1;
|
||||
vf2d posB = pos2;
|
||||
|
||||
for (auto i = 0u; i < clipVertices.size(); i++) {
|
||||
auto clipA = clipVertices[i];
|
||||
auto clipB = clipVertices[(i + 1) % clipVertices.size()];
|
||||
|
||||
auto intersection = lineSegmentIntersect(clipA, clipB, posA, posB);
|
||||
if (intersection < 0 || intersection > 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto clipDirection = directionFromLine(clipA, clipB, posA);
|
||||
auto intersectionPoint = posA + (posB - posA) * intersection;
|
||||
|
||||
if (clipDirection >= 0) {
|
||||
posA = intersectionPoint;
|
||||
} else {
|
||||
posB = intersectionPoint;
|
||||
}
|
||||
}
|
||||
|
||||
pge->DrawLineDecal(posA + offset, posB + offset, p);
|
||||
}
|
||||
|
||||
void olc::ViewPort::drawClippedDecal(Decal *decal,
|
||||
const vf2d *points,
|
||||
const vf2d *uvs,
|
||||
const Pixel *col,
|
||||
uint32_t elements) const {
|
||||
std::vector<vf2d> outputList{points, points + elements};
|
||||
std::vector<vf2d> outputUvs{uvs, uvs + elements};
|
||||
std::vector<Pixel> outputCols{col, col + elements};
|
||||
|
||||
for (auto i = 0u; i < clipVertices.size(); i++) {
|
||||
auto clipA = clipVertices[i];
|
||||
auto clipB = clipVertices[(i + 1) % 4];
|
||||
|
||||
auto inputList{outputList};
|
||||
auto inputUvs{outputUvs};
|
||||
auto inputCols{outputCols};
|
||||
outputList.clear();
|
||||
outputUvs.clear();
|
||||
outputCols.clear();
|
||||
|
||||
for (auto i = 0u; i < inputList.size(); i++) {
|
||||
auto polygonA = inputList[i];
|
||||
auto polygonB = inputList[(i + 1) % inputList.size()];
|
||||
auto uvA = inputUvs[i];
|
||||
auto uvB = inputUvs[(i + 1) % inputList.size()];
|
||||
auto colA = inputCols[i];
|
||||
auto colB = inputCols[(i + 1) % inputList.size()];
|
||||
|
||||
auto intersection =
|
||||
lineSegmentIntersect(clipA, clipB, polygonA, polygonB);
|
||||
auto intersectionPoint =
|
||||
polygonA + (polygonB - polygonA) * intersection;
|
||||
auto intersectionUv = uvA + (uvB - uvA) * intersection;
|
||||
auto intersectionCol = PixelLerp(colA, colB, intersection);
|
||||
|
||||
float aDirection = directionFromLine(clipA, clipB, polygonA);
|
||||
float bDirection = directionFromLine(clipA, clipB, polygonB);
|
||||
|
||||
if (bDirection <= 0) {
|
||||
if (aDirection > 0) {
|
||||
outputList.push_back(intersectionPoint);
|
||||
outputUvs.push_back(intersectionUv);
|
||||
outputCols.push_back(intersectionCol);
|
||||
}
|
||||
outputList.push_back(polygonB);
|
||||
outputUvs.push_back(uvB);
|
||||
outputCols.push_back(colB);
|
||||
} else if (aDirection <= 0) {
|
||||
outputList.push_back(intersectionPoint);
|
||||
outputUvs.push_back(intersectionUv);
|
||||
outputCols.push_back(intersectionCol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (outputList.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto &point : outputList) {
|
||||
point += offset;
|
||||
}
|
||||
|
||||
pge->DrawExplicitDecal(decal,
|
||||
outputList.data(),
|
||||
outputUvs.data(),
|
||||
outputCols.data(),
|
||||
outputList.size());
|
||||
}
|
||||
|
||||
float olc::ViewPort::lineSegmentIntersect(vf2d lineA,
|
||||
vf2d lineB,
|
||||
vf2d segmentA,
|
||||
vf2d segmentB) {
|
||||
return ((lineA.x - segmentA.x) * (lineA.y - lineB.y)
|
||||
- (lineA.y - segmentA.y) * (lineA.x - lineB.x))
|
||||
/ ((lineA.x - lineB.x) * (segmentA.y - segmentB.y)
|
||||
- (lineA.y - lineB.y) * (segmentA.x - segmentB.x));
|
||||
}
|
||||
|
||||
float olc::ViewPort::directionFromLine(vf2d lineA, vf2d lineB, vf2d point) {
|
||||
return (lineB.x - lineA.x) * (point.y - lineA.y)
|
||||
- (point.x - lineA.x) * (lineB.y - lineA.y);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col, const olc::vf2d& scale){
|
||||
olc::vf2d spos = { 0.0f, 0.0f };
|
||||
Pixel textCol=col;
|
||||
const auto hexToNumber=[](char c){
|
||||
if(c<='9')return c-'0';
|
||||
return (c-'A')+10;
|
||||
};
|
||||
for (int skip=0,index=-1;auto c : sText)
|
||||
{
|
||||
index++;
|
||||
if(skip){
|
||||
skip--;
|
||||
continue;
|
||||
}
|
||||
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||
if (c == '\n')
|
||||
{
|
||||
spos.x = 0; spos.y += 8.0f * scale.y;
|
||||
}
|
||||
else if (c == '\t')
|
||||
{
|
||||
spos.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||
}
|
||||
else if (c>=-128&&c<-105)
|
||||
{
|
||||
textCol={PixelGameEngine::charToColor[c].r,PixelGameEngine::charToColor[c].g,PixelGameEngine::charToColor[c].b,col.a};
|
||||
}
|
||||
else if (c=='#')
|
||||
{
|
||||
skip=6;
|
||||
textCol=BLACK;
|
||||
for(int i=1;i<7;i++){
|
||||
if(i<3){
|
||||
textCol.r*=16;
|
||||
textCol.r+=hexToNumber(sText[index+i]);
|
||||
}else
|
||||
if(i<5){
|
||||
textCol.g*=16;
|
||||
textCol.g+=hexToNumber(sText[index+i]);
|
||||
}else{
|
||||
textCol.b*=16;
|
||||
textCol.b+=hexToNumber(sText[index+i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int32_t ox = (c - 32) % 16;
|
||||
int32_t oy = (c - 32) / 16;
|
||||
DrawPartialDecal(pos + spos, pge->GetFontDecal(), {float(ox) * 8.0f, float(oy) * 8.0f}, {8.0f, 8.0f}, scale, textCol);
|
||||
spos.x += 8.0f * scale.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col, const olc::vf2d& scale){
|
||||
struct DecalData{
|
||||
Decal*decal;
|
||||
float expireTime=0.0f;
|
||||
};
|
||||
if(sText.length()==0)return;
|
||||
static std::map<std::u32string,DecalData>garbageCollector;
|
||||
std::u32string key=font.GetFontName()+U"_"+sText;
|
||||
if(!garbageCollector.count(key)){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
||||
garbageCollector[key].decal=font.RenderStringToDecal(sText,WHITE);
|
||||
}
|
||||
garbageCollector[key].expireTime=pge->GetRuntime()+120.0f;
|
||||
std::erase_if(garbageCollector,[&](auto&key){
|
||||
if(key.second.expireTime<pge->GetRuntime()){
|
||||
delete key.second.decal;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
DrawDecal(pos,garbageCollector[key].decal,scale/4,col);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawStringPropDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col, const olc::vf2d& scale){
|
||||
olc::vf2d spos = { 0.0f, 0.0f };
|
||||
Pixel textCol=col;
|
||||
const auto hexToNumber=[](char c){
|
||||
if(c<='9')return c-'0';
|
||||
return (c-'A')+10;
|
||||
};
|
||||
for (int skip=0,index=-1;auto c : sText)
|
||||
{
|
||||
index++;
|
||||
if(skip){
|
||||
skip--;
|
||||
continue;
|
||||
}
|
||||
if(c=='\r')continue; //Ignore carriage returns. Stupid Linux.
|
||||
if (c == '\n')
|
||||
{
|
||||
spos.x = 0; spos.y += 8.0f * scale.y;
|
||||
}
|
||||
else if (c == '\t')
|
||||
{
|
||||
spos.x += 8.0f * float(nTabSizeInSpaces) * scale.x;
|
||||
}
|
||||
else if (c>=-128&&c<-105)
|
||||
{
|
||||
textCol={PixelGameEngine::charToColor[c].r,PixelGameEngine::charToColor[c].g,PixelGameEngine::charToColor[c].b,col.a};
|
||||
}
|
||||
else if (c==PixelGameEngine::Reset[0])
|
||||
{
|
||||
textCol=col;
|
||||
}
|
||||
else if (c=='#')
|
||||
{
|
||||
skip=6;
|
||||
textCol=BLACK;
|
||||
for(int i=1;i<7;i++){
|
||||
if(i<3){
|
||||
textCol.r*=16;
|
||||
textCol.r+=hexToNumber(sText[index+i]);
|
||||
}else
|
||||
if(i<5){
|
||||
textCol.g*=16;
|
||||
textCol.g+=hexToNumber(sText[index+i]);
|
||||
}else{
|
||||
textCol.b*=16;
|
||||
textCol.b+=hexToNumber(sText[index+i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int32_t ox = (c - 32) % 16;
|
||||
int32_t oy = (c - 32) / 16;
|
||||
DrawPartialDecal(pos + spos, pge->GetFontDecal(), { float(ox) * 8.0f + float(pge->vFontSpacing[c - 32].x), float(oy) * 8.0f }, { float(pge->vFontSpacing[c - 32].y), 8.0f }, scale, textCol);
|
||||
spos.x += float(pge->vFontSpacing[c - 32].y) * scale.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawShadowStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float shadowSizeFactor){
|
||||
std::string strippedText=sText;
|
||||
std::erase_if(strippedText,[](char chr){return chr<0;});
|
||||
int skip=0;
|
||||
std::erase_if(strippedText,[&](char chr){if(skip>0){skip--;return true;}if(chr=='#'){skip=6;return true;}return false;});
|
||||
for(float y=-shadowSizeFactor;y<=shadowSizeFactor+0.1;y+=shadowSizeFactor/2){
|
||||
for(float x=-shadowSizeFactor;x<=shadowSizeFactor+0.1;x+=shadowSizeFactor/2){
|
||||
if(x!=0||y!=0){
|
||||
DrawStringDecal(pos+vf2d{x,y}, strippedText, shadowCol,scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
DrawStringDecal(pos, sText, col,scale);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawShadowStringPropDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float shadowSizeFactor){
|
||||
std::string strippedText=sText;
|
||||
std::erase_if(strippedText,[](char chr){return chr<0;});
|
||||
int skip=0;
|
||||
std::erase_if(strippedText,[&](char chr){if(skip>0){skip--;return true;}if(chr=='#'){skip=6;return true;}return false;});
|
||||
for(float y=-shadowSizeFactor;y<=shadowSizeFactor+0.1;y+=shadowSizeFactor/2){
|
||||
for(float x=-shadowSizeFactor;x<=shadowSizeFactor+0.1;x+=shadowSizeFactor/2){
|
||||
if(x!=0||y!=0){
|
||||
DrawStringPropDecal(pos+vf2d{x,y}, strippedText, shadowCol,scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
DrawStringPropDecal(pos, sText, col,scale);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale,const float shadowSizeFactor){
|
||||
struct DecalData{
|
||||
Decal*decal;
|
||||
float expireTime=0.0f;
|
||||
};
|
||||
if(sText.length()==0)return;
|
||||
static std::map<std::u32string,DecalData>garbageCollector;
|
||||
std::u32string key=font.GetFontName()+U"_"+sText;
|
||||
if(!garbageCollector.count(key)){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
||||
garbageCollector[key].decal=font.RenderStringToDecal(sText,WHITE);
|
||||
}
|
||||
garbageCollector[key].expireTime=pge->GetRuntime()+120.0f;
|
||||
std::erase_if(garbageCollector,[&](auto&key){
|
||||
if(key.second.expireTime<pge->GetRuntime()){
|
||||
delete key.second.decal;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
for(float y=-shadowSizeFactor;y<=shadowSizeFactor+0.1;y+=shadowSizeFactor/2){
|
||||
for(float x=-shadowSizeFactor;x<=shadowSizeFactor+0.1;x+=shadowSizeFactor/2){
|
||||
if(x!=0||y!=0){
|
||||
DrawDecal(pos+vf2d{x,y},garbageCollector[key].decal,scale/4,shadowCol);
|
||||
}
|
||||
}
|
||||
}
|
||||
DrawDecal(pos,garbageCollector[key].decal,scale/4,col);
|
||||
}
|
||||
|
||||
void olc::ViewPort::DrawDropShadowStringDecal(Font&font, const olc::vf2d& pos, const std::u32string& sText, const Pixel col, const Pixel shadowCol, const olc::vf2d& scale){
|
||||
struct DecalData{
|
||||
Decal*decal;
|
||||
float expireTime=0.0f;
|
||||
};
|
||||
if(sText.length()==0)return;
|
||||
static std::map<std::u32string,DecalData>garbageCollector;
|
||||
std::u32string key=font.GetFontName()+U"_"+sText;
|
||||
if(!garbageCollector.count(key)){ //If the text key already exists, don't have to recreate the decal, just update the expire time.
|
||||
garbageCollector[key].decal=font.RenderStringToDecal(sText,WHITE);
|
||||
}
|
||||
garbageCollector[key].expireTime=pge->GetRuntime()+120.0f;
|
||||
std::erase_if(garbageCollector,[&](auto&key){
|
||||
if(key.second.expireTime<pge->GetRuntime()){
|
||||
delete key.second.decal;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
DrawDecal(pos+vf2d{0,0.5f},garbageCollector[key].decal,scale/4,shadowCol);
|
||||
DrawDecal(pos+vf2d{0.5f,0},garbageCollector[key].decal,scale/4,shadowCol);
|
||||
DrawDecal(pos+vf2d{0.5f,0.5f},garbageCollector[key].decal,scale/4,shadowCol);
|
||||
DrawDecal(pos,garbageCollector[key].decal,scale/4,col);
|
||||
}
|
||||
|
||||
#endif
|
@ -1171,6 +1171,8 @@ namespace olc
|
||||
void ClearBuffer(Pixel p, bool bDepth = true);
|
||||
// Returns the font image
|
||||
olc::Sprite* GetFontSprite();
|
||||
// Returns the font image
|
||||
olc::Decal* GetFontDecal();
|
||||
|
||||
// Clip a line segment to visible area
|
||||
bool ClipLineToScreen(olc::vi2d& in_p1, olc::vi2d& in_p2);
|
||||
@ -1254,6 +1256,8 @@ namespace olc
|
||||
public: // Branding
|
||||
std::string sAppName;
|
||||
|
||||
friend class ViewPort;
|
||||
|
||||
private: // Inner mysterious workings
|
||||
olc::Sprite* pDrawTarget = nullptr;
|
||||
Pixel::Mode nPixelMode = Pixel::NORMAL;
|
||||
@ -2461,6 +2465,8 @@ namespace olc
|
||||
|
||||
olc::Sprite* PixelGameEngine::GetFontSprite()
|
||||
{ return fontRenderable.Sprite(); }
|
||||
olc::Decal* PixelGameEngine::GetFontDecal()
|
||||
{ return fontRenderable.Decal(); }
|
||||
|
||||
bool PixelGameEngine::ClipLineToScreen(olc::vi2d& in_p1, olc::vi2d& in_p2)
|
||||
{
|
||||
|
@ -39,6 +39,8 @@ All rights reserved.
|
||||
//#define OLC_PGE_HEADLESS
|
||||
#define OLC_PGEX_TTF
|
||||
#include "olcPGEX_TTF.h"
|
||||
#define OLC_PGEX_VIEWPORT
|
||||
#include "olcPGEX_ViewPort.h"
|
||||
#define OLC_PGE_APPLICATION
|
||||
#include "olcPixelGameEngine.h"
|
||||
#define OLC_PGEX_TRANSFORMEDVIEW
|
||||
|
Loading…
x
Reference in New Issue
Block a user