I. ケース効果
このケースは回転とスピンのケースをベースにしています:
次に、コードの解析:
セットアップRC機能
- setupRC
- SetupRC
void SetupRC()
{
//1.クリア・スクリーンの色をカラー・バッファに設定する。
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
//2.シェーダー・マネージャーを初期化する。
shaderManager.InitializeStockShaders();
//3.深度テストを開く/バックサイドのカリング
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
//4.大玉をセットアップする
gltMakeSphere(torusBatch, 0.4f, 40, 80);
//5.ボールをセットアップする
gltMakeSphere(sphereBatch, 0.1f, 26, 13);
//6.床の頂点データを設定する&床のテクスチャ
GLfloat texSize = 10.0f;
floorBatch.Begin(GL_TRIANGLE_FAN, 4,1);
floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
floorBatch.Vertex3f(-20.f, -0.41f, 20.0f);
floorBatch.MultiTexCoord2f(0, texSize, 0.0f);
floorBatch.Vertex3f(20.0f, -0.41f, 20.f);
floorBatch.MultiTexCoord2f(0, texSize, texSize);
floorBatch.Vertex3f(20.0f, -0.41f, -20.0f);
floorBatch.MultiTexCoord2f(0, 0.0f, texSize);
floorBatch.Vertex3f(-20.0f, -0.41f, -20.0f);
floorBatch.End();
//7.ランダムボールの頂点座標データ
for (int i = 0; i < NUM_SPHERES; i++) {
//y軸はそのままで、X,Zはランダムな値を生成する。
GLfloat x = ((GLfloat)((rand() % 400) - 200 ) * 0.1f);
GLfloat z = ((GLfloat)((rand() % 400) - 200 ) * 0.1f);
//Y方向に、球を0.0こうすることで、テクスチャが目の高さに浮いているように見える。
//球の配列の各頂点に、頂点データをセットする。
spheres[i].SetOrigin(x, 0.0f, z);
}
//8.テクスチャ・オブジェクトに名前をつける
glGenTextures(3, uiTextures);
//9.TGAファイルを2Dテクスチャーとして読み込む。
//パラメーター1:テクスチャーファイルの名前
// 2&パラメータ3:縮小する必要がある&ズーム・フィルター
//パラメータ4:テクスチャ座標サラウンド・モード。
glBindTexture(GL_TEXTURE_2D, uiTextures[0]);
LoadTGATexture("marble.tga", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, GL_REPEAT);
glBindTexture(GL_TEXTURE_2D, uiTextures[1]);
LoadTGATexture("marslike.tga", GL_LINEAR_MIPMAP_LINEAR,
GL_LINEAR, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, uiTextures[2]);
LoadTGATexture("moonlike.tga", GL_LINEAR_MIPMAP_LINEAR,
GL_LINEAR, GL_CLAMP_TO_EDGE);
}
主にステップ8と9:
- ステップ8で、uiTexturesは、使用する床、大きなボール、小さなボールのテクスチャを含む定義されたテクスチャの配列です。
//テクスチャー・マーカーの配列
GLuint uiTextures[3];
bool LoadTGATexture(const char *szFileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode)
{
GLbyte *pBits;
int nWidth, nHeight, nComponents;
GLenum eFormat;
//1.テクスチャデータを読み込む
pBits = gltReadTGABits(szFileName, &nWidth, &nHeight, &nComponents, &eFormat);
if(pBits == NULL)
return false;
//2main関数ではテクスチャのパラメータを設定する。
//パラメータ1:テクスチャの寸法
//パラメータ2:テクスチャのS/T座標設定モード
//パラメータ3:wrapMode.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
//パラメータ1:テクスチャの寸法
//パラメーター2:線形フィルター
//パラメータ3:wrapMode,wrapMode
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
//3.テクスチャを読み込む
//パラメータ1:テクスチャの寸法
//パラメータ2:mipマッピングレベル
//パラメータ3:テクスチャー・セルの色成分。-内部パラメーターnComponentsを一般的な圧縮テクスチャー・フォーマットに変更する。GL_COMPRESSED_RGB
//パラメータ4:読み込んだテクスチャの幅
//パラメータ5:テクスチャの高さを読み込む
//パラメータ6:読み込んだテクスチャの深さ
//パラメータ7:ピクセル・データのデータ型
//パラメータ8:テクスチャのイメージデータへのポインタ。
glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB, nWidth, nHeight, 0,
eFormat, GL_UNSIGNED_BYTE, pBits);
//使用後はテクスチャーを解放する。pBits
free(pBits);
//Mipマップを生成できるのは以下の4つのモードと等しいminFilterだけである。
//GL_NEAREST_MIPMAP_NEARESTパフォーマンスも非常によく ちらつきも非常に弱い。
//GL_LINEAR_MIPMAP_NEARESTゲームのスピードアップによく使われる 高品質のリニア・フィルターを使う。
//GL_LINEAR_MIPMAP_LINEAR GL_NEAREST_MIPMAP_LINEAR フィルタは、Mipレイヤーの間にあるフィルタの跡を消すために、レイヤー間で余分な補間を行う。
//GL_LINEAR_MIPMAP_LINEAR トリリニアMipマッピング。最高精度でテクスチャー・フィルタリングを行う黄金律。
if(minFilter == GL_LINEAR_MIPMAP_LINEAR ||
minFilter == GL_LINEAR_MIPMAP_NEAREST ||
minFilter == GL_NEAREST_MIPMAP_LINEAR ||
minFilter == GL_NEAREST_MIPMAP_NEAREST)
//4.Mip、テクスチャをロードして、すべてのMipレイヤーを生成する。
// GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D
glGenerateMipmap(GL_TEXTURE_2D);
return true;
}
これでsetupRCのコードは終わりで、いくつかの初期化が行われます。
RenderSence関数
renderSence
RenderSence
//シーンを描画するために呼び出しを行う
void RenderScene(void)
{
//1.床の色の値
static GLfloat vFloorColor[] = { 1.0f, 1.0f, 0.0f, 0.75f};
//2.時間ベースのアニメーション
static CStopWatch rotTimer;
float yRot = rotTimer.GetElapsedSeconds() * 60.0f;
//3.カラーと深度バッファをクリアする
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//4.スタックに押し込む
modelViewMatrix.PushMatrix();
//5.オブザーバー行列を設定する
M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);
modelViewMatrix.MultMatrix(mCamera);
//6.スタック
modelViewMatrix.PushMatrix();
//7.---反射効果を追加する---
//Y軸を反転させる
modelViewMatrix.Scale(1.0f, -1.0f, 1.0f);
//鏡の世界はY軸を中心に一定の距離だけ平行移動する。
modelViewMatrix.Translate(0.0f, 0.8f, 0.0f);
//8.正面を時計回りに指定する
glFrontFace(GL_CW);
//9.地面以外のものを描く
drawSomething(yRot);
//10.正面を反時計回りに戻す
glFrontFace(GL_CCW);
//11.ミラーを描く、行列を復元する
modelViewMatrix.PopMatrix();
//12.ブレンド機能を有効にする
glEnable(GL_BLEND);
//13. glBlendFuncの混色式を指定する。
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//14.地面のテクスチャをバインドする
glBindTexture(GL_TEXTURE_2D, uiTextures[0]);
/*15.
テクスチャ調整シェーダー
パラメータ1:GLT_SHADER_TEXTURE_MODULATE
パラメータ2:モデル・ビューの投影行列。
パラメータ3:色
パラメータ4:テクスチャ・ユニット
*/
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_MODULATE,
transformPipeline.GetModelViewProjectionMatrix(),
vFloorColor,
0);
//shaderManager.UseStockShader(GLT_SHADER_TEXTURE_REPLACE,transformPipeline.GetModelViewProjectionMatrix(),0);
//描画を開始する
floorBatch.Draw();
//ブレンドをキャンセルする
glDisable(GL_BLEND);
//16.地面以外のものを描く
drawSomething(yRot);
//17.描画が終わったら、行列を復元する。
modelViewMatrix.PopMatrix();
//18.バッファを入れ替える
glutSwapBuffers();
//19.再レンダリングする
glutPostRedisplay();
}
- 実コンテンツとミラーコンテンツが実際に同じであるため、ちょうどイメージは、フロント方向を設定することによって、OpenGLで知っている前のコンテンツでは、フロントのデフォルトの反時計回りの方向ですので、実コンテンツは、反時計回りの方向で使用することができます達成することができます時計回りのミラーコンテンツができます。
- どのdrawSomething関数は、大きなボールを描画するために使用され、小さなボールは、フロントまたはミラーコンテンツかどうかは同じですが、方向が同じではないので、すべての呼び出しdrawSomethingを描画することができます。
- drawSomethingのコードは以下の通り:
void drawSomething(GLfloat yRot)
{
//1.光源の位置を定義する&拡散色
static GLfloat vWhite[] = { 1.0f, 1.0f, 1.0f, 1.0f };
static GLfloat vLightPos[] = { 0.0f, 3.0f, 0.0f, 1.0f };
//2.ホバリングするボールを描く
glBindTexture(GL_TEXTURE_2D, uiTextures[2]);
for(int i = 0; i < NUM_SPHERES; i++) {
modelViewMatrix.PushMatrix();
modelViewMatrix.MultMatrix(spheres[i]);
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
modelViewMatrix.GetMatrix(),
transformPipeline.GetProjectionMatrix(),
vLightPos,
vWhite,
0);
sphereBatch.Draw();
modelViewMatrix.PopMatrix();
}
//3.大きなボールを描く
modelViewMatrix.Translate(0.0f, 0.2f, -2.5f);
modelViewMatrix.PushMatrix();
modelViewMatrix.Rotate(yRot, 0.0f, 1.0f, 0.0f);
glBindTexture(GL_TEXTURE_2D, uiTextures[1]);
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
modelViewMatrix.GetMatrix(),
transformPipeline.GetProjectionMatrix(),
vLightPos,
vWhite,
0);
torusBatch.Draw();
modelViewMatrix.PopMatrix();
//4.回転するボールを描く(回転する)
modelViewMatrix.PushMatrix();
modelViewMatrix.Rotate(yRot * -2.0f, 0.0f, 1.0f, 0.0f);
modelViewMatrix.Translate(0.8f, 0.0f, 0.0f);
glBindTexture(GL_TEXTURE_2D, uiTextures[2]);
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,
modelViewMatrix.GetMatrix(),
transformPipeline.GetProjectionMatrix(),
vLightPos,
vWhite,
0);
sphereBatch.Draw();
modelViewMatrix.PopMatrix();
}
メイン機能
記事では、テクスチャの読み込みと使用、そしてテクスチャの削除について説明しました。
//テクスチャを削除する
void ShutdownRC(void)
{
glDeleteTextures(3, uiTextures);
}
int main(int argc, char* argv[])
{
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize();
glutCreateWindow("OpenGL SphereWorld");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
glutSpecialFunc(SpeacialKeys);
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW Error: %s
", glewGetErrorString(err));
return 1;
}
SetupRC();
glutMainLoop();
ShutdownRC();
return 0;
}
OK、それで最終的な効果が得られます。いいと思ったら、好きになるしかありません!それを読んで気に入った人は、すべての試験に合格し、すべての賞を獲得すると聞いたことがあります!





