mieki256's diary



2024/01/20() [n年前の日記]

#1 [prog] C++とOpenGLで宇宙飛行的なWindows用のスクリーンセーバを作ってみた

ここ最近、C/C++ (MinGW gcc/g++ 6.3.0) と OpenGL を使って色々実験してたけど、ようやく Windwos用のスクリーンセーバを作れたので github にアップロードしておいた。昔あった、「宇宙飛行」みたいな描画をするスクリーンセーバ。

_mieki256/ssstars_opengl: C++ and OpenGL screensaver similar to ssstars.scr.


ユーザ名が日本語になってる環境でも動くことを確認できたし、サブPCに持っていっても動いてくれたので、他の環境でもおそらく動くのではないかなと…。

今回のスクリーンセーバの、プログラミング面のポイントとしては…。 ここまでできれば、後は何を描画するのか、そこだけに注力できそうかなと…。

少し解説 :

プログラム面について少し解説をメモ。

スクリーンセーバの処理は、ssstars_opengl.cpp で行ってる。

_ssstars_opengl/ssstars_opengl.cpp at main - mieki256/ssstars_opengl

C/C++ でWindows用のスクリーンセーバを作成する時は、スクリーンセーバ用のライブラリ scrnsave を利用すると作業が簡単になる。
  • ヘッダーファイルとして scrnsave.h を include する。
  • MinGW (gcc/g++ 6.3.0)なら libscrnsave.a ( or libscrnsavw.a ?) をリンクする。(-lscrnsave を gcc/g++ のオプションとしてつける。)

scrnsave を利用すると、以下の3つの関数を自分で書くだけでスクリーンセーバが作れる。
  • ScreenSaverProc() : フルスクリーン表示時の処理
  • ScreenSaverConfigureDialog() : 設定ダイアログの処理
  • RegisterDialogClasses() : 謎。

一番最後の RegisterDialogClasses() は return TRUE; だけ書いておけばいいらしいので、実質2つの関数を書くだけでいい。

フルスクリーン表示を担当する ScreenSaverProc() には、以下のメッセージが飛んでくるので、それぞれ行うべき処理を書けばいい。
  • WM_CREATE : ウインドウが生成された時にメッセージが飛んでくる。初期化時の処理を書く。タイマーもセットする。
  • WM_TIMER : タイマーで指定した一定時間毎にメッセージが飛んでくる。各フレームの描画処理を書く。描画内容が少しずつ変化するような処理を書けばアニメーションができる。
  • WM_DESTROY : ウインドウ破棄時にメッセージが飛んでくる。終了時の処理を書く。

設定ダイアログの処理を担当する ScreenSaverConfigureDialog() には、以下のメッセージが飛んでくるので、これもそれぞれ行うべき処理を書けばいい。
  • WM_INITDIALOG : 設定ダイアログが表示される際にメッセージが飛んでくる。初期化処理を書く。
  • WM_COMMAND : 設定ダイアログ上のボタン等が押された時にメッセージが飛んでくる。OKボタンが押された時、Cancelボタンが押された時の処理を書く。

設定ダイアログにどんなGUI部品を載せるか、どこに配置するかは、リソースファイル resource.rc の中に書く。
  • #include "resource.h" を最初のほうに書いておく。
  • ダイアログは、必ず、DLG_SCRNSAVECONFIGURE というIDを使って定義しておく。このIDにしておくだけで、scrnsaveライブラリが、このダイアログを設定ダイアログとして勝手に(?)表示してくれる。

リソースファイルの中で、スクリーンセーバ名も記述できる。
  • IDS_DESCRIPTION を割り当てた文字列が、スクリーンセーバ名。
  • Windowsのスクリーンセーバ設定ウインドウ上では、IDS_DESCRIPTION が割り当てられた文字列をスクリーンセーバ名として表示してくれる。

今回のプログラムの、各関数の役割は以下。
  • InitGL() : OpenGL関係の初期化処理。
  • SetupAnimation() : OpenGL関係の初期化処理と、オブジェクトワークの初期化。
  • Render() : 毎フレームの描画処理。オブジェクトの座標を変更して、OpenGLで画面描画をしている。
  • CleanupAnimation() : アニメーション関係の終了処理。ワーク等を確保して使っていたなら、ここで解放。
  • CloseGL() : OpenGL関係の終了処理。確保して使っていたアレコレを解放。
  • writeConfigToIniFile() : iniファイルに設定値を書き込み。
  • getConfigFromIniFile() : iniファイルから設定値を読み込み。


png画像を実行ファイルに含めたり、iniファイルの読み書きをするあたりは、以前のメモを参考に。

_C言語でiniファイルの読み書きをしたい - mieki256's diary
_xxdというコマンドがあることを知った - mieki256's diary
_メモリ上のpngバイナリをOpenGLのテクスチャとして利用 - mieki256's diary

参考ページ :

余談。スクリーンセーバの関連情報がどんどん消えている気がする :

思考メモ。完全に余談。

C/C++でスクリーンセーバを作る方法について色々ググって眺めてたけど、どうもこのあたり、解説ページがどんどん消滅している気がする…。WebArchive に残っていればまだ助かるけれど、残ってない場合もチラホラあって…。

「スクリーンセーバなんて今時使うやつ居ないだろ」という風潮で消えつつあるのだろうか…。ディスプレイがブラウン管から液晶に変わったことで、画面の焼き付き防止というスクリーンセーバの実用性は、たしかにもう求められていないし…。

ただ、スクリーンセーバというものは、まだ実用性があった頃から少しずつ、観賞して楽しむものに変化したジャンルで…。つまるところ、日常生活にちょっとした潤いを与えてくれる、実にさりげないCGアート作品群に変質していた。なのに「実用性」「実用性」って…。

例えば、壁にA5〜B5サイズの額縁に入った絵画がひっそり飾られていたとして。「こんなもん実用性無いだろ。無駄だ無駄」と、君は平気でソレをゴミ箱に突っ込むのかと。実用性があるものはこの世に存在する価値があって、実用性がないものは無価値だからどんどん削除していくべきだと…。0/1だけで考えるのですかと。

そう考えると、スクリーンセーバの作り方について解説してるページが少しずつ消滅している状況があるとしたら、仮にその理由が「スクリーンセーバなんて今時使うやつ居ねえだろ」という理由だったら、それは良くない流れかもしれないなと…。

とは言うものの。スクリーンセーバってインタラクティブ性があるわけでもないので、実は動画でいいんじゃないの? という気もしていて…。昔は動画をPCで再生するのは荷が重かったから、まだその都度計算してシンプルな映像をリアルタイムに提示していくほうが実現性が高かったのだろうけど。今はむしろ動画を再生しちゃうほうが確実(?)だし。

まあ、今となってはメガデモに近いところもあるのかなあ…。制約が特にないから、メガデモと比べたらなんだかゆるゆるだけど。

思考メモです。オチは無いです。

以上です。

過去ログ表示

Prev - 2024/01 - Next
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project