REF
MS OpenGL REFERENCE
■ glNormal
SYNTAX
glNormal( );
DESC
glColor : 同様に glNormal() は定数設定処理が可能
TIP
各頂点属性ごとに stream をわけることも可能
stream 毎に 定数を使用するかどうかの flag, 周期を 定数 register に設定する
それを元に vfetch
2. 定数レジスタの数は 256 個のみ
3. 検証をする時は PIX でシェーダコストの分析をする
WARNING
dx は 定数設定処理ができない ∴ gpu 挙動
頂点毎に設定する必要あり
void drawCube3()
{
float s = 100;
static float v[] = {
-s, -s, s,
s, -s, s,
s, s, s,
-s, s, s,
-s, -s, -s,
s, -s, -s,
s, s, -s,
-s, s, -s,
};
static float n[] = {
0, 0, 1, 0, 0, -1,
1, 0, 0, -1, 0, 0,
0, -1, 0, 0, 1, 0,
};
// 6 QUADS
static unsigned short idx[] = {
0, 1, 2, 3, 4, 5, 6, 7,
1, 5, 6, 2, 4, 0, 3, 7,
4, 5, 1, 0, 3, 2, 6, 7,
};
glBegin( GL_QUADS );
for( int i=0; i< 6; i++ ){
// glColor と同じように, 現在の State の影響をうける
glNormal3fv( n + (3*i) );
for( int j=0; j< 4; j++ ){
int p = idx[ 4*i + j ];
glVertex3fv( v + 3*p );
}
}
glEnd();
glDisable( GL_LIGHTING );
}
glDisable(GL_CULL_FACE); // 両面を書く
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glPopMatrix();
glBegin( GL_TRIANGLES );
glEnd();
glColor3f();
glColor4f();
glVertexPointer( 3, GL_FLOAT, stride, (u8*)ofs + tom_fvf_2_vertex_offset );
stride == sz_per_vtx
TIP
lighting off でないと有効ではない
■ glColor
SYNTAX
glColor
DESC
頂点カラー を設定
glVertex() を call すると その時点の Color が設定される
// 1 Color で描画
glColor4f( 1,1,1,1 );
glVertex3f();
glVertex3f();
glVertex3f();
// 各頂点で変更
glColor4f( 1,1,1,1 );
glVertex3f();
glColor4f( 1,0,0,1 );
glVertex3f();
glColor4f( 0,0,1,1 );
glVertex3f();
■ glColorMask
SYNTAX
glColorMask()
DESC
framebuffer の書き込み制御
TRUE : ON
FALSE : 描画 OFF ( 黒が MASK )
■ 描画
■ glDrawArrays
SYNTAX
glDrawArrays( mode, offset, cnt );
DESC
格納した頂点バッファを描画する
glDrawElements とは違い 頂点配列 への Index を指定しないので
頂点バッファのデータは描画順にならんでないとだめ
[0]-- [3]
| |
| |
[1]-- [2]
// □をひとつ
// 0 番目から 4 個
glDrawArrays( GL_QUADS, 0, 4 );
■ glDrawElements
SYNTAX
void glDrawElements(
GLenum mode, // Primitive 形式の指定
GLsizei cnt , // 個数
GLenum type, //
const GLvoid *idx // 頂点配列をさす Index
);
■ glReadPixels
SYNTAX
void glReadPixels(
s32 x, s32 y, // 開始位置( WindowSpace )
u32 w, u32 h, // 大きさ
s32 fmt,
s32 type,
void *buf // Copy 先
)
DESC
Framebuffer の内容を Client Memory に Copy する
WARNING
この処理は、かなりの負荷がかかる
Default は BackBuffer から得る
この Command は 終了するまで制御を返さない
そして GL の Pipeline をすべて Flush する
REF
http://sky.geocities.jp/freakish_osprey/opengl/opengl_capture.htm
FW::init() {
//画像(読み取る領域)のピクセル数
int nr = w * h;
// 1 Pixel 要素数 ( RGB 3 RGBA 4 )
int format = 4; //rgba
// バッファから読み取ったデータを格納する配列
byte[] buf = new byte[nr * format];
//読み取るバッファを指定
//バックバッファを読み取る
//フロントバッファを読み取りたい GL_FRONT を指定
glReadBuffer( GL_BACK );
// ClientMemory への Pack ( 詰め込み )方法の指定
// Defalut ( GL_RGBA, GL_UNSIGNED_BYTE )は 密にセットする
//
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
// FrameBuffer image を使う Texture Object
glGenTextures( 1, &gId );
glBindTexture( GL_TEXTURE_2D, gId );
}
FW::update() {
// Scene を描画
drawScene();
// FrameBuffer から Pixel Data 取得
glReadPixels(
500, //読み取る領域の左下隅のx座標
500, //読み取る領域の左下隅のy座標
SW, //読み取る領域の幅
SH, //読み取る領域の高さ
GL_RGBA, //取得したい色情報の形式()
GL_UNSIGNED_BYTE, //読み取ったデータを保存する配列の型
gBuf //読み取ったデータを保存する配列
);
// Image の更新
glBindTexture( GL_TEXTURE_2D, gId );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, SW, SH, 0,
GL_RGBA, GL_UNSIGNED_BYTE, gBuf );
// 一度かいた絵を利用して何かする
draw();
}
//バッファから読み取る。
glReadPixels(
x, //読み取る領域の左下隅のx座標
y, //読み取る領域の左下隅のy座標
width, //読み取る領域の幅
height, //読み取る領域の高さ
GL_BGRA, //取得したい色情報の形式()
GL_UNSIGNED_BYTE, //読み取ったデータを保存する配列の型
buf //読み取ったデータを保存する配列
);
■ glReadBuffer
SYNTAX
void glReadBuffer( GLenum target )
DESC
読み取るバッファを指定
glReadPixels() などに影響する
// ちなみに最初の 1 回目の描画は Front Buffer には未初期化の画像があることがわかる
glReadPixels( GL_FRONT );
■ glPixelStorei
SYNTAX
void glPixelStorei(GLenum pname, GLint val)
DESC
set pixel storage modes
Main Memory と OpenGL 側の Memory でデータを転送するときに
Data がどのように配置( Alignment )されているか教える
1, 2, 4, 8 を指定できる
この数が 大きいほど 効率的に Data を転送できる
DEFAULT
4
POINT
unpack とは Application が GL に Pixel Data を送り出す時の指定方法
"store" 命令 と考えれば OK
GL_UNPACK_ALIGNMENT
Specifies the alignment requirements
for the start of each pixel row in memory.
The allowable values are
1 (byte-alignment),
2 (rows aligned to even-numbered bytes),
4 (word-alignment),
8 (rows start on double-word boundaries).
The initial value is 4.
// Client Memory から Read 方法を指定する
The following storage parameter affects
how pixel data is read from client memory.
// だから glTexImage2D() に必須
This value is significant for glTexImage2D and glTexSubImage2D:
// バッファの読み取り方を指定する
// Alignment を指定するらしい
// glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
WARNING
// 1 Pixel 3 byte の raw format を利用するときは必須
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
void *img = readRawTexture( "./test.raw" );
■ glCopyPixels
SYNTAX
glCopyPixels(
s32 x, y, // 読み取り位置
u32 w, h, // 大きさ
s32 type // Copy する Buffer の指定 ( GL_COLOR | GL_DEPTH | GL_STENCIL )
);
DESC
指定した Buffer を RasterPos の位置に Copy
■ glCopyTexImage2D
SYNTAX
void glCopyTexImage2D(
s32 tgt,
s32 lvl,
s32 ifmt, // Copy すべき対象を指定する
// GL_LUMINANCE : 輝度値のみ
// TextureObject にも DepthBuffer がある
s32 x,y,w,h, // Copy する FrameBuffer の矩形
// FrameBuffer( ReadBuffer ) の 左下.w, h は, FrameBuffer の左下からの サイズ.
// 小さい値をセットすれば当然きれる ( 観測すみ. )
s32 border
);
DESC
FrameBuffer( BackBuffer )から 画像data を TextureObject に Copy する
MultiPath には必須の API
TIP
parameter は glTexImage2D() と同じ
pixel data の転送元が異なるだけ
ARG3 : ReadBuffer からどの値をとるよーという宣言.
-> BackBuffer は, RGB + DEPTH だったから別々にとることも可能.
-> Texture
も Buffer だから どんな内部構成( ifmt )にするかの指定が可能
WARNING
w, h は 2冪.(VER:2.0 )
画面全体を copy するならば, 2 冪でないとだめ ?
// Depth 値もとれる
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16,
0, 0, vpW, vpH, 0 );
// Copy 先の Texture Object を選択
glBindTexture( GL_TEXTURE_2D, id );
if ( 0 ) {
glReadPixels(
500, //読み取る領域の左下隅のx座標
500, //読み取る領域の左下隅のy座標
SW, //読み取る領域の幅
SH, //読み取る領域の高さ
GL_RGBA, //取得したい色情報の形式()
GL_UNSIGNED_BYTE, //読み取ったデータを保存する配列の型
gBuf //読み取ったデータを保存する配列
);
// Image の更新
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, SW, SH, 0,
GL_RGBA, GL_UNSIGNED_BYTE, gBuf );
}
else {
// こちらの方が高速
glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA,
500, 500, SW, SH, 0 );
}
■ glCopyTexSubImage2D
SYNTAX
glCopyTexSubImage2D(
GLenum target,
GLint level,
GLint x, y, // Copy 先の Texture の位置
GLint x, y, // Copy 元の FrameBuffer の位置と大きさ
GLsizei w, h
)
WARNING
CubeMap には 裏側から利用するため Texture を反転する
■ glRasterPos
SYNTAX
void glRasterPos[234][sidf](
TYPE x,
TYPE y,
TYPE z,
TYPE w
);
DESC
RaterPos( Screen 上に描画する bitmap の位置 ) を指定する
POINT
glRasterPos で指定した位置は VertexTransform の影響をうける
3D 空間での glVertex と同様に考えればいい
RasterPos は次の変換をうける
ObjectSpace ---> ClipSpace ---> WindowSpace
ClipingVolume 内にある場合のみ WindowSpace へ変換される
// glVertex2f() と同じく Texcoord の影響をうける
glRasterPos2f( 1, 1 );
// z = 0, w = 1 としての扱われる
glRasterPos4f( 1, 1, 0, 1 );
WARNING
POINT
最も初期の FrameBuffer は HostMemory ( Application から直接参照できる Memory )
に格納されていた
■ glDrawPixels
SYNTAX
void glDrawPixels(
u32 w, u32 h, // Size
s32 fmt, // format ( RGB )
s32 type, // 型 ( U8 )
void *data // Pixel Data
);
DESC
CPU memory から FrameBuffer の PixelData に data を転送
( 読み込んだ画像を直接表示するときに利用する )
glRasterPos() で指定した位置に描画される
RasterPos が無効なら描画されない
POINT
glDrawPixels は以下の State の影響をうける
Pixel は 3D の描画と同じく Fragment の変換時に処理をうける
そのため Texture が有効なら 影響をうける
たいていは Default で問題なし
表示されない時は次の State を指定する
for( u32 i=0; i< 8; i++ ){
glActiveTexture( GL_TEXTURE0 + i );
glDisable( GL_TEXTURE_1D );
glDisable( GL_TEXTURE_2D );
glDisable( GL_TEXTURE_3D );
glDisable( GL_TEXTURE_CUBE_MAP );
}
// Fragment へ変換する際の FOG Color の着色
glDisable( GL_FOG );
glDisable( GL_DEPTH_TEST );
さらに Window の一部 が 別の Window に隠されている時も問題になる
OpenGL が 隠された 領域から Pixel Data を返せるかどうかは Window System に依存する
POINT
format
Pixel が何を表すか GL に伝える
色なら GL_RGBA
Depth なら GL_DEPTH_COMPONENT
type
Pixel の Data 型
GL の立場で考えれば この情報は必然
data の先頭は void * でもらうため
FW::init() {
glClearColor( 1, 0.7f, 1, 1 );
data = new u8[ w*h * sizeof(char) * 4 ];
for( u32 i=0; i< w*h; i++ ){
data[4*i + 0] = 255;
data[4*i + 1] = 255;
data[4*i + 2] = 0;
data[4*i + 3] = 255;
}
// 画面 size
float W = 1024.0f;
float H = W/2;
// ModelView 変換はしない
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
// 画面 size の大きさになるように Frustum を作成
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, W, 0, H, 1, 1000 );
// 影響のある TEST を OFF にする
// Rasterize 後の FragmentTest で不合格にならないように
glDisable( GL_DEPTH_TEST );
// Fragment 変換時に 不要な色がつかないように
glDisable( GL_TEXTURE_2D );
glDisable( GL_FOG );
glDisable( GL_BLEND );
}
void FW::Draw() {
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
static s32 cnt = 900;
float y = 100;
// x < 0 になると消える
glRasterPos3f( (--cnt), y, -1.5f ); // Z も Frustum にはいるように
// RasterPos が有効かチェックする
{
GLboolean ret;
glGetBooleanv( GL_CURRENT_RASTER_POSITION_VALID, &ret );
psc( "raster pos vaiid %d", ret );
}
glDrawPixels( w, h, GL_RGBA, GL_UNSIGNED_BYTE, data );
}
TIP
TextureObject を利用した方が処理が早い
-> EXT:GL_ARB_pixel_buffer_object により高速化可能
如何に処理負荷がかかるかわかる
WARNING
glRasterPos() は VertexTransform の影響をうける
-> ie. MV = UNIT, Frustum == Window の時に同一の場所になる.
glWindowPos() VER1.4 で直接指定可能.
Rasterize 時の State の影響もうける.
-> Tex OFF
-> DepthTest
■ glBitmap
SYNTAX
void glBitmap(
u32 w, u32 h, // 画像の大きさ
float x, float y, // 開始位置 offset
float xinc, float yinc,// 描画後 の RasterPos の移動量( WindowSpace )
byte *data
);
DESC
大きさ w, h の bimap ( 1pixel 1 bit 画像 )を x, y の位置から
現在の RasterPos に data を描画
描画後 は xinc, yinc だけ RasterPos が移動する
POINT
本来は txt を描画するために利用したが, RasterPos を移動するのに利用する
// "有効な位置" を指定する
glRasterPos( )
// glBitmap() で RasterPos を移動して "有効な位置" からずれても問題なし
glBitmap()
■ glWindowPos
SYNTAX
void glWindowPos[23][sifd]( type x, type x, type z );
VER
1.4
DESC
RasterPos を WindowSpace で指定する
VertexTransform をバイパスする
WARNING
Symbol が見つからないため 中止
■ glMultiTexCoord()
SYNTAX
void glMultiTexCoord( GLenum unitTex, TYPE tc );
DESC
指定した unitTex に tc をセットする.
REF
http://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20050704
TIP
glTexCoord(); は実は. glMultiTexCoord( GL_TEXTURE0, ); と同じ.
// Texture Unit 1 に Texture Coord を指定する
float t = { 0, 0, 1 };
glMultiTexCoord3fv( GL_TEXTURE1, t );
glBegin( GL_QUADS );
for( int i=0; i< 4; i++ ){
glVertex3fv( vtx );
}
glEnd();
PFNGLMULTITEXCOORD2DVPROC glMultiTexCoord2dv;
PFNGLMULTITEXCOORD3FVPROC glMultiTexCoord3fv;
glMultiTexCoord2dv =
(PFNGLMULTITEXCOORD2DVPROC)wglGetProcAddress("glMultiTexCoord2dv");
glMultiTexCoord3fv =
(PFNGLMULTITEXCOORD3FVPROC)wglGetProcAddress("glMultiTexCoord3fv");
■ glClientActiveTexture
SYNTAX
void glClientActiveTexture( GLenum unitTex );
DESC
VertexArray の tc をわりあてる, UnitTex を指定する.
TIP
MultiTex && VertexArray の組あわせで使う
■ glBindTexture
SYNTAX
void glBindTexture( GLenum tgt, GLuint idTextureObject );
DESC
TextureObject を選択する.
idTextureObject をはじめて渡す際に, TextureObject が作成される.
-> この時, TextureObject の param ( == State )は Default で初期化される.
EX.
img = NULL
ERROR
GL_INVALID_OPERATION:
異なる tgt を指定して bind をする.
■ glTexPrameter
SYNTAX
void glTexPrameter( GLenum tgt, GLenum namePrm, TYPE prm )
DESC
TextureObject の Parameter( State )を設定する
MipMap はメンドイので使わない方向で
仮説:
CurrentActiveUnit && CurrentBind TextureObject かな ?
3 種類のカテゴリ.
1.
Rasterize 時の Fragment と Texel の対応関係の指定.
Fragment が Texel より小さい場合: GL_TEXTURE_MAG_FILTER
Fragment が Texel を覆う場合: GL_TEXTURE_MIN_FILTER
WARNING:
Default が Mipmap を利用する
-> メンドイので省略.
GL に自動生成させる( 画像を指定する前に )
VER:1.4
{
glTexPrameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE );
glTexImage2D();
}
tc の wrapping Param : はみだしたときどうするか ?
TIP
■ glTexSubImage2D
SYNTAX
void glTexSubImage2D(
GLenum target,
GLint level,
GLint xoffset,
GLint yoffset,
GLsizei width
GLsizei height
GLenum format
GLenum type
const GLvoid * pixels
);
DESC
二次元のテクスチャーサブ画像を指定します
glTexImage2D の 部分集合版.
指定した Texture の一部分を利用する.
既存の二次元のテクスチャ画像の接触する部分領域を再定義します
Err
GL_INVALID_ENUM
target が GL_TEXTURE_2D でない場合
format が容認された定数でない
type が型定数でない場合
GL_INVALID_VALUE
width < 0 | height < 0
GL_INVALID_OPERATION
type がGL_UNSIGNED_SHORT_5_6_5で、format が GL_RGB でない場合
1.
■ glPushMatrix glPopMatrix
SYNTAX
KEY
TODO
NEXT
DESC
[ cur Mtx を cp ] したものを最上段に配置
TIP
MtxTex は Unit ごとに設定する. ( 選択は glActiveTexture で )
自前で mtx 計算をする場合は不要な処理のはず.
-> 余計な Error を防ぐために使用を禁止する.
Default
Stk ごとに 1 つの MtxUnit をふくむ.
EX
GL_MAX_( MODELVIEW | PROJECTION | TEXTURE )_STACK_DEPTH
WARNING
■ glDeleteTextures
SYNTAX
void glDeleteTextures( GLsizei, GLint * );
DESC
指定した Texture Object を破棄する
■ glDepthMask
SYNTAX void glDepthMask( bool flag );
DESC
指定した Buffer の書き込み Mask を設定する.
はいってくる Fragment に対して, 指定した bit と && 操作する.
-> なので, glDepthMask( true ); -> Depth 値が Buffer に書き込まれる.
TIP
glColorMask( bool red, bool, grn, bool blu, bool alp );
glStencilMask( int mask );
EX
WARNING
■ glFinish
SYNTAX
void glFinish()
DESC
この関数は、コマンドが完全に履行されるまで制御を返しません
発行済みコマンドを強制実行し、グラフィックス ハードウェアやネットワークが
コマンドの効果が現れた(描画を終了した)ことを保障した時点で制御が戻ります
[GPU]---> おわったよ ----> [CPU]
処理の同期をとる際に利用する.( ということは使わない方が早い ? )
-> StopWatch ではかろう.
-> たとえば, 2D 表示を別の PostScript などでする場合.
先に 3次元処理を終了しておく.
同期まちをするので, 過度の使用は APP の処理速度をおとす.
-> 特に Network 経由の場合.
基本的に glFlush() を利用するべし.
-> では描きはじめはどこでいえる ?
-> glFlush() かな ?
-> Block するということは,
■ glFlush
SYNTAX
void glFlush()
発行した OpenGL コマンドの実行を強制するという方法が用いられます
Flush == 送り出す.
[ 有.限.時.間.内 ]に終了することが保障される.
-> ということは...
[N: CPU:update]flush !
N[GPU:Render]
----------------------------------> 1 frame 内で終了すればよいのか.
WBuffer などで, Buffer を交換する際は, 自動的に Flush される.
ちなみに 今の FW では CMyGL::flip() で SwapBuffers( hDC ); をしている
-> FW::Draw() の最後.
-> もし Flush ならば, 処理待ちはしていないことになる.
-> ちなみに消すとまったく表示されなくなる.
-> しかし FW::update() は正しいようだ。
-> SwapBuffers の前に glFinish() を読んでも動作は OK のようだ.
コマンドを発行したからといって、サーバーが描画を終了しているとは限らないのです
-> なぜか ?
ClientServerModel だから, Newwork 経由で毎度命令データを送るわけではない.
-> 手紙一枚のために車を走らせる ?
-> というわけで、Packet をまとめてから送る.
-> でも促したい場合もある. -> そういう場合は, Flush する( 送り出す ).
Graphics 処理は PIPELINE 方式である.
[CPU] ---> [GPU] : この流れを 1 Frame 以内でしないこと.
-> というより今は 1 Frame でしているのか ?
-> 実はすでに遅延しているということはない ?
POINT
[CPU] : 描画CMD 発行. : ( 各 CMD の終了をまつ必要なし )
[GPU] : 専用の HW で処理.: CPU が送り出した 頂点を次々に処理する
-> というわけで, CPU は 各 CMD ごとに GPU の処理を待つ必要はない.
さて [CPU] < -> [GPU] が Network ではなれていた場合,
描画 CMD をひとつずつ送るのは、大変 OverHead がかかる.
-> よって, NetworkProgram は CMD を NetworkPacket にまとめる。
しかし [ 1Frame の描画 CMD の発行が終了した ]際は, 強制的に送ってほしい.
-> そこで glFlush(); -> 手紙を無理やり送る姿を想像しよう
Network をはさまない場合は, CMD 発行と同時に即時処理される
-> ということは PC はこちら. ?
-> じゃあ, 別に問題ないのでは ?
-> GPU. CPU が並行して動作しているのでは ?
-> とりあえず次のケースでは glFlush() が有効.
各 Frame の最後で, 残りの CMD をすべて送り出す保障をする.
SystemMemory に描画する SoftwareRenderer で 明示的に描画する際.
-> とりあえず glFlush(); は何回 call しても問題ないのかな ?
TIP
DX での Flush, Finish 相当は何か ?
EX
■ glClearColor
SYNTAX
void glClearColor( float r, float g, float b, float a );
DESC
glClear に使用する Color を設定する
[0-1] に clamp される
POINT
指定した Alpha 成分も, Clear() するとその値に FrameBuffer の Alpha 成分がなる
Shader, glCopyTexImage2D, Blend 時はこの Alpha 成分を利用することになる
FragmentShader で Fragment.w の値を指定すると Blend State で以下の影響をうける
DST( FrameBuffer) + SRC( Fragment )
WARNING
FrameBuffer に Alpha 成分がなければ Alpha 成分は無視される
TIP
Alpha も設定できることに注目
glCopyTexImage2D() では Alpha 成分も Copy できる
■ glClear
SYNTAX
void glClear( GLbitfield mask )
DESC
Frame Buffer をクリアする
Application は 各 frame の最初に color Buffer と DepthBuffer をクリアする
TIP
一度の 呼び出しで 複数の Buffer をクリアすると高速
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
■ glColorPointer
SYNTAX void glColorPointer(
GLint size,
GLenum type,
GLsizei stride,
const GLvoid *pointer
);
DESC
The glColorPointer function defines an array of colors.
BLEND OFF == glDisable( GL_BLEND );
Fragment col.w = 1; の値が FrameBuffer に格納される.
BLEND ON
Fragment col.w = a; BlendExp にしたがって格納。
-> 要は [ COLOR 成分 ]と同様にふるまう. と考えるべし.
TIP
Alpha も設定できることに注目
glCopyTexImage2D() では Alpha 成分も Copy できるようだ. !