Re: DrawCircleGaugeにアンチエイリアスをかけたい ( No.1 ) |
- 名前:C-- 日時:2018/04/21 21:29
半径部分を DrawLineAA で描く、ということくらいでしょうか。
スペースキーを押している時にAAをかける例を作ってみました。
・"TestCircle.png" は公式(?)画像の dxlib.o.oo7.jp/file/TestCircle.png です。
・あくまで半径のみで、外周部分は考慮していません。
#include "DxLib.h"
#include <math.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
DxLib::ChangeWindowMode(TRUE);
if (DxLib::DxLib_Init() == -1) return -1;
DxLib::SetDrawScreen(DX_SCREEN_BACK);
int nGRID = LoadGraph(TEXT("TestCircle.png"));
double dKAKUDO_START = 12.449;
double dKAKUDO_END = 205.327;
while (DxLib::ProcessMessage() == 0)
{
DxLib::ClearDrawScreen();
DxLib::DrawBox(0, 0, 640, 480, DxLib::GetColor(0, 0, 128), TRUE);
DxLib::DrawCircleGauge(320, 240, dKAKUDO_END / 3.6, nGRID, dKAKUDO_START / 3.6);
if (DxLib::CheckHitKey(KEY_INPUT_SPACE))
{
double th1 = 0, th2 = 0, r = 126.0;
float x2 = 0, y2 = 0, tc = 2.0F;
unsigned int c = DxLib::GetColor(0, 255, 0);
th1 = (2.0 * DX_PI / 360.0) * (-dKAKUDO_START + 90.0);
th2 = (2.0 * DX_PI / 360.0) * (-dKAKUDO_END + 90.0);
x2 = (float)(r * cos(th1) + -0.0 * sin(th1) + 320.0);
y2 = (float)(-(r * sin(th1) + 0.0 * cos(th1)) + 240.0);
DxLib::DrawLineAA(320.0F, 240.0F, x2, y2, c, tc);
x2 = (float)(r * cos(th2) + -0.0 * sin(th2) + 320.0);
y2 = (float)(-(r * sin(th2) + 0.0 * cos(th2)) + 240.0);
DxLib::DrawLineAA(320.0F, 240.0F, x2, y2, c, tc);
}
DxLib::ScreenFlip();
}
DxLib::InitGraph();
return DxLib::DxLib_End();
}
 |
Re: DrawCircleGaugeにアンチエイリアスをかけたい ( No.2 ) |
- 名前:管理人 日時:2018/04/23 01:25
C--さんの方法よりかなり手順が多くなり面倒ですが
『一度縦横2倍に拡大した円グラフを描画した後、裏画面に等倍に縮小して描画する』
という方法でジャギーを抑えることができます
#include "DxLib.h"
int SrcGraph ; // 元画像
int SrcW, SrcH ; // 元画像のサイズ
int Src_x2_Graph ; // 元画像を 2倍に拡大した画像
int WorkScreen ; // 作業用画面
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// ウィンドウモードで起動
ChangeWindowMode( TRUE ) ;
// DXライブラリの初期化
if( DxLib_Init() == -1 )
{
return -1 ;
}
// 円グラフ用の画像を乗算済みアルファの画像に変換しながら読み込み
SetUsePremulAlphaConvertLoad( TRUE ) ;
SrcGraph = LoadGraph( "TestCircle.png" ) ;
SetUsePremulAlphaConvertLoad( FALSE ) ;
// 円グラフ用の画像のサイズを取得
GetGraphSize( SrcGraph, &SrcW, &SrcH ) ;
// 円グラフ用の画像の縦横2倍サイズのグラフィックハンドルを作成
Src_x2_Graph = MakeScreen( SrcW * 2, SrcH * 2, TRUE ) ;
// Src_x2_Graph に円グラフ用の画像を2倍に拡大して描画
{
// 描画先を Src_x2_Graph に変更
SetDrawScreen( Src_x2_Graph ) ;
// 最近点サンプリングで描画
SetDrawMode( DX_DRAWMODE_NEAREST ) ;
// 乗算済みアルファ画像用のアルファブレンドに設定
SetDrawBlendMode( DX_BLENDMODE_PMA_ALPHA, 255 ) ;
// 円グラフ用の画像を2倍拡大描画
DrawExtendGraph( 0, 0, SrcW * 2, SrcH * 2, SrcGraph, TRUE ) ;
}
// 拡大された円グラフを描画するための作業用画面の作成
WorkScreen = MakeScreen( SrcW * 2, SrcH * 2, TRUE ) ;
while( ProcessMessage() == 0 )
{
// 作業用画面に2倍拡大された円グラフを描画する
{
// 描画先を作業用画面に変更
SetDrawScreen( WorkScreen ) ;
// 作業用画面を画面のクリア
ClearDrawScreen() ;
// 乗算済みアルファ画像用のアルファブレンドに設定
SetDrawBlendMode( DX_BLENDMODE_PMA_ALPHA, 255 ) ;
// 2倍拡大された円グラフを描画
DrawCircleGauge( SrcW, SrcH, 60.0, Src_x2_Graph, 5.0 ) ;
}
// 裏画面に2倍拡大された円グラフを等倍に縮小して描画
{
// 描画先を裏画面に変更
SetDrawScreen( DX_SCREEN_BACK ) ;
// 裏画面をクリア
ClearDrawScreen() ;
// 乗算済みアルファ画像用のアルファブレンドに設定
SetDrawBlendMode( DX_BLENDMODE_PMA_ALPHA, 255 ) ;
// バイリニアフィルタリングで描画
SetDrawMode( DX_DRAWMODE_BILINEAR ) ;
// 2倍拡大された円グラフ画像を等倍に縮小して画面中心に描画
DrawExtendGraph( 320 - SrcW / 2, 240 - SrcH / 2, 320 + SrcW / 2, 240 + SrcH / 2, WorkScreen, TRUE ) ;
}
// 裏画面の内容を表画面に変更
ScreenFlip() ;
}
// グラフィックハンドル削除
InitGraph() ;
// DXライブラリの後始末
DxLib_End() ;
return 0 ;
}
使用している画像は C--さんのプログラムで使用している画像と同じ TestCircle.png です
https://dxlib.xsrv.jp/file/TestCircle.png
上記のプログラムで行っていることは以下の通りです
<準備>
1. 2倍に拡大した円グラフ用の画像( Src_x2_Graph )を用意する
2. 2倍に拡大した円グラフを描画するための作業用画面( WorkScreen )を作成しておく
<ループ時>
1. 作業用画面( WorkScreen )に2倍に拡大した円グラフ用の画像( Src_x2_Graph )を使って DrwaCircleGauge で円グラフを描画する
2. 裏画面に作業用画面( WorkScreen )を縦横2分の1に縮小して描画する( 描画モードをバイリニアにして描画 )
あと、プログラム中の随所に『乗算済みアルファ』という言葉が登場しますが、『描画対象にできる画像』に対して
アルファブレンド描画を行う場合、『乗算済みアルファ』を使用しないとアルファ値( 透明度 )が正しく処理されないからです
( TestCircle.png には半透明のピクセルは無いので『乗算済みα』を使用する必要はありませんが・・・ )
詳しくはこちらの『乗算済みアルファのすすめ』を参照してください m(_ _)m
<乗算済みアルファのすすめ>
https://dxlib.xsrv.jp/lecture/PremulAlpha/PremulAlpha.html
 |
|