BCB Client

- C++ Builderを用いたWindowsプログラミングメモ -

OpenGLを試してみる

せっかく強力なVGAを積んでるのにゲームにしか使えないなんて...

という訳でまずは、サンプルから。
インストールしたフォルダ(C:\Program Files\Borland\CBuilder6\Examples\OpenGL)の下に
「Drawing」と「Rotate」というOpenGLのサンプルがあります。

今回は「Drawing」を参考にしつつ...最もシンプルなコードで。


<GlSkel.h>
//---------------------------------------------------------------------------
#ifndef GlSkelH
#define GlSkelH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <gl\gl.h>	// OpenGL用のヘッダを忘れずに
//---------------------------------------------------------------------------
class TFormMain : public TForm
{
__published:
	void __fastcall FormResize(TObject *Sender);
	void __fastcall FormDestroy(TObject *Sender);
	void __fastcall FormCreate(TObject *Sender);

private:
	HDC hdc;
	HGLRC hrc;

	__fastcall TFormMain(TComponent* Owner);
	void __fastcall IdleLoop(TObject*, bool&);
	void __fastcall RenderGLScene();
	void __fastcall SetPixelFormatDescriptor();
	void __fastcall DrawObjects();
	void __fastcall SetupLighting();
};
//---------------------------------------------------------------------------
extern PACKAGE TFormMain *FormMain;
//---------------------------------------------------------------------------
#endif





<GlSkel.cpp>
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "GlSkel.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TFormMain *FormMain;
//---------------------------------------------------------------------------
// コンストラクタ
__fastcall TFormMain::TFormMain(TComponent* Owner)
    : TForm(Owner)
{
	// アイドル中の実行
	Application->OnIdle = IdleLoop;
}
//---------------------------------------------------------------------------
// フォーム開始
void __fastcall TFormMain::FormCreate(TObject *Sender)
{
	hdc = GetDC(Handle);		// デバイスコンテキスト取得
	SetPixelFormatDescriptor();	// ピクセルフォーマットの設定
	hrc = wglCreateContext(hdc);	// レンダリングコンテキスト作成
	if(hrc == NULL){
		ShowMessage("レンダリングコンテキスト作成失敗");
	}
	// 取得したレンダリングコンテキストに対してカレント設定
	if(wglMakeCurrent(hdc, hrc) == false){
		ShowMessage("wglMakeCurrent失敗");
	}

	// 深度バッファ有効
	glEnable(GL_DEPTH_TEST);
	// glClearでクリアする色を設定
	glClearColor(0.0, 0.0, 0.0, 1.0);
	// 照明と素材の設定
	SetupLighting();
}
//---------------------------------------------------------------------------
// ピクセルフォーマットの設定
void __fastcall TFormMain::SetPixelFormatDescriptor()
{
	// ココはとりあえず、おまじないとして。
	PIXELFORMATDESCRIPTOR pfd = {
		sizeof(PIXELFORMATDESCRIPTOR),
		1,
		PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
		PFD_TYPE_RGBA,
		24,
		0,0,0,0,0,0,
		0,0,
		0,0,0,0,0,
		32,
		0,
		0,
		PFD_MAIN_PLANE,
		0,
		0,0,
	};
	int PixelFormat = ChoosePixelFormat(hdc, &pfd);
	SetPixelFormat(hdc, PixelFormat, &pfd);
}
//---------------------------------------------------------------------------
// 照明と素材の設定
void __fastcall TFormMain::SetupLighting()
{
	// 素材に対する環境光、拡散光、鏡面光、光沢を設定
	GLfloat MaterialAmbient[] = {0.5, 0.5, 0.5, 1.0};
	GLfloat MaterialDiffuse[] = {1.0, 1.0, 1.0, 1.0};
	GLfloat MaterialSpecular[] = {1.0, 1.0, 1.0, 1.0};
	GLfloat MaterialShininess[] = {50.0};

	// 照明の位置
	GLfloat AmbientLightPosition[] = {0.5, 1.0, 1.0, 0.0};
	// 環境光の設定
	GLfloat LightAmbient[] = {0.5, 0.5, 0.5, 1.0};

	glMaterialfv(GL_FRONT, GL_AMBIENT, MaterialAmbient);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, MaterialDiffuse);
	glMaterialfv(GL_FRONT, GL_SPECULAR, MaterialSpecular);
	glMaterialfv(GL_FRONT, GL_SHININESS, MaterialShininess);
	glLightfv(GL_LIGHT0, GL_POSITION, AmbientLightPosition);
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, LightAmbient);

	glEnable(GL_LIGHTING);		// 照明を有効
	glEnable(GL_LIGHT0);		// 照明0を有効
	glEnable(GL_COLOR_MATERIAL);	// 素材の色設定を有効
	// 素材の表面に環境光と拡散光を有効にします
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

	glShadeModel(GL_SMOOTH);	// ポリゴンを滑らかに見せる
}
//---------------------------------------------------------------------------
// リサイズ処理
void __fastcall TFormMain::FormResize(TObject *Sender)
{
	float nRange = 3.0;

	// クライアント領域をビューポートとします
	int w = ClientWidth;
	int h = ClientHeight;

	if(w == 0) w = 1;
	if(h == 0) h = 1;

	// ビューポートの設定
	glViewport(0, 0, w, h);

	// 視野を設定する際は投影行列に切り替えます
	glMatrixMode(GL_PROJECTION);
	// 単位行列に設定
	glLoadIdentity();
	// 視野を設定
	if(w <= h){
		// 正射影で設定(視野=視体積を左,右,下,上,手前,奥の順に設定)
		glOrtho(-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);
	}
	else{
		glOrtho(-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);
	}
	// ポリゴンを描画するにはモデルビュー行列に切り替えます
	glMatrixMode(GL_MODELVIEW);
	// 単位行列に設定
	glLoadIdentity();
}
//---------------------------------------------------------------------------
// フォーム終了
void __fastcall TFormMain::FormDestroy(TObject *Sender)
{
	wglMakeCurrent(NULL, NULL);
	wglDeleteContext(hrc);
}
//---------------------------------------------------------------------------
// 描画ループ(アイドル中はココが呼ばれ続けます)
void __fastcall TFormMain::IdleLoop(TObject*, bool& done)
{
	done = false;
	RenderGLScene();	// 描画部
	SwapBuffers(hdc);	// バッファを切替
}
//---------------------------------------------------------------------------
// 描画
void __fastcall TFormMain::RenderGLScene()
{
	// 描画された絵を毎回消します
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glRotatef(1, 0, 1, 0);	// Y軸を基準に1度ずつ回ります

	glBegin(GL_TRIANGLES);		// 三角形を描く
		glColor3f(1,0,0);	// 色は赤で
		glVertex3f(0,0,0);	// 座標x=0,y=0,z=0と
		glVertex3f(1,0,0);	// 座標x=1,y=0,z=0と
		glVertex3f(0,1,0);	// 座標x=0,y=1,z=0を結んだ三角形を
	glEnd();			// 描画します

	glFlush();	// これまでのOpenGLコマンド実行
}
//---------------------------------------------------------------------------


と..まぁ新しい事がワンサカ出てきましたね..

opengl_01.png



 ←実行すると赤い三角形がグリグリ回ってます。







ま、詳しい事は追々と..

[ トップ | 一覧 | 前へ | 次へ ]

  • トップ
  • 一覧
  • リンク
  • 掲示板

Copyright © BCB Client. All Rights Reserved. Template by ネットマニア