まず以下のスクリプトをおもむろに実行する
import bpy ############################################## # ボタンを定義 class ConeButton(bpy.types.Operator): bl_idname = "szl.button" bl_label = "Add a CONE" def execute(self, context): bpy.ops.mesh.primitive_cone_add() return{'FINISHED'} ############################################## # パネルの項目を定義 class ConeUI(bpy.types.Panel): bl_label = "panel title" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "AddConePanel" def draw(self, context): self.layout.operator("szl.button") ############################################## classes = ( ConeUI, ConeButton ) ############################################## # アドオン有効化時に呼び出される def register(): for c in classes: bpy.utils.register_class(c) # アドオン無効化時に呼び出される def unregister(): for c in classes: bpy.utils.unregister_class(c)if __name__ == "__main__": register()
すると、パネルに新しい項目が追加され、ボタンを押すとConeが生成される。
これは上記スクリプトの最後の register() 関数が実行されたため。
しかしBlenderを再起動すれば消えてしまう。そこでまず以下のように変更を加える。ファイル名は add-cone-addon.py とでもしておく。
下記、bl_infoの部分があるとアドオンとして認識される。
また、registerはBlenderがアドオンを読み込んだときに自動で呼び出されるので、一番下の呼び出し部分を削除する。
import bpy ##############################################bl_info = { "name" : "sample: add-on-name", "author" : "yodori soratori", "version" : (1, 0), "blender" : (2, 81, 0), "location" : "location", "description": "sample", "warning" : "warning message", # 空だと!アイコンが出ない "support" : "TESTING", # または OFFICIAL または COMMUNITY "wiki_url" : "", "tracker_url": "", "category" : "Object" #アドオンのカテゴリ }############################################## # ボタンを定義 class ConeButton(bpy.types.Operator): bl_idname = "szl.button" bl_label = "Add a CONE" def execute(self, context): bpy.ops.mesh.primitive_cone_add() return{'FINISHED'} ############################################## # class ConeUI(bpy.types.Panel): bl_label = "panel title" bl_space_type = "VIEW_3D" bl_region_type = "UI" bl_category = "AddConePanel" def draw(self, context): self.layout.operator("szl.button") ############################################## classes = ( ConeUI, ConeButton ) ############################################## # アドオン有効化時に呼び出される def register(): for c in classes: bpy.utils.register_class(c) # アドオン無効化時に呼び出される def unregister(): for c in classes: bpy.utils.unregister_class(c)#if __name__ == "__main__": # register()
そして、Preference → Add-ons でアドオンとしてインストールする
エッジを二本選択し、その交点を求めたい。
How can I add vertices to intersection of two edges?
https://blender.stackexchange.com/questions/2976/how-can-i-add-vertices-to-intersection-of-two-edges
のPythonスクリプトを実行すると、二辺の交差点に頂点を一つ追加できる。(Blender 2.79 , 2.8 両対応)
しかし頂点が一つ置かれるだけだと不便なので、各エッジをsubdivideする形で追加するように変更した。
コードは以下:
import bmesh import bpy from mathutils import geometry # get cross point of 2 edges def calc_cross_coordinate(edge2): if len(edge2) == 2: [[v1, v2], [v3, v4]] = [[v.co for v in e.verts] for e in edge2] iv = geometry.intersect_line_line(v1, v2, v3, v4) iv = (iv[0] + iv[1]) / 2 return iv # subdivide 2 edges and move the points to cross point def subdivide_selects(edge2, moveto): obj = bpy.context.object me = obj.data bm = bmesh.from_edit_mesh(me) ret = bmesh.ops.subdivide_edges(bm, edges=edge2, use_grid_fill=True, cuts=1) bmesh.update_edit_mesh(me) for i in ret['geom_split']: if type(i) == bmesh.types.BMVert: i.co=moveto def cross_subdivide(): obj = bpy.context.object me = obj.data bm = bmesh.from_edit_mesh(me) edge2 = [e for e in bm.edges if e.select] if len(edge2) == 2: pos = calc_cross_coordinate(edge2) subdivide_selects(edge2,pos) cross_subdivide()
今回の処理を行う関数。
エッジが二本選択されているとき、二本のエッジをsubdivideし、新規頂点を交点に作成する。
二本のエッジを引数にとり、geometry.intersect_line_lineで交差している座標を求める。
三次元の線分の場合、現実には誤差の関係で絶対に交差しないので、交点は二つ求まる。その中間点を交点(iv)としている。
bmesh.ops.subdivide_edgesでオブジェクトをsubdivideしている。
戻り値の['geom_split']に作成されたデータが入っているので、データ型がBMVertのものだけを取り出し、座標を交点で上書きする
glutBitmapCharacterは珍しい関数では無いけれどなぜかどのサンプルもzを殺している。個人的には以下のようにx,y,zの指定をちゃんとやった方が圧倒的に使いやすい。
//! @brief 文字列を表示 //! @param [in] x 三次元の座標(X) //! @param [in] y 三次元の座標(Y) //! @param [in] z 三次元の座標(Z) //! @param [in] str 文字列(英語のみ) void render_string(float x, float y, float z, const char* str) { glRasterPos3f(x, y, z); const char* c = str; while (*c) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *c++); } }
単に現在の状態を表示するだけならコンソールでいいし、見栄えが重要ならそもそもglutなんて使わないし、何より、文字を左上に出すならちゃんとglLoadIdentityしてから世界座標系で指定する必要がある。手間を省けてない。
//! @brief 文字列を表示 //! @param [in] x 三次元の座標(X) //! @param [in] y 三次元の座標(Y) //! @param [in] z 三次元の座標(Z) //! @param [in] str 文字列(英語のみ) void render_string(float x, float y, float z, const char* str) { glRasterPos3f(x, y, z); const char* c = str; while (*c) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *c++); } } int width, height; //回転オブジェクト定義 nu::mrotate camr; //表示 void disp(void) { glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, width, height); glPushMatrix(); //原点を視線方向に0.5ずらす glTranslated(0, 0, -0.5); //回転行列を適用 double mat[16]; glMultMatrixd(camr.getmatrix(mat)); //一辺0.7のキューブを描画 cube(0.7); glColor3d(1, 1, 1); double ws = -0.7 / 2; double we = 0.7 / 2; render_string(ws, ws, ws, "min"); render_string(we, we, we, "max"); glPopMatrix(); glLoadIdentity(); render_string(-1, 0.9, 0, "sample"); glFlush(); }
ずっと不便き極まりなかったことが今更だがわかったのでここに残しておきたい。というか、世の人は多分今の方が使いやすいか、簡単に戻し型がわかってしまうのだろう。だから私の使う検索ワードではヒットしないのである。
ある日の更新を境に、Firefoxホームに表示されたgoogleやamazonをクリックすると検索になってしまい、サイトに飛ばなくなった。
記憶が確かなら元々はよくアクセスするサイトが自動で出てきていたのに、虫眼鏡マークのボタンに上書きされてしまった格好だったと思う。
@がついていると検索ワード入力になるのかとか思って色々試したが戻らなかった。
@amazonと@googleは検索エンジン扱いになっている。つまりリンクでは無い。だからトップサイトとして登録し、それとは全く別に、(必要であれば)検索エンジンとしてのアイコンを無効にする。
としたのち、以下でapacheを再起動
以下でいいはずなのだが、
なぜか動いてくれないので、以下を実行する
「ドキュメント」の左上の「新しいドキュメント」をクリック
「コンテンツ」に本文を書いて「保存」をクリック。「プレビュー」で表示を確認できる。
HTMLタグを直に打てる
サイトのトップページの設定がデフォルトではHomeになっているので、システム設定で site_start の項目を検索し、トップページにしたい記事のIDを設定する
エレメント→テンプレートを右クリックし、「テンプレートを作成」を選択
画面を下の方にスクロールするとテンプレートの入力欄がある
テンプレートを入力し、「保存」をクリックする
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF8" /> <title> [[*pagetitle]] | [[++site_name]]</title> </head> <body> <font color="blue">[[++site_url]]</font><br /> <font color="green">[[*longtitle:default=`[[*pagetitle]]`]]</font><br /> <font color="red"> [[*content]] </font><br /> </body> </html>
「ドキュメント」からテンプレートを適用したいページをクリックし、「使用テンプレート」で作成したテンプレートを選択し、「保存」をクリック
保存後、「プレビュー」で結果を表示する
リソース変数やコンフィグ変数の指定方法が、バージョンの差なのかタイプの差なのか知らないが日本公式のものでは動かなかったので、以下を参考にする
https://docs.modx.com/current/en/building-sites/tag-syntax/common
Bitnami MODx StackはCMSのMODxを使える状態で配布されている仮想マシンのイメージ。
Step.1 以下から仮想マシンをダウンロードする
MODX Virtual Machines
https://bitnami.com/stack/modx/virtual-machine
※現時点でのファイル名 bitnami-modx-2.7.2pl-2-linux-debian-9-x86_64.ova
Step.2 VirtualBoxを起動し、.ovaをインポート
Step.3 仮想マシンを起動し、ログイン名 bitnami , パスワード bitnami でdebianにログイン
※この時上記ログインパスワードを強制的に変えさせられるかもしれないのでなにか適当に入力する
Step.4 ホストOSからMODxにログインする
ID/パスワードはdebianの起動時に出てくるが、
cat ./bitnami_credentials
としても確認できる
URLはIPアドレスをipconfigから確認できる。
例 http://192.168.1.3
Step.5 一応日本語化する
MODX Virtual Machines
https://bitnami.com/stack/modx/virtual-machine
起動直後のログイン画面に
が表示されいてる
この画面が出てこない場合、ログイン情報は、以下のコマンドで確認できる
サイトURLはipconfigで確認する
System Settingsを開く
「Filter by area…」にlanguageと入力し設定項目を絞り込む
Manager Language の項目を ja に設定
設定を変えてもなぜか暫く変わらないので注意。あちこち移動しているといつの間にか変わる
なお日本語での言語の設定名は「管理画面の言語」
続く...
Find application credentials
https://docs.bitnami.com/bch/faq/get-started/find-credentials/
MODX Virtual Machines
https://bitnami.com/stack/modx/virtual-machine
Obtain application and server credentials
https://docs.bitnami.com/virtual-machine/apps/modx/get-started/first-steps/
まず、前回とほぼ同じプログラムで、下記( ※ )部分を「、」などの文字に変更する。
//参考 //https://gist.github.com/cloudwu/766bccc60c254f9cc2abfa397bcff2ea #include<windows.h> #include <tchar.h> #include <cstdio> #define STB_TRUETYPE_IMPLEMENTATION #define STBTT_STATIC #include "stb_truetype.h" // utf8文字コードをコードポイントに変換 unsigned int utf8_decode(const char* o); // フォントで文字を描画した画像を作成 void drawfontchar(unsigned int f); unsigned char* pixels = nullptr; //画素の格納先 int iwidth; //画像サイズの格納先 int iheight; LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { HDC hdc; PAINTSTRUCT ps; switch (msg) { case WM_DESTROY: //画像の破棄 delete[] pixels; PostQuitMessage(0); return 0; case WM_PAINT://画面に表示 hdc = BeginPaint(hwnd, &ps); if (pixels != nullptr) { RECT rect; GetClientRect(hwnd, &rect); FillRect(hdc, &rect, (HBRUSH)GetStockObject(GRAY_BRUSH)); for (int y = 0; y < iheight; y++) { for (int x = 0; x < iwidth; x++) { unsigned char r = pixels[y * iwidth + x]; if (r == 0) SetPixel(hdc, x, y, RGB(255, 0, 0)); else SetPixel(hdc, x, y, RGB(0, 0, 0)); } } } EndPaint(hwnd, &ps); break; } return DefWindowProc(hwnd, msg, wp, lp); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow) { HWND hwnd; WNDCLASS winc; MSG msg; winc.style = CS_HREDRAW | CS_VREDRAW; winc.lpfnWndProc = WndProc; winc.cbClsExtra = winc.cbWndExtra = 0; winc.hInstance = hInstance; winc.hIcon = LoadIcon(NULL, IDI_APPLICATION); winc.hCursor = LoadCursor(NULL, IDC_ARROW); winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); winc.lpszMenuName = NULL; winc.lpszClassName = TEXT("NEW_WINDOW"); if (!RegisterClass(&winc)) return 0;//指定した文字のunicodeのコードポイントを取得(※) unsigned int c = utf8_decode(u8"ぬ");//一文字書かれた画像を作成(pixelsに格納) drawfontchar(c); hwnd = CreateWindow( TEXT("NEW_WINDOW"), TEXT("example : stb_truetype.h"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 150, 150, NULL, NULL, hInstance, NULL ); if (hwnd == NULL) return 0; while (GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg); return msg.wParam; } unsigned char ttf_buffer[1 << 25]; //一文字書かれた画像を作成 void drawfontchar(unsigned int codepoint) { const int HEIGHT = 100; stbtt_fontinfo font; //フォントファイルを開く FILE* pf_font = fopen(R"(C:\Windows\Fonts\msgothic.ttc)", "rb"); fread(ttf_buffer, 1, 1 << 25, pf_font); fclose(pf_font); stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer, 0)); float scale = stbtt_ScaleForPixelHeight(&font, HEIGHT); int ascent, baseline, decent; stbtt_GetFontVMetrics(&font, &ascent, &decent, 0); baseline = (int)(ascent * scale); int height = (int)((ascent - decent) * scale); int x0, y0, x1, y1; stbtt_GetCodepointBitmapBox(&font, codepoint, scale, scale, &x0, &y0, &x1, &y1); //出力先のメモリ確保 iwidth = x1 - x0; iheight = y1 - y0; pixels = new unsigned char[iheight * iwidth]; stbtt_MakeCodepointBitmap( &font, //フォント情報 pixels, //描画先 iwidth, //描画先の幅 iheight,//描画先の高さ iwidth, //描画先の画像の一行のバイト数(?) scale, //X方向倍率 scale, //Y方向倍率 codepoint); } //utf8一文字をコードポイントに変換 unsigned int utf8_decode(const char* o) { const unsigned int MAXUNICODE = 0x10FFFF; static const unsigned int limits[] = { 0xFF, 0x7F, 0x7FF, 0xFFFF }; const unsigned char* s = (const unsigned char*)o; unsigned int c = s[0]; unsigned int res = 0; /* final result */ if (c < 0x80) /* ascii? */ res = c; else { int count = 0; /* to count number of continuation bytes */ while (c & 0x40) { /* still have continuation bytes? */ int cc = s[++count]; /* read next byte */ if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ return -1; /* invalid byte sequence */ res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ c <<= 1; /* to test next bit */ } res |= ((c & 0x7F) << (count * 5)); /* add first byte */ if (count > 3 || res > MAXUNICODE || res <= limits[count]) return -1; /* invalid byte sequence */ s += count; /* skip continuation bytes read */ } return res; }
出力されるのは文字の部分だけなので、そのまま画像の幅で並べると以下のようになる。
まず、グローバル変数に以下を追加する
int _Baseline_; int _Y0;
次に、drawfontchar関数に以下を追加する
//一文字書かれた画像を作成 void drawfontchar(unsigned int codepoint) { const int HEIGHT = 100; stbtt_fontinfo font; //フォントファイルを開く FILE* pf_font = fopen(R"(C:\Windows\Fonts\msgothic.ttc)", "rb"); fread(ttf_buffer, 1, 1 << 25, pf_font); fclose(pf_font); stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer, 0)); float scale = stbtt_ScaleForPixelHeight(&font, HEIGHT); int ascent, baseline, decent; stbtt_GetFontVMetrics(&font, &ascent, &decent, 0); baseline = (int)(ascent * scale); int height = (int)((ascent - decent) * scale); int x0, y0, x1, y1; stbtt_GetCodepointBitmapBox(&font, codepoint, scale, scale, &x0, &y0, &x1, &y1);_Baseline_ = baseline; _Y0 = y0;//出力先のメモリ確保 iwidth = x1 - x0; iheight = y1 - y0; pixels = new unsigned char[iheight * iwidth]; stbtt_MakeCodepointBitmap( &font, //フォント情報 pixels, //描画先 iwidth, //描画先の幅 iheight,//描画先の高さ iwidth, //描画先の画像の一行のバイト数(?) scale, //X方向倍率 scale, //Y方向倍率 codepoint); }
さらに、表示時にY方向にオフセットを加える
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { HDC hdc; PAINTSTRUCT ps; switch (msg) { case WM_DESTROY: //画像の破棄 delete[] pixels; PostQuitMessage(0); return 0; case WM_PAINT://画面に表示 hdc = BeginPaint(hwnd, &ps); if (pixels != nullptr) { RECT rect; GetClientRect(hwnd, &rect); FillRect(hdc, &rect, (HBRUSH)GetStockObject(GRAY_BRUSH)); for (int y = 0; y < iheight; y++) { for (int x = 0; x < iwidth; x++) { unsigned char r = pixels[y * iwidth + x]; if (r == 0) SetPixel(hdc, x, y + _Y0 + _Baseline_, RGB(255, 0, 0)); else SetPixel(hdc, x, y + _Y0 + _Baseline_, RGB(0, 0, 0)); } } } EndPaint(hwnd, &ps); break; } return DefWindowProc(hwnd, msg, wp, lp); }
各文字ごとに、y0とbaselineで高さの調整を行った場合。
さらに、文字ごとに一定の間隔で並べると
幅に関しては揃える基準が無いのでX方向のオフセットは定数にする。
件のstbライブラリにあるstb_truetype.hでttfのラスタライズができる。public domainでttfが簡単に使えるなら試してみたい。
//参考 //https://gist.github.com/cloudwu/766bccc60c254f9cc2abfa397bcff2ea #include<windows.h> #include <tchar.h> #include <cstdio> #define STB_TRUETYPE_IMPLEMENTATION #define STBTT_STATIC #include "stb_truetype.h" // utf8文字コードをコードポイントに変換 unsigned int utf8_decode(const char* o); // フォントで文字を描画した画像を作成 void drawfontchar(unsigned int f);unsigned char* pixels = nullptr; //画素の格納先 int iwidth; //画像サイズの格納先 int iheight;LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { HDC hdc; PAINTSTRUCT ps; switch (msg) { case WM_DESTROY://画像の破棄 delete [] pixels;PostQuitMessage(0); return 0; case WM_PAINT://画面に表示 hdc = BeginPaint(hwnd, &ps);if (pixels != nullptr) { for (int y = 0; y < iheight; y++) { for (int x = 0; x < iwidth; x++) { unsigned char r = pixels[y * iwidth + x]; if (r == 0) SetPixel(hdc, x, y, RGB(255, 255, 255)); else SetPixel(hdc, x, y, RGB(0, 0, 0)); } } }EndPaint(hwnd, &ps); break; } return DefWindowProc(hwnd, msg, wp, lp); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow) { HWND hwnd; WNDCLASS winc; MSG msg; winc.style = CS_HREDRAW | CS_VREDRAW; winc.lpfnWndProc = WndProc; winc.cbClsExtra = winc.cbWndExtra = 0; winc.hInstance = hInstance; winc.hIcon = LoadIcon(NULL, IDI_APPLICATION); winc.hCursor = LoadCursor(NULL, IDC_ARROW); winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); winc.lpszMenuName = NULL; winc.lpszClassName = TEXT("NEW_WINDOW"); if (!RegisterClass(&winc)) return 0;//指定した文字のunicodeのコードポイントを取得 unsigned int c = utf8_decode(u8"ぬ"); //一文字書かれた画像を作成(pixelsに格納) drawfontchar(c);hwnd = CreateWindow( TEXT("NEW_WINDOW"), TEXT("example : stb_truetype.h"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 200, 100, NULL, NULL, hInstance, NULL ); if (hwnd == NULL) return 0; while (GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg); return msg.wParam; } unsigned char ttf_buffer[1 << 25];//一文字書かれた画像を作成 void drawfontchar(unsigned int codepoint) { const int HEIGHT = 60; stbtt_fontinfo font; //フォントファイルを開く FILE* pf_font = fopen(R"(C:\fonts\GenShinGothic-Bold.ttf)", "rb"); fread(ttf_buffer, 1, 1 << 25, pf_font); stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer, 0)); float scale = stbtt_ScaleForPixelHeight(&font, HEIGHT); int ascent, baseline, decent; stbtt_GetFontVMetrics(&font, &ascent, &decent, 0); baseline = (int)(ascent * scale); int height = (int)((ascent - decent) * scale); int x0, y0, x1, y1; stbtt_GetCodepointBitmapBox(&font, codepoint, scale, scale, &x0, &y0, &x1, &y1); //出力先のメモリ確保 iwidth = x1 - x0; iheight = y1 - y0; pixels = new unsigned char[iheight * iwidth]; stbtt_MakeCodepointBitmap( &font, //フォント情報 pixels, //描画先 iwidth, //描画先の幅 iheight,//描画先の高さ iwidth, //描画先の画像の一行のバイト数(?) scale, //X方向倍率 scale, //Y方向倍率 codepoint); }//utf8一文字をコードポイントに変換
unsigned int utf8_decode(const char* o) { const unsigned int MAXUNICODE = 0x10FFFF; static const unsigned int limits[] = { 0xFF, 0x7F, 0x7FF, 0xFFFF }; const unsigned char* s = (const unsigned char*)o; unsigned int c = s[0]; unsigned int res = 0; /* final result */ if (c < 0x80) /* ascii? */ res = c; else { int count = 0; /* to count number of continuation bytes */ while (c & 0x40) { /* still have continuation bytes? */ int cc = s[++count]; /* read next byte */ if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ return -1; /* invalid byte sequence */ res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ c <<= 1; /* to test next bit */ } res |= ((c & 0x7F) << (count * 5)); /* add first byte */ if (count > 3 || res > MAXUNICODE || res <= limits[count]) return -1; /* invalid byte sequence */ s += count; /* skip continuation bytes read */ } return res; }
以下のサンプルコードに手を加え、win32apiで文字を一つ表示できるようにした。
https://gist.github.com/cloudwu/766bccc60c254f9cc2abfa397bcff2ea
源真ゴシック
#include<windows.h> #include <tchar.h> #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h"unsigned char* pixels = nullptr; //画素の格納先 int width; //画像サイズの格納先 int height; int bpp; //一画素のバイト数LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { HDC hdc; PAINTSTRUCT ps; switch (msg) { case WM_DESTROY://画像の破棄 stbi_image_free(pixels);PostQuitMessage(0); return 0; case WM_PAINT://画面に表示 hdc = BeginPaint(hwnd, &ps);if (pixels != nullptr){ for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { unsigned char r = pixels[(y*width + x)*bpp + 0]; unsigned char g = pixels[(y*width + x)*bpp + 1]; unsigned char b = pixels[(y*width + x)*bpp + 2]; SetPixel(hdc,x, y, RGB(r, g, b)); } }}EndPaint(hwnd, &ps); break; } return DefWindowProc(hwnd, msg, wp, lp); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int nCmdShow) { HWND hwnd; WNDCLASS winc; MSG msg; winc.style = CS_HREDRAW | CS_VREDRAW; winc.lpfnWndProc = WndProc; winc.cbClsExtra = winc.cbWndExtra = 0; winc.hInstance = hInstance; winc.hIcon = LoadIcon(NULL, IDI_APPLICATION); winc.hCursor = LoadCursor(NULL, IDC_ARROW); winc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); winc.lpszMenuName = NULL; winc.lpszClassName = TEXT("NEW_WINDOW"); if (!RegisterClass(&winc)) return 0; hwnd = CreateWindow( TEXT("NEW_WINDOW"), TEXT("example : stb_image.h"), WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); if (hwnd == NULL) return 0;//画像のロード pixels = stbi_load(R"(C:\mydata\test\beach-blur-clouds-dawn-462030.jpg)", &width, &height, &bpp, 0);//https://odashi.hatenablog.com/entry/20110911/1315730376 RECT rw, rc; ::GetWindowRect(hwnd, &rw); // ウィンドウ全体のサイズ ::GetClientRect(hwnd, &rc); // クライアント領域のサイズ // 希望するクライアント領域のサイズを持つウィンドウサイズを計算 int new_width = (rw.right - rw.left) - (rc.right - rc.left) + width; int new_height = (rw.bottom - rw.top) - (rc.bottom - rc.top) + height; SetWindowPos(hwnd, NULL, 0, 0, new_width, new_height, SWP_NOMOVE | SWP_NOZORDER);while (GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg); return msg.wParam; }
pexels
https://www.pexels.com/ja-jp/photo/hdr-462030/
更新しない備忘録改二
https://odashi.hatenablog.com/entry/20110911/1315730376
でらうま倶楽部