Giter Club home page Giter Club logo

siv3d / opensiv3d Goto Github PK

View Code? Open in Web Editor NEW
975.0 44.0 132.0 1.73 GB

C++20 framework for creative coding 🎮🎨🎹 / Cross-platform support (Windows, macOS, Linux, and the Web)

Home Page: https://siv3d.github.io/

License: MIT License

C++ 84.66% Objective-C++ 0.87% CMake 1.10% HLSL 0.85% GLSL 2.10% AngelScript 0.14% C 9.24% Objective-C 0.03% JavaScript 0.40% Metal 0.01% HTML 0.10% WGSL 0.50%
game-engine gamedev game-developement cpp cpp20 c-plus-plus game cross-platform

opensiv3d's Introduction

Siv3D

Siv3D logo

Siv3D (OpenSiv3D) is a C++20 framework for creative coding (2D/3D games, media art, visualizers, and simulators). Siv3D applications run on Windows, macOS, Linux, and the Web.

Features

  • Graphics
    • Advanced 2D graphics
    • Basic 3D graphics (Wavefront OBJ, primitive shapes)
    • Custom vertex / pixel shaders (HLSL, GLSL)
    • Text rendering (Bitmap, SDF, MSDF)
    • PNG, JPEG, BMP, SVG, GIF, Animated GIF, TGA, PPM, WebP, TIFF
    • Unicode 15.1 emojis and 7,000+ icons
    • Image processing
    • Video rendering
  • Audio
    • WAVE, MP3, AAC, OggVorbis, Opus, MIDI, WMA*, FLAC*, AIFF*
    • Adjustable volume, pan, play speed and pitch
    • File streaming (WAVE, MP3, OggVorbis)
    • Fade in and fade out
    • Looping
    • Mixing busses
    • Filters (LPF, HPF, echo, reverb)
    • FFT
    • SoundFont rendering
    • Text to speech*
  • Input
    • Mouse
    • Keyboard
    • Gamepad
    • Webcam
    • Microphone
    • Joy-Con / Pro Controller
    • XInput*
    • Digital drawing tablet*
    • Leap Motion*
  • Window
    • Fullscreen mode
    • High DPI support
    • Window styles (sizable, borderless)
    • File dialog
    • Drag & drop
    • Message box
    • Toast notification*
  • Network and communication
    • HTTP client
    • Multiplayer (with Photon SDK)
    • TCP communication
    • Serial communication
    • Interprocess communication (pipe)
    • OSC (Open Sound Control)
  • Math
    • Vector and matrix classes (Point, Float2, Vec2, Float3, Vec3, Float4, Vec4, Mat3x2, Mat3x3, Mat4x4, SIMD_Float4, Quaternion)
    • 2D shape classes (Line, Circle, Ellipse, Rect, RectF, Triangle, Quad, RoundRect, Polygon, MultiPolygon, LineString, Spline2D, Bezier2, Bezier3)
    • 3D shape classes (Plane, InfinitePlane, Sphere, Box, OrientedBox, Ray, Line3D, Triangle3D, ViewFrustum, Disc, Cylinder, Cone)
    • Color classes (Color, ColorF, HSV)
    • Polar / cylindrical / spherical coordinates system
    • 2D / 3D shape intersection
    • 2D / 3D geometry processing
    • Rectangle packing
    • Planar subdivisions
    • Linear and gamma color space
    • Pseudo random number generators
    • Interpolation, easing, and smoothing
    • Perlin noise
    • Math parser
    • Navigation mesh
    • Extended arithmetic types (HalfFloat, int128, uint128, BigInt, BigFloat)
  • String and Text Processing
    • Advanced String class (String, StringView)
    • Unicode conversion
    • Regular expression
    • {fmt} style text formatting
    • Text reader / writer classes
    • CSV / INI / JSON / XML / TOML reader classes
    • CSV / INI / JSON writer classes
    • JSON Validation
  • Misc
    • Basic GUI (button, slider, radio buttons, checkbox, text box, color picker, list box, menu bar, table)
    • Integrated 2D physics engine (Box2D)
    • Advanced array / 2D array classes (Array, Grid)
    • Kd-tree
    • Disjoint set
    • Asynchronous asset file streaming
    • Data compression (zlib, Zstandard)
    • Transitions between scenes
    • File system
    • Directory watcher
    • QR code reader / writer
    • GeoJSON
    • Date and time
    • Stopwatch and timer
    • Logging
    • Serialization
    • UUID
    • Child process
    • Clipboard
    • Power status
    • Scripting (AngelScript)
    • OpenAI API (Chat, Vision, Image, Speech, Embedding)

* Some features are limited to specific platforms

How to Install Siv3D + Tutorial

v0.6.14 | released 5 February 2024 | Release Notes

Platform SDK Requirements
Windows Download SDK /
SDK をダウンロード
- Windows 10 / 11 (64-bit)
- Microsoft Visual C++ 2022 17.7
- Windows 10 SDK
- Intel / AMD CPU
macOS Download SDK /
SDK をダウンロード
- macOS Big Sur / Monterey / Ventura
- Xcode 12.5 or newer
- Intel CPU / Apple Silicon (Rosetta mode)*
- OpenGL 4.1 compatible hardware
Linux Compiling for Linux /
Linux 版のビルド
- GCC 9.3.0 (with Boost 1.71.0) / GCC 11.2 (with Boost 1.74.0)
- Intel / AMD CPU
- OpenGL 4.1 compatible hardware
Web (experimental**) Compiling for Web /
Web 版のビルド
Web browser with WebAssembly and WebGL2 support

* Native Apple Silicon support will be added in the future release. You can build and run Siv3D in Rosetta mode
** Some functionality may be missing or limited

Community

Miscellaneous

Supporting the Project

If you would like to support the project financially, visit my GitHub Sponsors page. Your support will accelerate the development of this exciting framework.

💗 https://github.com/sponsors/Reputeless

Examples

1. Hello, Siv3D!

Screenshot

# include <Siv3D.hpp>

void Main()
{
	// 背景の色を設定する | Set the background color
	Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });

	// 画像ファイルからテクスチャを作成する | Create a texture from an image file
	const Texture texture{ U"example/windmill.png" };

	// 絵文字からテクスチャを作成する | Create a texture from an emoji
	const Texture emoji{ U"🦖"_emoji };

	// 太文字のフォントを作成する | Create a bold font with MSDF method
	const Font font{ FontMethod::MSDF, 48, Typeface::Bold };

	// テキストに含まれる絵文字のためのフォントを作成し、font に追加する | Create a font for emojis in text and add it to font as a fallback
	const Font emojiFont{ 48, Typeface::ColorEmoji };
	font.addFallback(emojiFont);

	// ボタンを押した回数 | Number of button presses
	int32 count = 0;

	// チェックボックスの状態 | Checkbox state
	bool checked = false;

	// プレイヤーの移動スピード | Player's movement speed
	double speed = 200.0;

	// プレイヤーの X 座標 | Player's X position
	double playerPosX = 400;

	// プレイヤーが右を向いているか | Whether player is facing right
	bool isPlayerFacingRight = true;

	while (System::Update())
	{
		// テクスチャを描く | Draw the texture
		texture.draw(20, 20);

		// テキストを描く | Draw text
		font(U"Hello, Siv3D!🎮").draw(64, Vec2{ 20, 340 }, ColorF{ 0.2, 0.4, 0.8 });

		// 指定した範囲内にテキストを描く | Draw text within a specified area
		font(U"Siv3D (シブスリーディー) は、ゲームやアプリを楽しく簡単な C++ コードで開発できるフレームワークです。")
			.draw(18, Rect{ 20, 430, 480, 200 }, Palette::Black);

		// 長方形を描く | Draw a rectangle
		Rect{ 540, 20, 80, 80 }.draw();

		// 角丸長方形を描く | Draw a rounded rectangle
		RoundRect{ 680, 20, 80, 200, 20 }.draw(ColorF{ 0.0, 0.4, 0.6 });

		// 円を描く | Draw a circle
		Circle{ 580, 180, 40 }.draw(Palette::Seagreen);

		// 矢印を描く | Draw an arrow
		Line{ 540, 330, 760, 260 }.drawArrow(8, SizeF{ 20, 20 }, ColorF{ 0.4 });

		// 半透明の円を描く | Draw a semi-transparent circle
		Circle{ Cursor::Pos(), 40 }.draw(ColorF{ 1.0, 0.0, 0.0, 0.5 });

		// ボタン | Button
		if (SimpleGUI::Button(U"count: {}"_fmt(count), Vec2{ 520, 370 }, 120, (checked == false)))
		{
			// カウントを増やす | Increase the count
			++count;
		}

		// チェックボックス | Checkbox
		SimpleGUI::CheckBox(checked, U"Lock \U000F033E", Vec2{ 660, 370 }, 120);

		// スライダー | Slider
		SimpleGUI::Slider(U"speed: {:.1f}"_fmt(speed), speed, 100, 400, Vec2{ 520, 420 }, 140, 120);

		// 左キーが押されていたら | If left key is pressed
		if (KeyLeft.pressed())
		{
			// プレイヤーが左に移動する | Player moves left
			playerPosX = Max((playerPosX - speed * Scene::DeltaTime()), 60.0);
			isPlayerFacingRight = false;
		}

		// 右キーが押されていたら | If right key is pressed
		if (KeyRight.pressed())
		{
			// プレイヤーが右に移動する | Player moves right
			playerPosX = Min((playerPosX + speed * Scene::DeltaTime()), 740.0);
			isPlayerFacingRight = true;
		}

		// プレイヤーを描く | Draw the player
		emoji.scaled(0.75).mirrored(isPlayerFacingRight).drawAt(playerPosX, 540);
	}
}

2. Breakout

Screenshot

# include <Siv3D.hpp>

void Main()
{
	// 1 つのブロックのサイズ | Size of a single block
	constexpr Size BrickSize{ 40, 20 };

	// ボールの速さ(ピクセル / 秒) | Ball speed (pixels / second)
	constexpr double BallSpeedPerSec = 480.0;

	// ボールの速度 | Ball velocity
	Vec2 ballVelocity{ 0, -BallSpeedPerSec };

	// ボール | Ball
	Circle ball{ 400, 400, 8 };

	// ブロックの配列 | Array of bricks
	Array<Rect> bricks;

	for (int32 y = 0; y < 5; ++y)
	{
		for (int32 x = 0; x < (Scene::Width() / BrickSize.x); ++x)
		{
			bricks << Rect{ (x * BrickSize.x), (60 + y * BrickSize.y), BrickSize };
		}
	}

	while (System::Update())
	{
		// パドル | Paddle
		const Rect paddle{ Arg::center(Cursor::Pos().x, 500), 60, 10 };

		// ボールを移動させる | Move the ball
		ball.moveBy(ballVelocity * Scene::DeltaTime());

		// ブロックを順にチェックする | Check bricks in sequence
		for (auto it = bricks.begin(); it != bricks.end(); ++it)
		{
			// ブロックとボールが交差していたら | If block and ball intersect
			if (it->intersects(ball))
			{
				// ブロックの上辺、または底辺と交差していたら | If ball intersects with top or bottom of the block
				if (it->bottom().intersects(ball) || it->top().intersects(ball))
				{
					// ボールの速度の Y 成分の符号を反転する | Reverse the sign of the Y component of the ball's velocity
					ballVelocity.y *= -1;
				}
				else // ブロックの左辺または右辺と交差していたら
				{
					// ボールの速度の X 成分の符号を反転する | Reverse the sign of the X component of the ball's velocity
					ballVelocity.x *= -1;
				}

				// ブロックを配列から削除する(イテレータは無効になる) | Remove the block from the array (the iterator becomes invalid)
				bricks.erase(it);

				// これ以上チェックしない | Do not check any more
				break;
			}
		}

		// 天井にぶつかったら | If the ball hits the ceiling
		if ((ball.y < 0) && (ballVelocity.y < 0))
		{
			// ボールの速度の Y 成分の符号を反転する | Reverse the sign of the Y component of the ball's velocity
			ballVelocity.y *= -1;
		}

		// 左右の壁にぶつかったら | If the ball hits the left or right wall
		if (((ball.x < 0) && (ballVelocity.x < 0))
			|| ((Scene::Width() < ball.x) && (0 < ballVelocity.x)))
		{
			// ボールの速度の X 成分の符号を反転する | Reverse the sign of the X component of the ball's velocity
			ballVelocity.x *= -1;
		}

		// パドルにあたったら | If the ball hits the left or right wall
		if ((0 < ballVelocity.y) && paddle.intersects(ball))
		{
			// パドルの中心からの距離に応じてはね返る方向(速度ベクトル)を変える | Change the direction (velocity vector) of the ball depending on the distance from the center of the paddle
			ballVelocity = Vec2{ (ball.x - paddle.center().x) * 10, -ballVelocity.y }.setLength(BallSpeedPerSec);
		}

		// すべてのブロックを描画する | Draw all the bricks
		for (const auto& brick : bricks)
		{
			// ブロックの Y 座標に応じて色を変える | Change the color of the brick depending on the Y coordinate
			brick.stretched(-1).draw(HSV{ brick.y - 40 });
		}

		// マウスカーソルを非表示にする | Hide the mouse cursor
		Cursor::RequestStyle(CursorStyle::Hidden);

		// ボールを描く | Draw the ball
		ball.draw();

		// パドルを描く | Draw the paddle
		paddle.rounded(3).draw();
	}
}

3. Hello, 3D world!

Screenshot

# include <Siv3D.hpp>

void Main()
{
	// Resize the window and scene to 1280x720
	Window::Resize(1280, 720);

	// Background color (remove SRGB curve for a linear workflow)
	const ColorF backgroundColor = ColorF{ 0.4, 0.6, 0.8 }.removeSRGBCurve();

	// Texture for UV check (mipmapped. treat as SRGB texture in a linear workflow)
	const Texture uvChecker{ U"example/texture/uv.png", TextureDesc::MippedSRGB };

	// Multisample RenderTexture for a linear workflow
	const MSRenderTexture renderTexture{ Scene::Size(), TextureFormat::R8G8B8A8_Unorm_SRGB, HasDepth::Yes };

	// 3D debug camera (free camera)
	// Vertical FOV: 30°, Eye position: (10, 16, -32)
	// Move: [W][S][A][D][E][X], View: [arrow keys]
	DebugCamera3D camera{ renderTexture.size(), 30_deg, Vec3{ 10, 16, -32 } };

	while (System::Update())
	{
		// Update a camera
		camera.update(2.0);

		// Set up a camera in the current 3D scene
		Graphics3D::SetCameraTransform(camera);

		// [3D rendering]
		{
			// Clear renderTexture with the background color,
			// then make renderTexture the render target for the current 3D scene
			const ScopedRenderTarget3D target{ renderTexture.clear(backgroundColor) };

			// Draw a floor
			Plane{ 64 }.draw(uvChecker);

			// Draw a box
			Box{ -8,2,0,4 }.draw(ColorF{ 0.8, 0.6, 0.4 }.removeSRGBCurve());

			// Draw a sphere
			Sphere{ 0,2,0,2 }.draw(ColorF{ 0.4, 0.8, 0.6 }.removeSRGBCurve());

			// Draw a cylinder
			Cylinder{ 8, 2, 0, 2, 4 }.draw(ColorF{ 0.6, 0.4, 0.8 }.removeSRGBCurve());
		}

		// [2D rendering]
		{
			// Flush 3D rendering commands before multisample resolve
			Graphics3D::Flush();

			// Multisample resolve
			renderTexture.resolve();

			// Transfer renderTexture to the current 2D scene (default scene)
			Shader::LinearToScreen(renderTexture);
		}
	}
}

opensiv3d's People

Contributors

agehama avatar azaika avatar comefrombottom avatar ebishu-0309 avatar falrnd avatar fuyutsubaki avatar kestrel-90r avatar kurokoji avatar luke256 avatar m4saka avatar mak1a avatar murakamishun avatar nokotan avatar ogame3334 avatar para7 avatar polyester-ctrl avatar raclamusi avatar reputeless avatar ryoga-exe avatar sthairno avatar tana avatar taotao54321 avatar tetsurom avatar tomolatoon avatar voidproc avatar wynd2608 avatar yama-can avatar yksake avatar yunba28 avatar yurkth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opensiv3d's Issues

drawFrame()が遅い

Triangle::drawFrame()Polygon::drawFrame() が遅いので、高速化してほしいです。

JSONValuer::hasMember関数の命名

JSONValueがJSONObjectである時に、ある名前の要素が存在するかどうかを判定する関数の名前は現在 hasMember となっていますが、C++においては contains といった名前の方が一般的に思えます。

siv3d_v0.1.5_macOS でビルドは通るけどウィンドウが表示されない

siv3d_v0.0.8_macOS では問題なく起動しました。

macOS Sierra (10.12.5)
XCode 8.3.3

MacBook Pro (13-inch, Late 2011)
2.8 GHz Intel Core i7
8 GB 1333 MHz DDR3
Macintosh HD
Intel HD Graphics 3000 512 MB

実行時に表示されるメッセージです。

Siv3D for macOS
[info]ℹ️ CPU vendor: GenuineIntel
[info]ℹ️ CPU name:        Intel(R) Core(TM) i7-2640M CPU @ 2.80GHz
[info]ℹ️ Instruction set extensions: SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AES-NI, AVX

Geometry2D::Contains() のバグ

Geometry2D::Contains(const Triangle& a, const Line& b)
Geometry2D::Contains(const Quad& a, const Line& b) の実装で Line::end() が使われていない。

ParseIntについて

ParseIntにL"08"、L"09"を代入した場合に0になるようです。
L"01"~L"07"までは1~7が返るので、報告しておきます。

# include <Siv3D.hpp>

void Main()
{
	Window::Resize(640, 640);
	while (System::Update())
	{
		ClearPrint();
		for (int i = 0; i < 10; i++)
		{
			Print << Format(i, L":") << ParseInt<int>(Format(i));
			Print << Format(L"0", i, L":") << ParseInt<int>(Format(L"0", i));
		}
	}
}

TextBoxを有効化する方法

TextBoxをTabキーなどでアクティブな状態にしたいのですが、そのような機能はありますか?
TextBox::update(true)
とした場合、カーソルがTextBoxの上にないと有効化されないため、使いづらいです。

Circular型の改造案

namespace s3d
{
	template<int32 Oclock>
	struct Polar
	{
	private:

		static constexpr double Clock() noexcept
		{
			return Oclock * (Math::TwoPi / 12);
		}

	public:

		// 中心
		Vec2 center;

		// 半径
		double r;

		// 角度
		double theta;

		//デフォルトコンストラクタ
		Polar() = default;

		//コピーコンストラクタ
		Polar(const Polar& polar) noexcept = default;

		Polar(const Vec2& _center, double _r, double _theta) noexcept
			: center(_center)
			, r(_r)
			, theta(_theta)
		{}

		// 始点と終点を設定し、その関係を極座標で表現します
		Polar(const Vec2& center, const Vec2& pos)
		{
			const Vec2 vec = pos - center;

			*this = Polar(pos, vec.length(), atan2(vec.y, vec.x) - Clock());
		}

		Polar operator +() const noexcept
		{
			return *this;
		}

		Polar operator -() const noexcept
		{
			return rotated(Math::Pi);
		}

		Vec2 operator +(const Vec2& v) const noexcept
		{
			return toVec2() + v;
		}

		Vec2 operator -(const Vec2& v) const noexcept
		{
			return toVec2() - v;
		}

		// 極座標が示す先の座標を取得
		Vec2 toVec2() const
		{
			return center.movedBy(std::sin(theta + Clock()) * r, -std::cos(theta + Clock()) * r);
		}

		Float2 toFloat2() const
		{
			return { center.x + std::sin(theta + Clock()) * r, center.y - std::cos(theta + Clock()) * r };
		}

		operator Vec2() const noexcept
		{
			return toVec2();
		}

		// 始点を移動
		Polar& setCenter(const Vec2& _center)
		{
			center = _center;
			return *this;
		}

		// 極座標が指し示す先を座標で指定し直す
		Polar& setPos(const Vec2& to)
		{
			*this = Polar(center, to);
			return *this;
		}

		// 一時的に回転させる
		Polar rotated(double _theta) const
		{
			Polar polar(*this);
			polar.theta += _theta;
			return polar;
		}

		// 半径を変更した新しいオブジェクトを返す
		Polar resized(double _r) const noexcept
		{
			Polar polar(*this);
			polar.r = _r;
			return polar;
		}

		// 半径に倍率をかけた新しいオブジェクトを返す
		Polar scaled(double _scale) const
		{
			Polar polar(*this);
			polar.r *= _scale;
			return polar;
		}

		// 始点と終点を結んだ線を返す
		Line Polar::getLine() const
		{
			return Line(center, toVec2());
		}
	};

	using Polar3 = Polar<3>;
}

Shape2D::CreateFlag()の実装案

std::array<Shape2D, 2> CreateTriangleFlag(double poleHeight, double poleWidth, double flagHeight, double flagWidth, const Vec2& pos)
{
	const float poleHeightF = static_cast<float>(poleHeight);
	const float poleHalfWidthF = static_cast<float>(poleWidth)*0.5f;
	const float flagHeightF = static_cast<float>(flagHeight);
	const float flagWidthF = static_cast<float>(flagWidth);

	Array<Float2> verticesPole(4, pos);
	Array<uint32> indicesPole(6);
	verticesPole[0].moveBy(-poleHalfWidthF, -poleHeightF);
	verticesPole[1].moveBy(+poleHalfWidthF, -poleHeightF);
	verticesPole[2].moveBy(+poleHalfWidthF, 0.0f);
	verticesPole[3].moveBy(-poleHalfWidthF, 0.0f);
	indicesPole = { 0,1,2, 2,3,0 };

	Array<Float2> verticesFlag(3, verticesPole[1]);
	Array<uint32> indicesFlag(3);

	verticesFlag[1].moveBy(flagWidthF, flagHeightF*0.5f);
	verticesFlag[2].moveBy(0.0f, flagHeightF);
	indicesFlag = { 0,1,2 };

	return { Shape2D{verticesPole,indicesPole}, Shape2D{verticesFlag,indicesFlag} };
}

std::array<Shape2D, 2> CreateRectFlag(double poleHeight, double poleWidth, double flagHeight, double flagWidth, const Vec2& pos)
{
	const float poleHeightF = static_cast<float>(poleHeight);
	const float poleHalfWidthF = static_cast<float>(poleWidth)*0.5f;
	const float flagHeightF = static_cast<float>(flagHeight);
	const float flagWidthF = static_cast<float>(flagWidth);

	Array<Float2> verticesPole(4, pos);
	Array<uint32> indicesPole(6);
	verticesPole[0].moveBy(-poleHalfWidthF, -poleHeightF);
	verticesPole[1].moveBy(+poleHalfWidthF, -poleHeightF);
	verticesPole[2].moveBy(+poleHalfWidthF, 0.0f);
	verticesPole[3].moveBy(-poleHalfWidthF, 0.0f);
	indicesPole = { 0,1,2, 2,3,0 };

	Array<Float2> verticesFlag(4, verticesPole[1]);
	Array<uint32> indicesFlag(6);

	verticesFlag[1].moveBy(flagWidthF, 0.0f);
	verticesFlag[2].moveBy(flagWidthF, flagHeightF);
	verticesFlag[3].moveBy(0.0f, flagHeightF);
	indicesFlag = { 0,1,2, 2,3,0 };

	return { Shape2D{ verticesPole,indicesPole }, Shape2D{ verticesFlag,indicesFlag } };
}

std::array<Shape2D, 2> CreateSwallowtailFlag(double poleHeight, double poleWidth, double flagHeight, double flagWidthLarger, double flagWidthSmaller, const Vec2& pos)
{
	const float poleHeightF = static_cast<float>(poleHeight);
	const float poleHalfWidthF = static_cast<float>(poleWidth)*0.5f;
	const float flagHeightF = static_cast<float>(flagHeight);
	const float flagWidthLargerF = static_cast<float>(flagWidthLarger);
	const float flagWidthSmallerF = static_cast<float>(flagWidthSmaller);

	Array<Float2> verticesPole(4, pos);
	Array<uint32> indicesPole(6);
	verticesPole[0].moveBy(-poleHalfWidthF, -poleHeightF);
	verticesPole[1].moveBy(+poleHalfWidthF, -poleHeightF);
	verticesPole[2].moveBy(+poleHalfWidthF, 0.0f);
	verticesPole[3].moveBy(-poleHalfWidthF, 0.0f);
	indicesPole = { 0,1,2, 2,3,0 };

	Array<Float2> verticesFlag(5, verticesPole[1]);
	Array<uint32> indicesFlag(9);

	verticesFlag[1].moveBy(flagWidthLargerF, 0.0f);
	verticesFlag[2].moveBy(flagWidthSmallerF, flagHeightF*0.5f);
	verticesFlag[3].moveBy(flagWidthLargerF, flagHeightF);
	verticesFlag[4].moveBy(0.0f, flagHeightF);
	indicesFlag = { 0,1,2, 2,3,4, 4,0,2 };

	return { Shape2D{ verticesPole,indicesPole }, Shape2D{ verticesFlag,indicesFlag } };
}

Array::map() が一部のユースケースでCEとなる

struct Hoge {
	double operator () (const Vec2& v) {
		return v.x;
	}

	String operator () (Vec2&& v) {
		return Format(v);
	}
};

のようなファンクタを作り、

Array<Vec2> arr = f();

auto newArr = arr.map(Hoge{});

のようなコードを書くとエラーとなる。

Array::map() の定義を

template <class Fty>
auto map(Fty f) const
	-> Array<decltype(f(*this[0]))>
{
	Array<decltype(f(*this[0]))> new_array;

	new_array.reserve(size());

	for (const auto& v : *this)
	{
		new_array.push_back(f(v));
	}

	return new_array;
}

以下のように書き換えるとうまくいくと思われる。

ColorFとColorの扱いについて

auto color = Palette::Orange : ColorF(Palette::Blue, 0.1);
がエラーを吐いてしまうのですが、
auto color = ColorF(Palette::Orange) : ColorF(Palette::Blue, 0.1);
のようにするしかないでしょうか?

今確認できる手段がないのですが、0.3.1だとエラーがなかったように思います。

TrumpSetクラス

第4回OpenSiv3D実装会

# include <Siv3D.hpp>
# include <HamFramework.hpp>

namespace s3d
{
	namespace Trump
	{
		enum Mark
		{
			Spade,
			Heart,
			Clover,
			Diamond,
			Joker,
		};


		struct Card
		{
			Font font;
			Vec2 size;
			Mark mark;
			int32 number;

			Card() = default;

			explicit constexpr Card(const Font& _font, const Vec2& _size, Mark _mark, int32 _number = 1) noexcept
				: font(_font)
				, size(_size)
				, mark(_mark)
				, number(_number)
			{
				assert(InRange(_number, 1, 13) || _mark == Joker);
			}

			void drawAt(const Vec2& center) const
			{
				static const String numbercs[13] = {L"A",L"2",L"3",L"4",L"5",L"6",L"7",L"8",L"9",L"10",L"J",L"Q",L"K"};
				const RectF rect(Arg::center = center, size);

				RoundRect(rect,rect.w*0.05).draw();

				if (mark != Joker)
				{
					const Color color = mark % 2 ? Palette::Red : Palette::Black;
					const wchar markc = L"♠♥♣♦J"[mark];
					const String numberc = numbercs[number - 1];

					font(markc, numberc).drawAt(rect.center(), color);
				}
				else
				{
					font(L"").drawAt(rect.center(), Palette::Black);
				}
			}
		};

		class TrumpSet
		{
		private:
			
			Font m_font = Font(15);
			Vec2 m_size = Vec2(50*1,50*1.618);

		public:

			TrumpSet() = default;

			Card operator()(Mark _mark, int32 _number = 1) const
			{
				return Card(m_font,m_size,_mark,_number);
			}

//			Card operator()(const String& card)
//			{}
		};
	}
}

void Hoge(Trump::Card card)
{}
void Main()
{
	Window::Resize(1280, 720);

	const Trump::TrumpSet trump;

	while (System::Update())
	{
		if (KeyP.down())
		{
			ScreenCapture::SaveCurrentFrame();
		}
		for (auto i : Range(1, 13))
		{
			trump(Trump::Spade, i)	.drawAt(Vec2(50 + i * 55, 50 + 100 * 0));
			trump(Trump::Heart, i)	.drawAt(Vec2(50 + i * 55, 50 + 100 * 1));
			trump(Trump::Clover, i)	.drawAt(Vec2(50 + i * 55, 50 + 100 * 2));
			trump(Trump::Diamond, i).drawAt(Vec2(50 + i * 55, 50 + 100 * 3));
			trump(Trump::Joker, i)	.drawAt(Vec2(50 + i * 55, 50 + 100 * 4));
		}
	}
}

Visual Studio 2017 15.9.1でビルドに失敗する

Visual Studio 2017 を最新の15.9.1に更新した後、ビルドに失敗するようになりました。

以前使っていたバージョン(おそらく15.7)ではビルドできていました。
Windows SDK 10.0.17134.0 はインストール済みです。

image

プロセスの作成機能

Boost.Process の使用を検討。
子プロセスの終了や終了コードを取得できるようにする。

Macでのlogのhtmlファイルの生成場所の変更

Macにおいて生成したアプリケーションを/Applicationsにおくとlogのhtmlファイルも/Applicationsに置かれてしまいます。

代替案としてはとりあえず以下のものを考えました。

  • ユーザが関数あるいは設定ファイルにて指定できる
  • ~/Library/Logsへの設置

後者に関しては常に~/Library/Logsでも使い勝手が悪いのでReleaseビルドの時のみ~/Library/Logsにして、Debugの時は./にするなどでも良いと思います。

Viewportの中でCamera2Dが使いたい

現状のCamera2Dだと、Transformer2Dのスコープの中で拡大・縮小する座標がずれてしまうために使うことが出来ないので、使えるようにしてほしいです。

# include <Siv3D.hpp> // OpenSiv3D v0.4.0

void Main()
{
	Camera2D camera;

	Array<Vec2>	verticles;
	for (int i = 0; i < 100; i++) verticles.emplace_back(RandomVec2(Scene::Rect()));

	while (System::Update())
	{
		auto v = ScopedViewport2D(100, 100, 480, 360);
		auto t1 = Transformer2D(Mat3x2::Identity(), Mat3x2::Translate(100, 100));
		
		Circle(Cursor::PosF(), 8).draw(Palette::Green);
		
		camera.update();

		auto t2 = camera.createTransformer();

		Scene::Rect().draw(ColorF(Palette::Skyblue, 0.5));
		for (const auto& v : verticles) Circle(v, 16).draw(Palette::Red).drawFrame(1.0, Palette::Black);
	}
}

LineString::draw()について

極端にポイント間の距離が短いと描画されないようです。

# include <Siv3D.hpp> // OpenSiv3D v0.1.6

void Main()
{
	const Vec2 p1(0, 1);
	const Vec2 p2(1, 1);

	LineString lineString;

	for (double x = 0; x <= 1.0; x += 0.01)
		lineString.emplace_back(p1.lerp(p2, x).movedBy(0, 1.0*(pow(0.5 - x, 2.0) - 0.25)));

	while (System::Update())
	{
		const auto t = Transformer2D(Mat3x2::Scale(300));

		//描画されない
		lineString.draw(0.1);

		//描画される
		for (int i = 0; i < int(lineString.size() - 1); i++)
			Line(lineString[i], lineString[i + 1]).draw(0.1);
	}
}

Windowsでのデバック実行処理の不具合について

先程、OpenSiv3D0.1.6を使用し、サンプルソースコードを実行しようとしたところ、
ビルドはうまくいくのですがDebugの際にウィンドウが開かず実行が終了してしまいました。

私の開発環境ですが、

OS:

  • Windows10 Home 64bit
  • version 1703
  • Intel Core i7-7600 3.40GHz
  • RAM : 8GB
    NVIDIA GeForce GTX970 搭載

IDE:

  • Visual Studio Community 2017
  • Version 15.3.1

またデバックの際の出力結果は以下のアップローダの通りです。

http://textuploader.com/d6kuy

Graphics::SetFullScreen()について

Graphics::SetFullScreen()を使ってフルスクリーンになる瞬間に、画面を左クリックをしてしまうと灰色のウィンドウになって動作が停止してしまうようです。

試したところ、フルスクリーンが完了した後にならば左クリックは影響ないようです。
default

# include <Siv3D.hpp>

void Main()
{
	Graphics::SetFullScreen(true, Size(1280, 720));

	while (System::Update())
	{
		Circle(Window::Center(), 120).draw(Palette::Skyblue);
	}
} 

Texture描画時のバグ

恐らく次のようなコードで再現できるバグです。意図していない場所に線が描画されます。

void Reproduce() {
	Image img(10, 10);
	for (int i = 0; i < img.height(); i++) {
		for (int j = 0; j < img.width(); j++) {
			if (i >= 5) img[i][j] = Color(Palette::White, 255);
			else img[i][j] = Color(Palette::White, 0);
		}
	}
	Texture texture(img);

	Graphics::SetBackground(Palette::White);
	while (System::Update()) {
		texture.draw(Vec2(100, 100.5), Palette::Black); //変な線が入る
	}
}

Shape2D::CreateBaloon()の実装案

Shape2D CreateRectBaloon(double w, double h, double pointingRootRatio = 0.5, const Vec2& pointingPos = Vec2(0.0, 0.0),const Vec2& center = Vec2(0.0, 0.0), double angle = 0.0)
{
	Array<Float2> vertices(7);
	Array<uint32> indices(9);
	std::array<int32, 2> sign{1, -1};
	std::array<unsigned int, 4> rectIndices;

	const float firstAngle = std::atan2f(h, w);
	const Float2 direction = pointingPos - center;
	const float flagAngle = std::fmodf(std::atan2f(direction.y, direction.x) + Math::TwoPiF, Math::TwoPiF);
	const float remainderAngle = std::fmodf(flagAngle, Math::HalfPiF);
	const int32 dividedAngleIndex = static_cast<int32>(flagAngle / Math::HalfPiF);
	const int32 a = ((dividedAngleIndex % 2 == 0) ? (remainderAngle > firstAngle) : (remainderAngle > Math::HalfPiF - firstAngle)) + dividedAngleIndex * 2;
	const Float2 pointingRootCenter(sign[((a + 2)/4) % 2] * w * 0.25 * (1.0 + ((a + 3)/ 2)%2), sign[((a) / 4) % 2] * h * 0.25 * (1.0 + ((a + 1) / 2) % 2));
	const Float2 offset = sign[(((a + 3) % 8) / 4) % 2] * ((((a + 1) / 2) % 2) ? Float2(w * 0.25 * pointingRootRatio, 0.0) : Float2(0.0, h * 0.25 * pointingRootRatio));
	const int indexOffset = ((a + 1) / 2) % 4;

	vertices[0 + indexOffset] = pointingRootCenter - offset + center;
	vertices[1 + indexOffset] = pointingPos;
	vertices[2 + indexOffset] = pointingRootCenter + offset + center;

	size_t i = 0;

	for (size_t rectIndex = 0; rectIndex < 4; ++rectIndex)
	{
		if (indexOffset == rectIndex)
			i += 3;

		rectIndices[rectIndex] = i;
		vertices[i++] = Float2(sign[((rectIndex + 1)/2)%2] * w * 0.5, sign[((rectIndex) / 2) % 2] * h * 0.5) + center;
	}

	indices[0] = 0 + indexOffset;
	indices[1] = 1 + indexOffset;
	indices[2] = 2 + indexOffset;
	indices[3] = rectIndices[0];
	indices[4] = rectIndices[1];
	indices[5] = rectIndices[2];
	indices[6] = rectIndices[0];
	indices[7] = rectIndices[2];
	indices[8] = rectIndices[3];

	return Shape2D(vertices, indices);
}

Transition::isEnd()の実装案

[[nodiscrad]] constexpr bool isEnd(const Transition& transition) noexcept
{
	return transition.value() == 1.0 || transition.value() == 0.0;
}

apng writer

It's possible to have an animated PNG writer function?

GUIで表示/非表示の有無を調べる

GUI::isVisible()もしくはGUI::isEnable()のように,GUIが有効/表示の有無を調べる関数が欲しいです.
現在,GUIを開発していないみたいですが,将来的にGUIを実装するときにはぜひ.

Shape2D::Diamond()の実装案

Shape2D CreateDiamond(double w, double h, const Vec2& center = Vec2(0, 0), double angle = 0.0)
{
	Array<Float2> vertices(4, center);
	Array<uint32> indices(6);

	const float halfW = static_cast<float>(w)*0.5f;
	const float halfH = static_cast<float>(h)*0.5f;
	const float angleF = static_cast<float>(angle);
	const float s = std::sin(angleF);
	const float c = std::cos(angleF);

	vertices[0].moveBy(halfH * s, -halfH * c);
	vertices[1].moveBy(halfW * c, halfW * s);
	vertices[2].moveBy(-halfH * s, halfH * c);
	vertices[3].moveBy(-halfW * c, -halfW * s);

	indices = { 0,1,3, 2,3,1 };

	return { vertices, indices };
}

Rectについて

Rect(Line(Vec2(20,40),Vec2(120,80)))
みたいな感じで対角線でRectを初期化できるようにしてもらいたいです

もし、Vec2 p1とVec2 p2があり、p1,p2の大小関係が分からない場合に
Rect(Min(p1.x, p2.x), Min(p1.y, p2.y), Abs(p1.x - p2.x), Abs(p1.y - p2.y))
とする必要があるので。

Shape2D::CreateStairs()の実装案

Shape2D CreateStairs(double w, double h, int32 steps, const Vec2& pos = Vec2(0.0, 0.0), bool isUpStairs = true)
{
	if (steps <= 0)
	{
		return Shape2D();
	}

	Array<Float2> vertices(2 + 2 * steps);
	Array<uint32> indices(3 * 2 * steps);
	const float offsetX = w / steps;
	const float offsetY = h / steps;

	vertices[0] = pos;
	vertices[1] = pos + Float2(isUpStairs ? -w : w, 0);
		
	for (size_t i = 0; i < steps; ++i)
	{
		const int32 offsetIndex = i + 1;

		vertices[offsetIndex * 2] = vertices[1] + Float2(isUpStairs ? offsetX * i : -offsetX * i, -offsetY * offsetIndex);
		vertices[offsetIndex * 2 + 1] = vertices[1] + Float2(isUpStairs ? offsetX * offsetIndex : -offsetX * offsetIndex, -offsetY * offsetIndex);

		indices[6 * i] = 0;
		indices[6 * i + 1] = 1 + 2 * i;
		indices[6 * i + 2] = 2 + 2 * i;
		indices[6 * i + 3] = 0;
		indices[6 * i + 4] = 2 + 2 * i;
		indices[6 * i + 5] = 3 + 2 * i;
	}

	return Shape2D(vertices, indices);
}

参照型に対する NamedParameter の廃止

参照型に対する NamedParameter は使い方が明確でなく、ユースケースも少ない割に誤って書きやすいので廃止を検討するべきと思われる。

TextBoxについて

クリップボードの文字列をTextBoxの書き込み位置にコピーできるようにしたいのですが
TextBox内のカーソル位置(書き込み位置)を取得することはできますか?

複数の戻り値を持つGetPrivateIPv4が欲しい

複数のネットワークに接続している環境では複数のIPアドレスを持っているので、それらを全て取得できるようになると嬉しいです。

僕の手元の環境ではDocker用の内部ネットワークがあり、GetPrivateIPv4の結果が10.0.xx.xxとなってしまい192.168.xx.xxのIPアドレスが取れないです。

個人的には急いで無いのでそのうちでお願いします。

Array::in_groups()の動作について

#include <Siv3D.hpp>

void Main()
{
Array ar;
for (int i : step(6))
{
ar.push_back(i);
}

auto x = ar.in_groups(4);

for (int i : step(x.size()))
{
	for (int k : step(x[i].size()))
		Print(x[i][k]);
	
	Print();
}

while (System::Update()) {}

}

/*
出力結果
0
1

2

3

4
*/

Window::SetFullscreen() の第 3 引数に WindowResizeOption を追加

理由

v0.4.0 beta の Window::SetFullscreen() はシーンのサイズを変更しなかったが、デフォルトで変更されたほうが Window::Resize() と一貫性があり、多くのケースで便利である。

詳細

Window::SetFullscreen()true を返すケースかつ WindowResizeOption がシーン解像度の変更を要求するケースにおいて、シーン解像度の変更を行う。

プラットフォーム

各プラットフォームごとに実装が必要

変更前

bool Window::SetFullscreen(bool fullscreen, const Optional<Size>& fullscreenResolution = unspecified)

変更後

bool Window::SetFullscreen(bool fullscreen, const Optional<Size>& fullscreenResolution = unspecified, WindowResizeOption option = WindowResizeOption::ResizeSceneSize)

関連サンプル

バージョンアップについて

既存のOpenSiv3Dプロジェクトを最新のOpenSiv3Dプロジェクトに変更するためにはどのようにすれば良いのでしょうか?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.