OpenGLプログラミングメモ内検索 / 「頂点配列」で検索した結果
-
頂点配列
頂点配列です。 今までは glBegin() と glEnd() で囲んで glVertex3d や glTexCoord2f を 記述してきました。 わかりやすいですが、これでは何度も何度も関数を呼び出し、機能を切り替えて 値を設定している事になり、少ないポリゴン数であれば問題ありませんが、大量の ポリゴンを描画する時には描画速度に影響します。 頂点は頂点でまとめ、法線は法線、マテリアルはマテリアルというようにデータが まとまっていた方が機能切り替えが最小限になり効率が良くなります。 頂点配列はすべてCPUが処理します。 ファイル main.cpp main.cpp #pragma comment(linker, /SUBSYSTEM WINDOWS /ENTRY mainCRTStartup ) #include GL/freeglut/freeglut.h #def...
-
VBO
VBOです。 頂点配列はPC本体のRAM(メモリ)にデータを置いておいて、 描画する時にビデオカードにデータを転送し、それを使って描画していました。 データの少ない物を描画する分には問題ありませんがポリゴン数の多いモデルを 大量に描画したりする時に一々毎回データを転送していてはかなりの無駄が 生じています。 そこで描画を高速化する為にビデオカードのRAMに予めデータを置いておき PC本体から毎回データを転送しなくても良いようにするのがVBOです。 今回のプログラムは頂点配列の解説で使ったプログラムをVBOにしています。 ファイル main.cpp main.cpp #pragma comment(linker, /SUBSYSTEM WINDOWS /ENTRY mainCRTStartup ) #pragma comment(lib, glew32.lib ) #inclu...
-
メニュー
... テッセレーション 頂点配列 ディスプレイリスト VBO VBO(テクスチャ付) PBO FBO 垂直同期ON/OFF OpenGLのバージョンとGPUの情報を得る 秒間60フレーム 簡易輪郭線描画 固定機能 トゥーンレンダリング 固定機能 グレースケール ▲▲▲▲▲ ▼ 固定機能 スタティックメッシュ編 .MQOを読み込んで表示する(GLMetaseq) .MQOを自力で読み込んでみる1(解析編) .MQOを自力で読み込んでみる2(読み込み編) .MQOを自力で読み込んでみる3(表示編)] .MQOローダ(ワイヤーフレーム表示編) .OBJを読み込んでみる1(解析編) .OBJを読み込んでみる2(読み込み編) .OBJを読み込んでみる3(表示編) .Xを読み込んでみる1(解析編) .Xを読み込んでみる2(解析編2) .Xを読み込んでみる3(読み込み編) .Xを読み込...
-
.MQOを自力で読み込んでみる3(表示編)
今回は取りあえず、頂点配列で表示してみます。 .MQO の頂点データはインデックスになっていますが UV座標のデータは インデックスにはなっていないので glDrawElements を使うとテクスチャが めちゃくちゃになってしまいます。 仕方が無いので glDrawArrays 用に配列データを作成し直して描画 する事にしました。 今回は取りあえず表示するだけという事で法線やライトなどは省略し、VBOにもしていません。 それとテクスチャに使える画像形式はPNGのみです。今の所。 今後はワイヤーフレーム表示とかにも挑戦してみます。 PNG.h #include lodepng.h //テクスチャクラス class TEXTURE{ protected LodePNG_Decoder decoder;//デコーダ unsigned char* buffer;//バッファ ...
-
コメント板
...ferDataに渡す頂点配列、法線配列、色配列をC++で「動的確保」して渡そうとしているのですが、glBufferDataの第3引数には配列のアドレスを渡せばよいのでしょうか?よろしければヒントを頂けると幸いです。先日教えて頂いたことで、glDrawRangElementsなども使えるようになりました。本当にありがとうございました。 -- 村長 (2012-01-18 18 26 31) そうですね。動的確保した配列の先頭のアドレスを渡してあげれば良いです。 -- 管理人 (2012-01-18 20 08 04) ありがとうございます。再度挑戦してみます! -- 村長 (2012-01-18 20 30 26) 管理人さん、無事「配列の動的確保での描画」出来ました。ありがとうございました。 -- 村長 (2012-01-19 09 37 55) コメント板が...
-
.OBJを読み込んでみる3(表示編)
...ンデックス化はせずに頂点配列で表示しています。 テクスチャはマテリアルで重複しないようにモデルクラスで保持しています。 完全に重複を避けるにはアプリケーション単位で保持する必要が あると思います。 PNG.h #include lodepng.h //テクスチャクラス class TEXTURE{ protected LodePNG_Decoder decoder;//デコーダ unsigned char* buffer;//バッファ size_t buffersize, imagesize;//サイズ public TEXTURE(); TEXTURE(const char* FileName);//コンストラクタ void LOAD_PNG(const char* FileName);//PNG読み込み unsigned char* image;//イメ...
-
頂点ブレンディング
頂点ブレンディングの解説です。 前回までの解説で各頂点が各ボーンから受ける頂点ウェイトの 影響の度合いがわかりました。 頂点ブレンディングとは、その影響を受けた頂点座標を 算出する処理の事です。 具体的には、 頂点座標 × ボーン行列 × 頂点ウェイト を、その頂点に影響するボーンの数だけ処理して それぞれの結果を足します。(ブレンドする) これが、頂点ブレンディング処理です。 ここまでの知識で、スキンメッシュアニメーションの基本的な事が できるようになっています。 次回、実際にスキンメッシュアニメーションを行ってみましょう。
-
頂点シェーダー
頂点シェーダーは、頂点情報を受け取り色々と処理をしてフラグメントシェーダーに 情報を渡します。 頂点シェーダーでは頂点の位置を操作したり、受け取った頂点カラーを変化させたり 光源計算を頂点単位で計算したりします。 ここでは、固定機能と頂点シェーダーで全く同じ位置で四角形を描画します。 ところが、頂点シェーダーに渡された頂点位置は + gl_ModelViewMatrix * vec4(150.0,0.0,0.0,0.0) によって、X方向に150ずれて表示されます。 頂点シェーダー(vertex.shader) void main(void) { gl_Position = gl_ModelViewMatrix * gl_Vertex + gl_ModelViewMatrix * vec4(150.0,0.0,0.0,0.0);//頂点座標の出力 gl_FrontColor = ...
-
スキンメッシュアニメーションの原理2
スタティックメッシュを変形させるにはどうすれば良いのでしょう? スタティックメッシュを構成する要素には ①頂点座標 ②法線 ③UV ④マテリアル ⑤テクスチャ 等がありますが、この中の ①頂点座標 を変更してあげれば スタティックメッシュが変形します。 頂点座標を変更すると言っても glTranslatef とか glRotatef 等では モデルビュー行列が変更されるだけで頂点座標そのものは変更できません。 では、何か、頂点座標を変更するようなものがあるかと言うと、 そのようなものは用意されていません。 スタティックメッシュの頂点座標が格納されている配列データを 直接、平行移動やら回転等をしているかのようにデータを書き換えなければなりません。 この場合、あくまでも書き換えるのは表示用のデータで、初期姿勢のデータを 変更してはいけません。 スキンメッシュアニメーションの仕組みは ①ボーンが...
-
.MQOを自力で読み込んでみる1(解析編)
前回はGLMetaseqを使わせて頂きましたが、今回からは .MQO を自力で 読み込んでみたいと思います。 ただ使っているだけでは理解した事にはならないので実際に解析してみましょう。 まず、どのようなデータがあり、どのデータが必要となるのか、そこから探っていきたいと 思います。 では、メタセコイアを起動して何もせずにいきなり名前を付けて保存したデータを見て みます。 1.MQO Metasequoia Document Format Text Ver 1.0 Scene { pos 0.0000 0.0000 1500.0000 lookat 0.0000 0.0000 0.0000 head -0.5236 pich 0.5236 ortho 0 zoom2 5.0000 amb 0.250 0.250 0.250 } Object obj1 { depth 0 ...
-
スキンメッシュアニメーションの原理4
ここまでのおさらいです。 ①、ボーンが階層アニメーションを行っている。 ②、頂点座標データを書き換える。 ③、(頂点座標 × ボーンオフセット行列 × 座標変換行列 × バインドポーズ行列) × 頂点ウェイト ④、 ③を影響するボーンの数だけ処理して足す(頂点ブレンド) ⑤、 ④で得られた頂点座標を元に頂点法線を再設定する 以上でスキンメッシュアニメーションの処理は完成です。
-
2分木構造
木構造というデータ構造の中で、子ノードを3つ以上取れる木構造は多分木と言い、 子ノードの数がNで固定されている物をN分木と言います。 子ノードの数が2つの物を2分木と言います。 親のないノードを根(root node)、子のないノードを葉(leaf node)と呼びます。 なぜ急に2分木を解説するかと言うと、階層アニメーションや スキンメッシュアニメーションの階層構造を配列や動的な多次元配列で 管理すると無駄が生じるからです。 それに対して2分木構造で管理すると全く無駄が無く、どのような 子ノードの数や階層数にも対応でき、動的に増やしたり減らしたりする事も 簡単にできます。 ではまず、簡単に仕組みを解説します。 2分木構造は前回解説した自己参照構造体の自己参照ポインタを2つ持っている 構造体を作るだけで簡単に作成できます。 左ノード、右ノードという使用法が一般的ですが、今回は少し見方を変...
-
スキンメッシュアニメーションの原理3
スキンメッシュアニメーションの真髄、頂点に座標変換を 施す処理ですが、具体的には 頂点座標 × ボーンオフセット行列 × 座標変換行列 × バインドポーズ行列 という事になります。 スキンメッシュアニメーションの仕組みは ①ボーンが階層アニメーションを行っている。 ②頂点座標データを書き換える。 の次は ③頂点座標 × ボーンオフセット行列 × 座標変換行列 × バインドポーズ行列 と、なりそうですが、これで完全ではありません。 詳しくは言いませんが、これだけではモデルがバッキバキに変形してしまいます。 では、どうスムーズに変形させるかと言うと、頂点が各ボーンから受ける影響の 重み(ウェイト)を設定してあげれば良いですね。 解説は次回に回します。
-
ウェイト
ウェイトの解説です。 Weight は重さの事ですが、ここで言うウェイトとは、頂点ウェイトの事です。 頂点ウェイトとはモデルの頂点に関連付けられたボーンが移動した際に、 その頂点がそのボーンにどれだけ追従するかの比率の事です。 基本的には頂点ウェイトは、0.0~1.0の正規化された範囲で表されます。 場合によっては、0.0~1.0の範囲外のデータの場合もありますが、 その場合でも自前で正規化して使います。
-
.Xを読み込んでみる2(解析編2)
それでは、前回の続きでテクスチャを設定してUVと法線を出力する ようにしてXファイルを作りました。 例によってテンプレート部分は除去しています。 xof 0302txt 0064 Header{ 1; 0; 1; } Mesh { 3; 1.08418;-0.00726;0.62110;, -1.10385;-0.70444;-1.10694;, -1.38258;1.10387;-0.06233;; 1; 3;0,1,2;; MeshMaterialList { 1; 1; 0;; Material { 0.800000;0.800000;0.800000;1.000000;; 5.000000; 0.000000;0.000000;0.000000;; 0.000000;0.000000;0.000000;; Te...
-
ボーンオフセット行列
以下は SkinWeights チャンクですが、最後の方にある matrixOffset は ボーンオフセット行列と呼ばれます。 SkinWeights { Joint_2 ; //transformNodeName ボーン名 32; //nWeights ボーンの影響を受ける頂点の数 0, // ↓ vertexIndices ボーンの影響を受ける頂点のインデックス ・ ・ ・ 0.001631, // ↓ weights ボーンの影響を受ける各頂点の重み ・ ・ ・ 1.000000,0.000000,-0.000000,0.000000, // ↓ matrixOffset 0.000000,1.000000,-0.000000,0.000000, //メッシュの頂点をボーン空間に変換する行列 -0.000...
-
.MQOを自力で読み込んでみる2(読み込み編)
今回は読み込み編という事で、実際に .MQO ファイルを読み込んでみます。 前回の解析編で描画に使うデータがわかりましたのでそれを自作のクラスと 構造体にガンガン詰め込んでみます。 ファイルの読み込みには C++ の fstream を使おうかな?と思ったんですが、 効率があまりよくないので GLmetaseq の旧版を参考に C言語の fscanf_s と fgets を使う事にしました。 GLmetaseq の旧版ではディスプレイリストにガンガン登録して、それをサクッと表示 していますが、私的にはディスプレイリストは使わない方向で行きます。 何故かというと、ワイヤーフレーム表示とか将来的にはスキニングとかもやりたいからです。 #include string #include vector using namespace std; //3つのベクトル struct Vector...
-
VBO(テクスチャ付)
テクスチャも含めてVBOで描画します。 ファイル main.cpp lodepng.cpp lodepng.h PNG.h sample.png main.cpp #pragma comment(linker, /SUBSYSTEM WINDOWS /ENTRY mainCRTStartup ) #pragma comment(lib, glew32.lib ) #include gl/glew.h #include GL/freeglut/freeglut.h #include PNG.h #define WIDTH 320 #define HEIGHT 240 GLuint VboId[4];//4つ分 float angle=0.0f; GLuint texID; TEXTURE *texture; //頂点データ 3面を4頂点で作成する 1頂点はx...
-
.Xのスキンメッシュアニメーションファイルを解析
取りあえず、DirectX SDK に付属するビューワーで再生の確認をします。 本来はスタティックメッシュであるはずの bone1.mqo が、 ウネウネ変形しています。 例によって、テンプレート部分は除去しました。 xof 0303txt 0032 # Global definition. AnimTicksPerSecond { 3000; } # Materials definition. Material Material_1 { 0.800000;0.800000;0.800000;1.000000;; 5.000000; 0.300000;0.300000;0.300000;; 0.000000;0.000000;0.000000;; } # Models definition. Frame Model { FrameTransformMatrix { 1...
-
.OBJを読み込んでみる1(解析編)
.OBJ は Wavefront社の Advanced Visualizer というソフト用のファイルフォーマットです。 3Dプログラミング入門関係のHPや書籍では必ずと言って良いほど最初の方に登場します。 何故か?と言うとファイル形式がとてもシンプルでスタティックメッシュ(アニメーションしないメッシュ)を 表現するための全ての情報を含んでいるので入門用には最適だからです。 では、まず、例によってメタセコイアで .OBJ を作成し、中身を見てみる事にします。 メタセコイアを起動して面コマンドの基本図形を選択します。 そして立方体を作成し、それを .OBJ 形式で保存します。 保存する時の注意ですが法線、UVマッピング、マテリアルにチェックし、改行コードを Windows(CR/LF)にしなければなりません。 さらに左右を反転するにもチェックをしないとOpenGLでは逆に表示されます。...
-
拡散照明
環境光だけではのっぺりとした図にしかなりません。 立体的に見せるには陰影を付けてやらなければなりません。 拡散反射光は光源から入ってくる光を全ての方向に均一に反射します。 紙のようにざらざらとした光沢の少ないものの表現に適しています。 反射する光の量は、入射する光の量に応じて変化し、入射する光の量は 光のあたる場所によって異なるので、物体の形に陰が付きます。 左の画像は頂点シェーダーのみで陰影を付けたものですが、ハイライトの部分に何やら 線のようなものが見えます。これは頂点単位で色の補間が行われているためです。 右の画像は頂点シェーダーで位置ベクトルと法線ベクトルを計算しておき、フラグメントシェーダーに 渡してフラグメントシェーダーで光の計算をしています。 こうするとピクセル単位で色の計算(補間)が行われるので非常に綺麗な結果が得られます。 フラグメントシェーダーに渡す変数は varyin...
-
法線
法線ベクトルです。面法線とか頂点法線とかがあります。 法線ベクトルとは、2次元ではある線に垂直なベクトル、3次元ではある面に 垂直なベクトルの事です。 三角ポリゴンは、3つの頂点の並びにより面から垂直に出るベクトルが計算できます。 これが面法線です。 面法線は、光の計算をするときや面の表裏を判定する時に使われます。 今回は三角ポリゴンの面法線を強制的に設定してみました。 するとライトの位置やポリゴンの材質、色や視点など全く変えていないにもかかわらず ポリゴンの色が変化します。 これは固定機能パイプラインが描画で使用する面法線が変化させられているために ポリゴンの向きは全く変わっていないのに別の方向を向いているものとして計算されるからです。 ファイル main.cpp main.cpp #pragma comment(linker, /SUBSYSTEM WINDOWS /ENT...
-
テッセレーション
テッセレーションです。 面を再分割してくれます。 今回のプログラムはスペースキーを押すとテッセレーションで表示します。 ファイル main.cpp main.cpp #pragma comment(linker, /SUBSYSTEM WINDOWS /ENTRY mainCRTStartup ) #include stdio.h #include GL/freeglut/freeglut.h #include vector using namespace std; #define WIDTH 320 #define HEIGHT 240 //頂点情報用 struct vector3d{ double x; double y; double z; }vec3d; vector vector3d vertex; //テッセレータオブジェクト GLUtess...
-
フラグメントシェーダー
フラグメントシェーダーです。DirectXではピクセルシェーダーと呼ばれる物です。 フラグメントシェーダーではピクセル単位で色々な処理ができます。 今回は頂点シェーダーで描画位置をずらし、フラグメントシェーダーで色を反転させます。 全く同じ位置で、全く同じ色で描画するプログラムがシェーダーによって変化させられています。 頂点シェーダー(vertex.shader) void main(void) { gl_Position = gl_ModelViewMatrix * gl_Vertex + gl_ModelViewMatrix * vec4(150.0,0.0,0.0,0.0);//頂点座標の出力 gl_FrontColor = gl_Color;//そのままフラグメントシェーダーへ } フラグメントシェーダー(flagment.shader) void main() { gl...
-
ソフトシャドウ
ソフトシャドウです。 影の外側を、ぼやけさせます。 vertex.shader varying vec3 P; varying vec3 N; void main(void) { P = vec3(gl_ModelViewMatrix * gl_Vertex); N = normalize(gl_NormalMatrix * gl_Normal); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_Vertex; gl_Position = ftransform(); } flagment.shader varying vec3 P; varying vec3 N; uniform sampler2DShadow shadowMap; uniform float dis;//サンプリング変位 float shadow = 0.3...
-
固定機能との違い
固定機能とプログラマブルシェーダーでは何がどう違うのでしょう。 固定機能ではフラットシェーディングやグーローシェーディング(スムースシェーディング)、 ワイヤーフレーム表示程度しかありませんでした。 擬似的にトゥーンシェーディングっぽく表示する事もできますが、トゥーンシェーディング とは全然品質が違います。 固定機能というのは、あらかじめ用意された範囲内で簡単手軽に機能を切り替えたり 描画に関する事を全て 『用意された中から選んで設定する』 という物でした。 簡単手軽ですが、グラフィックスで表現できる幅が文字通り固定されています。 そこで、より幅広いグラフィックスを表現するためにプログラマブルシェーダーが登場しました。 ここでは、シェーダー使用の描画とシェーダー未使用の描画をしてみました。 左が固定機能パイプラインで描画、右がシェーダーで色を反転させて描画した物です。 シェーダーファイルの...
-
シャドウマッピング
シャドウマッピングです。 一時的に視点を光源に移してみると光の当たる部分を見る事ができます。 その時の見えない部分=障害物=デプスバッファの値が影となります。 オブジェクトが別のオブジェクトに落とす影は、もちろんの事、 オブジェクト自身が自らに落とす影も描画する事ができます。 vertex.shader varying vec3 P; varying vec3 N; void main(void) { P = vec3(gl_ModelViewMatrix * gl_Vertex); N = normalize(gl_NormalMatrix * gl_Normal); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_Vertex; gl_Position = ftransform(); } flagment.shader v...
-
.MQOローダ(ワイヤーフレーム表示編)
ワイヤーフレーム表示です。 最初、 glDrawArrays を使って描画したら遅くて実用的ではありませんでした。 そこで色々、思考錯誤して glMultiDrawArrays を使ったら、割りとそれなりの 速度で描画できるようになったので公開します。 PNG.h #include lodepng.h //テクスチャクラス class TEXTURE{ protected LodePNG_Decoder decoder;//デコーダ unsigned char* buffer;//バッファ size_t buffersize, imagesize;//サイズ public TEXTURE(); TEXTURE(const char* FileName);//コンストラクタ void LOAD_PNG(const char* FileName);//PNG読み込み ...
-
水面
水面と集光模様です。 vertex.shader //フラグメントシェーダーに渡す変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル void main(void){ P = vec3(gl_ModelViewMatrix * gl_Vertex); N = normalize(gl_NormalMatrix * gl_Normal); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_Vertex; gl_Position = ftransform(); } flagment.shader //頂点シェーダーから受け取る変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル uniform sampler2D s...
-
.OBJを読み込んでみる2(読み込み編)
では、取りあえず簡単な読み込みプログラムを作ってみます。 今回はテクスチャ無しで、マテリアルも読み込んでいませんが .MQO の読み込みプログラムの時とは違って法線情報が ありますので陰影が表現されています。 box.obj # Created by Metasequoia mtllib box.mtl v -100.000000 100.000000 100.000000 v -100.000000 -100.000000 100.000000 v 100.000000 100.000000 100.000000 v 100.000000 -100.000000 100.000000 v 100.000000 100.000000 -100.000000 v 100.000000 -100.000000 -100.000000 v -100.000000 100.000000 -10...
-
固定機能:鏡面反射
鏡面反射です。 glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularLight); でスペキュラーライトを設定し、 glMaterialfv(GL_FRONT, GL_SPECULAR, specular); でスペキュラーの反射を設定し、 glMaterialf(GL_FRONT,GL_SHININESS,8); でスペキュラーの指数を設定します。 シェーダーで言うと頂点シェーダーで処理したような品質になります。 ファイル main.cpp main.cpp #pragma comment(linker, /SUBSYSTEM WINDOWS /ENTRY mainCRTStartup ) #include GL/freeglut/freeglut.h #define WIDTH 320 #define HEIGHT 240 //回転用...
-
2Dと3Dの描画を切り替える
2Dと言っても、今では3Dを平面的に扱って表示しています。 その方が高速だったからです。 そして、なんと言っても2Dを3Dの一部として扱うと、移動、回転、 拡大縮小が自由自在に行える利点もあります。 そこで2Dと3Dを同時に描画しようとした場合、工夫が必要になります。 上手く切り替えてやらないと3Dも2Dも同じように移動、回転、拡大縮小 してしまいます。 それには、まず3Dを描画してから glPushMatrix(); で階層を降ります。 そして2Dを描画して glPopMatrix(); で階層を上がります。 これを繰り返します。 つまり3Dを親階層として2Dを子階層とします。 なので、子階層で何をしようが、親階層には影響が無いのです。 ファイル main.cpp main.cpp #pragma comment(linker, /SUBSYSTEM WINDOWS /ENT...
-
法線の再設定
さて、前回のプログラムでは法線を再設定していないので ライトを有効にするとおかしな描画になってしまいます。 ここで言う法線とは頂点法線の事なので、前回のプログラムで 求められた頂点変換後の頂点座標がそのまま使えます。 一つ注意しないといけないのは頂点法線は正規化してデータに 納めないといけない事です。 font.h #pragma once class GLFONT { public HFONT Hfont; HDC Hdc; GLFONT(wchar_t *fontname, int size); void DrawStringW(int x,int y,wchar_t *format, ...); }; //コンストラクタ フォント作成 GLFONT GLFONT(wchar_t *fontname, int size) { Hfont = CreateFontW(...
-
.Xを読み込んでみる3(読み込み編)
では実際にXファイルを読み込んでみます。 今回は読み込み編という事で3角ポリゴンのみです。http //www.geocities.co.jp/Playtown-Spade/7188/こちらのデータを使わせて頂いています。 事前にメタセコイアで3角ポリゴンに変換してテクスチャを PNG 形式に変換しています。 Xファイルのテンプレートを除去しないと読み込みできません。 PNG.h #include lodepng.h //テクスチャクラス class TEXTURE{ protected LodePNG_Decoder decoder;//デコーダ unsigned char* buffer;//バッファ size_t buffersize, imagesize;//サイズ public TEXTURE(); TEXTURE(const char* FileName)...
-
ディスプレースメントマップ
ディスプレイスメントマップです。 右がディスプレイスメントマップで、左がバンプマッピングです。 右の方はポリゴン形状が変化しているのに対して左は1枚のポリゴンです。 実際に形状が変化しているので非常にリアルな表現ができます。 brick128.png bump128.png vertex.shader //フラグメントシェーダーに渡す変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル varying vec3 T;//接線ベクトル varying vec3 B;//従法線ベクトル attribute vec3 tangent;//OpenGLから void main(void) { P = vec3(gl_ModelViewMatrix * gl_Vertex); N = normalize(gl_NormalMatrix ...
-
.Xの階層メッシュアニメーションを読み込んでみる2
それでは、実際に階層構造を作って表示してみる事にします。 今回はアニメーションはせずに、ただ単にモデルを表示するだけです。 2分木構造を再帰関数を使ってデータ処理をする場合、return で戻る先を きちんと把握していないとおかしなデータ構造になってしまいます。 再帰関数というのは一つずつネストを深めて行きます。 なので、return すると1階層戻るのではなく 1 NODE 戻ります。 以下の図で説明すると Frame5 から1階層戻る時は 1回の return で 1階層戻りますが、Frame4 から 1階層戻る時は 1回目の return で Frame3 に戻り、2回目の return でFrame2 に戻り、3回目の return で Frame1 に戻って、やっと1階層戻る事になります。 PNG.h #pragma once #include lodepng.h //...
-
.Xを読み込んでみる4(表示編)
前回の読み込み編ではテンプレート無しで3角ポリゴンの Xファイルしか 読み込めませんでしたが、今回はテンプレートを読み飛ばし、3角と4角ポリゴンの 両方の Xファイルを読み込めるようにしました。 Xファイルは作成するソフトによって癖がありますので全ての3Dアプリが作る Xファイルに 対応する事はできません。とりあえずメタセコイアが作る Xファイルに対応しています。 PNG.h #include lodepng.h //テクスチャクラス class TEXTURE{ protected LodePNG_Decoder decoder;//デコーダ unsigned char* buffer;//バッファ size_t buffersize, imagesize;//サイズ public TEXTURE(); TEXTURE(const char* FileName);...
-
.FBXを読み込んでみる2(読み込み編)
それでは実際に FBXSDK を使用してデータを取り出してみようと思います。 まず、fbx20113_fbxsdk_win をインストールして Visual studio にパスを通します。 そして プロジェクトのフォルダに fbxsdk_20113.dll と fbxsdk_20113d.dll を置きます。 使い方は KFbxSdkManager を作成して、 KFbxImporter を作成して、 KFbxImporter にファイルを読み込んで初期化します。 そして、 KFbxScene を作成して、 KFbxScene に KFbxImporter で インポートします。 そして、 KFbxNode を辿って KFbxMesh を探します。 KFbxMesh が見つかったら、そこから各種情報を取り出します。 今回は三角ポリゴンのみでテクスチャ無し、オブジェクト(レイヤー)が一つだ...
-
3D:線分と無限平面
線分と無限平面の当たり判定です。 無限平面を表現するのは困難なので、今回は代わりに三角ポリゴンを表示しています。 ファイル main.cpp font.h main.cpp #pragma comment(linker, /SUBSYSTEM WINDOWS /ENTRY mainCRTStartup ) #include GL/freeglut/freeglut.h #include math.h #include stdio.h #include font.h #define PAI 3.14159 #define WIDTH 320 #define HEIGHT 240 //3つのベクトル struct Vector3f{ float x; float y; float z; Vector3f(){}; Vector3f(float _x,floa...
-
GLSLとの変数のやり取り
GLSL に値を渡すには glGetUniformLocation を使用して シェーダー側の変数のIDを取得します glUniform1f 等でそのIDの変数に値をセットします。 vertex.shader //OpenGLから受け取る変数 uniform float factor; vec4 v4 = vec4(0.0, 0.0, 0.0, 0.0); void main(void) { v4.x=factor; gl_Position = gl_ModelViewMatrix * gl_Vertex + gl_ModelViewMatrix * v4;//頂点座標の出力 gl_FrontColor = gl_Color;//そのまま出力 } flagment.shader //OpenGLから受け取る変数 uniform float flagment; vec4 ...
-
GLSL:テクスチャマッピング
GLSLでテクスチャを描画します。 vertex.shader //フラグメントシェーダーに渡す変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル void main(void) { P = vec3(gl_ModelViewMatrix * gl_Vertex); N = normalize(gl_NormalMatrix * gl_Normal).xyz; gl_TexCoord[0] = gl_MultiTexCoord0; gl_Position = ftransform(); } flagment.shader //頂点シェーダーから受け取る変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル uniform...
-
再びキーフレーム
長らく道を逸れましたが、ここで再びキーフレームに戻ります。 .Xのアニメーションキーのキータイプ情報 0…回転 w,x,y,zの順にクォータニオンデータ 1…拡大縮小 x,y,zの順に拡大縮小データ 2…平行移動 x,y,zの順に平行移動データ 4…合成行列 回転、拡大縮小、平行移動行列が掛け合わされた4×4行列データ まず、最初に知っておかなくてはならない事があります。 それは、当サイトで使用している Cyberdelia は、合成行列タイプの アニメーションデータは階層構造が正しく生成できないという事です。 詳しくは Cyberdelia に付属のヘルプを参照して下さい。 とは言っても、合成行列でないタイプの方は正しく出力されますので、 それを元に合成行列を作成し、単純なキーフレームアニメーションを表示して みたいと思います。 とりあえず、平行移動行列だけに対応したプログラムを作成...
-
.FBXを読み込んでみる3(表示編)
前回のプログラムはテクスチャ無しで3角ポリゴンの FBX ファイルしか 読み込めませんでした。 今回のプログラムは3角と4角の両方のポリゴンに対応しています。 テクスチャはレイヤー0しか対応していませんが通常の使用には問題ないと 思います。 PNG.h #pragma once #include lodepng.h //テクスチャクラス class TEXTURE{ protected LodePNG_Decoder decoder;//デコーダ unsigned char* buffer;//バッファ size_t buffersize, imagesize;//サイズ public TEXTURE(); TEXTURE(const char* FileName);//コンストラクタ void LOAD_PNG(const char* FileName);//P...
-
鏡面反射
プラスチックや金属など、よく磨きこまれた反射率の高い物体に光が当たると 表面が光り輝いているように見えます。 そのハイライトを表現するのが鏡面反射です。 vertex.shader //フラグメントシェーダーに渡す変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル void main(void) { P = vec3(gl_ModelViewMatrix * gl_Vertex); N = normalize(gl_NormalMatrix * gl_Normal); gl_Position = ftransform(); } flagment.shader //頂点シェーダーから受け取る変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル void main(void)...
-
線形補間
さて、前回の「再びキーフレーム」では箱が瞬間移動してしまって いました。 補間がされていないためです。 DirectX SDK 付属のビューワーでは滑らかにアニメーションが 補間されています。 今回はキーフレームとキーフレームの間を線形補間してみようと思います。 ベクトルAとベクトルB間の補間は、求める値をIとすると、 で求める事ができます。 ここでのtは現在のキー位置のパラメーターです。 尚、 0 ≦t≦ 1 で、tが0の時はAと同じ値、tが1の時はBと同じ値に なります。 前回と同じくsample2.xを表示しています。 font.h #pragma once class GLFONT { public HFONT Hfont; HDC Hdc; GLFONT(wchar_t *fontname, int size); void DrawStringW(int x,in...
-
.Xの階層メッシュアニメーションを読み込んでみる3
平行移動と同じようにして拡大縮小も線形補間してみました。 新規に作成した sample3.x を表示しています。 font.h #pragma once class GLFONT { public HFONT Hfont; HDC Hdc; GLFONT(wchar_t *fontname, int size); void DrawStringW(int x,int y,wchar_t *format, ...); }; //コンストラクタ フォント作成 GLFONT GLFONT(wchar_t *fontname, int size) { Hfont = CreateFontW( size, //フォント高さ 0, //文字幅 0, //テキストの角度 0, ...
-
3D:OBBとOBB
OBBです。 バウンディングスフィアの応用で中心位置と半径を使い、 内積と外積を駆使して当たり判定を行います。 font.h #pragma once class GLFONT { public HFONT Hfont; HDC Hdc; GLFONT(wchar_t *fontname, int size); void DrawStringW(int x,int y,wchar_t *format, ...); }; //コンストラクタ フォント作成 GLFONT GLFONT(wchar_t *fontname, int size) { Hfont = CreateFontW( size, //フォント高さ 0, //文字幅 0, //テキストの角度 0, ...
-
バンプマッピング
バンプマッピングです。 右はバンプマップ無しで左がバンプマップ有りの状態です。 バンプマッピングは見る角度によっては思ったような効果は出ません。 brick128.png bump128.png vertex.shader //フラグメントシェーダーに渡す変数 varying vec3 P;//位置ベクトル varying vec3 N;//法線ベクトル varying vec3 T;//接線ベクトル varying vec3 B;//従法線ベクトル attribute vec3 tangent;//OpenGLから void main(void) { P = vec3(gl_ModelViewMatrix * gl_Vertex); N = normalize(gl_NormalMatrix * gl_Normal); T = normalize(gl_NormalM...
-
.Xのスキンメッシュアニメーションを読み込んでみる2
.x のスキンメッシュアニメーションを読み込んで表示します。 このプログラムは box.x 専用です。 わかりやすくするために敢えて、このようにしました。 これで完成ではありません。 法線を再設定してあげないと光の反射具合が変になってしまいます。 詳しくは次回に回します。 font.h #pragma once class GLFONT { public HFONT Hfont; HDC Hdc; GLFONT(wchar_t *fontname, int size); void DrawStringW(int x,int y,wchar_t *format, ...); }; //コンストラクタ フォント作成 GLFONT GLFONT(wchar_t *fontname, int size) { Hfont = CreateFontW( ...
-
環境マッピング
環境マッピングです。 正面の球に部屋を反射させて描画します。 room.xは、ここからダウンロードできます。 右クリックして、名前を付けてリンク先を保存してください。 wall.png vertex.shader varying vec3 P; varying vec3 N; varying vec4 Reflect; uniform mat4 ViewTranspose;//ビュー変換だけのモデルビュー行列の転置行列 void main(void) { P = vec3(gl_ModelViewMatrix * gl_Vertex); N = normalize(gl_NormalMatrix * gl_Normal); vec3 incident = normalize(P);//入射視線ベクトル vec3 reflect0 = reflect(incident...
-
@wiki全体から「頂点配列」で調べる
更新順にページ一覧表示
|
作成順にページ一覧表示
|
ページ名順にページ一覧表示
|
wiki内検索