HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2015
1108
スペースアンチエイリアス付き太線を描画する方法10解決


スペース

リンク

2015/11/8(Sun) 20:00:28|NO.72862


#include "gdi32.as" mref BMSCR,67 :Orig = BMSCR(37) Lpen = 0,255,0 repeat Color 255,255,255:boxf ExtCreatePen $10000 | $100,20,varptr(Lpen),0,0 BMSCR(37) = stat :line 20,20,200,rnd(50) DeleteObject stat redraw await title ""+cnt loop

太線を描画するだけならlineを何度もやったり、このようなプログラムを組めばいいのですが、
アンチエイリアス付きの太線はどのようにすれば実現できるのでしょうか?
いくら調べてもそれらしいものが見つかりません。
もし知っている方が居ましたら、教えて頂けると幸いです。



この記事に返信する


スペース

リンク

2015/11/8(Sun) 20:10:04|NO.72864

すみません、ついでに質問なのですが、
先ほど書いたgdiを使ってlineを描画するプログラムですが、
1万回描画するとバグって通常のlineが描画されてしまいます。
原因がわかる方が居ましたら、教えて頂けると嬉しいです。



Noap

リンク

2015/11/8(Sun) 20:36:32|NO.72866

それはbmscr(37)で元のcolor命令で作成されるペンを書き換えているので通常は終了時や次のcolor命令で解放されるべきなのがどんどん解放されずにたまっていって変なことになっています(リソースリーク)
あとこの場合はモジュールでもないのでループ中で毎回ペンの作成と解放をするのは意味がないとおもいます



スペース

リンク

2015/11/8(Sun) 21:06:31|NO.72868

>>Noapさん
Color命令を使うことで解放できるという意味でしょうか?
それとも次のColor命令を使うまでに解放しなければいけないということでしょうか?
もし前者ならColor命令を使っているので解放されているはずです。
後者の場合、解放するにはどうすればいいのでしょうか。
DeleteObject statの部分は元々、モジュールなので問題ありません。



Noap

リンク

2015/11/8(Sun) 21:16:04|NO.72869

とりあえず直したもの

#include "gdi32.as" mref BMSCR,67 //:Orig = BMSCR(37) Lpen = 0,255,0 repeat Color 255,255,255:boxf ExtCreatePen $10000 | $100,20,varptr(Lpen),0,0 if stat==0: dialog "ペンの作成に失敗":end Orig=BMSCR(37) BMSCR(37) = stat line 20,20,200,rnd(50) DeleteObject stat BMSCR(37)=Orig redraw await title ""+cnt loop

自分なりに書いてみたもの

#uselib "gdi32.dll" #cfunc ExtCreatePen "ExtCreatePen" int,int,sptr,int,sptr #func DeleteObject "DeleteObject" sptr #define PS_GEOMETRIC $00010000 #define PS_COSMETIC $00000000//普通の線 #define PS_ENDCAP_SQUARE $00000100 #define BS_SOLID $00000000 mref bmscr,67 logbrush= BS_SOLID,255,0 thickpen=ExtCreatePen( PS_GEOMETRIC | PS_ENDCAP_SQUARE, 20, varptr(logbrush),0,0) if thickpen==0: dialog "ペンの作成に失敗しました":end cls color 255,255,255 hpenbak=bmscr.37 onexit *delobj dim i,1 while bmscr.37=hpenbak: boxf bmscr.37=thickpen line 30,30,200,rnd(50) redraw 1 await title ""+i i++ wend *delobj bmscr.37=hpenbak DeleteObject thickpen end



Noap

リンク

2015/11/8(Sun) 21:24:30|NO.72871

color命令はbmscr.37に入っているハンドルのペンを解放してから新たなペンを作成してそのハンドルをbmscr.37に入れています。
ですがBMSCR(37)=statで書き換えているので元のHSPのシステムがつくったペンのハンドルが分からなくて解放することができなくてそのままどんどんたまっていって不具合を起こします。わたしのパソコンの場合は正常に描画されなくなるどころかHSPのランタイムがクラッシュしました。
なので元のペンを保存しておいてBMSCR(37)に書き戻すことが必要です。
わたしは初心者なので間違えている可能性が大いにあります。



スペース

リンク

2015/11/8(Sun) 21:28:21|NO.72872

>>Noapさん
詳しい解説とソースコード、有難うございます。上手くいきました。
ただ単にBMSCR(37) = statの直前の状態に戻せばよかったんですね。
(アンチエイリアス付きの線を描画したい、という質問内容を完全に忘れて解決にしてしまった為、
再投稿しました。)



Noap

リンク

2015/11/9(Mon) 17:53:52|NO.72885

わたしも忘れていました
GDI+は難しいです

参考
https://msdn.microsoft.com/en-us/library/windows/desktop/ms533969.aspx


//GDI+ //DLLがないこともあるので実際はDLLはcallfuncで呼び出すかexistであるかどうか確認したほうがいいと思う #uselib "gdiplus.dll" #func GdiplusStartup "GdiplusStartup" sptr,sptr,sptr #func GdiplusShutdown "GdiplusShutdown" sptr #func GdipCreateFromHDC "GdipCreateFromHDC" sptr,sptr #func GdipDeleteGraphics "GdipDeleteGraphics" sptr #func GdipSetSmoothingMode "GdipSetSmoothingMode" sptr,int #func GdipSetPixelOffsetMode "GdipSetPixelOffsetMode" sptr,int #func GdipCreatePen1 "GdipCreatePen1" int,float,int,sptr #func GdipDeletePen "GdipDeletePen" sptr #func GdipDrawLineI "GdipDrawLineI" sptr,sptr,int,int,int,int #define QualityModeInvalid -1 #define QualityModeDefault 0 #define QualityModeLow 1 #define QualityModeHigh 2 //すむーじんぐ モード #define SmoothingModeInvalid QualityModeInvalid//予約 #define SmoothingModeDefault QualityModeDefault #define SmoothingModeHighSpeed QualityModeLow #define SmoothingModeHighQuality QualityModeHigh #define SmoothingModeNone 3 #define SmoothingModeAntiAlias SmoothingModeAntiAlias8x4 #define SmoothingModeAntiAlias8x4 4 #define SmoothingModeAntiAlias8x8 8 //ぴくせる おふせっと モード #define PixelOffsetModeInvalid QualityModeInvalid//使わない #define PixelOffsetModeDefault QualityModeDefault #define PixelOffsetModeHighSpeed QualityModeLow #define PixelOffsetModeHighQuality QualityModeHigh #const PixelOffsetModeNone (QualityModeHigh+1) #const PixelOffsetModeHalf (QualityModeHigh+2) #define UnitPixel 2 //RGBからARGBに変換 //rgb2argb(p1,p2,p3,p4) //p1=透明度(0=透明,$FF=不透明) p2=赤 p3=緑 p4=青 #define ctype rgb2argb(%1=$FF, %2=0, %3=0, %4=0) ( ((%2<<16) & $00FF0000) | ((%3<<8) & $0000FF00 ) | (%4 & $000000FF) | ((%1<<24) & $FF000000) ) #define PENWIDTH 20//ペンの太さ dim gdiplus_token,1 dim gdiplus_pen,1 dim gdiplus_graphics,1 gdiplus_startup_input=1,0,0,0 color 88,191,63 GdiplusStartup varptr(gdiplus_token), varptr(gdiplus_startup_input), 0//GDI+ if stat==0{ GdipCreateFromHDC hdc, varptr(gdiplus_graphics) if gdiplus_graphics{ //Graphics::SetSmoothingMode GdipSetSmoothingMode gdiplus_graphics, SmoothingModeHighQuality//レンダリング //Graphics::SetPixelOffsetMode GdipSetPixelOffsetMode gdiplus_graphics, PixelOffsetModeHighQuality//ピクセルオフセット(ぼやかすことによってできる少しのずれをうめる) //Pen::Pen GdipCreatePen1 rgb2argb(,ginfo_r,ginfo_g,ginfo_b) ,PENWIDTH,UnitPixel,varptr(gdiplus_pen)//ペンの作成 if gdiplus_pen{ GdipDrawLineI gdiplus_graphics,gdiplus_pen,30,30,200,200 GdipDeletePen gdiplus_pen//ペンの廃棄 }else{ dialog "ペンをつくれなかった" } GdipDeleteGraphics gdiplus_graphics//グラフィックの廃棄 }else{ dialog "グラフィックをつくれなかった" } }else{ dialog "GDI+が開始できなかった": end } redraw 1 onexit *owari stop *owari GdiplusShutdown gdiplus_token//GDI+の終了 end



Noap

リンク

2015/11/9(Mon) 18:24:31|NO.72888

何度も見直しましたがもしかするととんでもない間違いをしているかもしれないので一応確認してくるとうれしいです。

ペンのことはこれが分かりやすいと思います

mref bmscr,67 mes "ペン"+bmscr(37)+"\nブラシ"+bmscr(36) color mes "ペン"+bmscr(37)+"\nブラシ"+bmscr(36)



スペース

リンク

2015/11/9(Mon) 19:02:47|NO.72889

>>Noapさん
本当に有難うございます。
凄くわかりやすく簡素で、かつ理想通りでした。
この質問は解決とします。
色々教えて頂き、ありがとうございました。



Noap

リンク

2015/11/9(Mon) 19:33:02|NO.72892

こちらこそありがとうございます
DLLがないこともあると書きましたが今のパソコン(XP以降)には基本的にあったと思うのでDLLがあるかないかは気にしなくてもいいかもしれません



ONION software Copyright 1997-2018(c) All rights reserved.