2008年8月22日 (金)

メモ2

Windowsフォームアプリケーションでプロジェクトを作成して…っていうやつの続き。

imagireさんのページのサンプルを元につくて見たがどうも描画がされない。

で,描画関数そのものはコールされているので問題ない模様。

色々といじってみた結果,共通ランタイムサポートの項目を変更して,それで動いた。

デフォルトでは(/clr:pure)とか言うのになっているが,下のようにこれを(/clr)にすると動く。

なんかこういうところが,素人にはわかりずらいっすね。

そんなわけで無事,レンダリング結果が表示されました。

Image3 Image2

| コメント (0) | トラックバック (0)

2008年8月21日 (木)

メモ…。

Visual C++ 2005, 2008でWindows フォームアプリケーションでプロジェクトを作成して,コンパイルしたときに…

1>AsuraCGL.obj : error LNK2028: 未解決のトークン (0A00000D) "extern "C" int __stdcall SetPixelFormat(struct HDC__ *,int,struct tagPIXELFORMATDESCRIPTOR const *)" (?SetPixelFormat@@$$J212YGHPAUHDC__@@HPBUtagPIXELFORMATDESCRIPTOR@@@Z) が関数 "private: int __clrcall Asura::CGl::SetupPixelFormat(struct HDC__ *)" (?SetupPixelFormat@CGl@Asura@@$$FAAMHPAUHDC__@@@Z) で参照されました。
1>AsuraCGL.obj : error LNK2028: 未解決のトークン (0A00000E) "extern "C" int __stdcall ChoosePixelFormat(struct HDC__ *,struct tagPIXELFORMATDESCRIPTOR const *)" (?ChoosePixelFormat@@$$J18YGHPAUHDC__@@PBUtagPIXELFORMATDESCRIPTOR@@@Z) が関数 "private: int __clrcall Asura::CGl::SetupPixelFormat(struct HDC__ *)" (?SetupPixelFormat@CGl@Asura@@$$FAAMHPAUHDC__@@@Z) で参照されました。
1>AsuraCGL.obj : error LNK2028: 未解決のトークン (0A000010) "extern "C" int __stdcall ReleaseDC(struct HWND__ *,struct HDC__ *)" (?ReleaseDC@@$$J18YGHPAUHWND__@@PAUHDC__@@@Z) が関数 "public: __clrcall Asura::CGl::~CGl(void)" (??1CGl@Asura@@$$FQAM@XZ) で参照されました。
1>AsuraCGL.obj : error LNK2028: 未解決のトークン (0A000013) "extern "C" struct HDC__ * __stdcall GetDC(struct HWND__ *)" (?GetDC@@$$J14YGPAUHDC__@@PAUHWND__@@@Z) が関数 "public: __clrcall Asura::CGl::CGl(struct HWND__ *)" (??0CGl@Asura@@$$FQAM@PAUHWND__@@@Z) で参照されました。
1>AsuraCGL.obj : error LNK2019: 未解決の外部シンボル "extern "C" int __stdcall ReleaseDC(struct HWND__ *,struct HDC__ *)" (?ReleaseDC@@$$J18YGHPAUHWND__@@PAUHDC__@@@Z) が関数 "public: __clrcall Asura::CGl::~CGl(void)" (??1CGl@Asura@@$$FQAM@XZ) で参照されました。
1>AsuraCGL.obj : error LNK2019: 未解決の外部シンボル "extern "C" int __stdcall SetPixelFormat(struct HDC__ *,int,struct tagPIXELFORMATDESCRIPTOR const *)" (?SetPixelFormat@@$$J212YGHPAUHDC__@@HPBUtagPIXELFORMATDESCRIPTOR@@@Z) が関数 "private: int __clrcall Asura::CGl::SetupPixelFormat(struct HDC__ *)" (?SetupPixelFormat@CGl@Asura@@$$FAAMHPAUHDC__@@@Z) で参照されました。
1>AsuraCGL.obj : error LNK2019: 未解決の外部シンボル "extern "C" int __stdcall ChoosePixelFormat(struct HDC__ *,struct tagPIXELFORMATDESCRIPTOR const *)" (?ChoosePixelFormat@@$$J18YGHPAUHDC__@@PBUtagPIXELFORMATDESCRIPTOR@@@Z) が関数 "private: int __clrcall Asura::CGl::SetupPixelFormat(struct HDC__ *)" (?SetupPixelFormat@CGl@Asura@@$$FAAMHPAUHDC__@@@Z) で参照されました。
1>AsuraCGL.obj : error LNK2019: 未解決の外部シンボル "extern "C" struct HDC__ * __stdcall GetDC(struct HWND__ *)" (?GetDC@@$$J14YGPAUHDC__@@PAUHWND__@@@Z) が関数 "public: __clrcall Asura::CGl::CGl(struct HWND__ *)" (??0CGl@Asura@@$$FQAM@PAUHWND__@@@Z) で参照されました。
1>C:\Users\Ishibashi\Desktop\a\Debug\a.exe : fatal error LNK1120: 外部参照 8 が未解決です。

…というエラーメッセージが出る問題

この原因は,ただ単に最後のメッセージにあるように外部参照が未解決になっているせい。

これは

#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")

の二つを入れてやれば,万事解決。

解決のもとになったのは次のページ…。

http://vsug.jp/tabid/63/forumid/42/postid/9206/scope/posts/Default.aspx

| コメント (0) | トラックバック (0)

2008年8月 8日 (金)

OpenGLで動画

OpenGLの実行画面をキャプチャーしてビデオを作成したいなぁ~と思って,プログラム組んでみたのですが,やっぱりglReadPixels()を使っているせいか,録画最中はかなりフレームレートが下がって使いもんにならなそうです。

なんか,うまいやり方ありそうなんですけどね…全然わかりません。

あんまし,いい結果にならないので,ホームページではなく,ここで一応要の部分のコードを公開しておこうかなって思います。

<< AviCreator.h >>

#ifndef __AVI_CREATOR_H_INCLUDED__
#define __AVI_CREATOR_H_INCLUDED__

//
// Includes
//
#include <windows.h>
#include <vfw.h>
#include <GL/glew.h>
#include <GL/glut.h>

//
// Link
//
#pragma comment(lib, "vfw32.lib")
#pragma comment(lib, "glew32.lib")

//
// CAviCreator class
//
class CAviCreator
{
protected:
unsigned int m_Width;
unsigned int m_Height;
unsigned long m_Size;
unsigned long m_Scale;
unsigned long m_Rate;
GLubyte* m_Pixels;
unsigned long m_FrameCount;
AVISTREAMINFOA m_AviStreamInfo;
PAVIFILE m_pAviFile;
PAVISTREAM m_pAviStream;
GLuint m_PboID[2];

public:
CAviCreator();
~CAviCreator();

bool Start( unsigned int width, unsigned int height, const char *file, unsigned long scale, unsigned long rate );
bool CaptureWindow();
void End();
void Release();
};

#endif // __AVI_CREATOR_H_INCLUDED__

<< AviCreator.cpp >>

//
// Includs
//
#include "AviCreator.h"

/////////////////////////////////////////////////////////////////////////
// CAviCreator class
/////////////////////////////////////////////////////////////////////////

//----------------------------------------------------------------------------------------------------
// Name : CAviCreator()
// Desc : コンストラクタ
//----------------------------------------------------------------------------------------------------
CAviCreator::CAviCreator()
{
m_Width = 0;
m_Height = 0;
m_Scale = 0;
m_Rate = 0;
m_Size = 0;
m_Pixels = NULL;
m_FrameCount = 0;
m_PboID[0] = 0;
m_PboID[1] = 0;
}

//----------------------------------------------------------------------------------------------------
// Name : ~CAviCreator()
// Desc : デストラクタ
//----------------------------------------------------------------------------------------------------
CAviCreator::~CAviCreator()
{
Release();
}

//----------------------------------------------------------------------------------------------------
// Name : Release()
// Desc : 後片付け
//----------------------------------------------------------------------------------------------------
void CAviCreator::Release()
{
// PBOの破棄
if ( m_PboID[0] != 0 )
{
  glDeleteBuffers( 1, &m_PboID[0] );
  m_PboID[0] = 0;
}
if ( m_PboID[1] != 0 )
{
  glDeleteBuffers( 1, &m_PboID[1] );
  m_PboID[1] = 0;
}

m_Width = 0;
m_Height = 0;
m_Scale = 0;
m_Rate = 0;
m_Size = 0;
m_Pixels = NULL;
m_FrameCount = 0;
}

//----------------------------------------------------------------------------------------------------
// Name : Start()
// Desc : セットアップをして録画を開始
//----------------------------------------------------------------------------------------------------
bool CAviCreator::Start(unsigned int width, unsigned int height, const char *file, unsigned long scale, unsigned long rate)
{
// GLEWの初期化
if ( glewInit() != GLEW_OK )
{
  MessageBox( NULL, TEXT("Error : GLEWの初期化に失敗しました"), TEXT("Error !!"), MB_ICONERROR | MB_OK );
  return false;
}

// 変数代入
m_Width = width;
m_Height = height;
m_Scale = scale;
m_Rate = rate;
m_FrameCount = 0;
m_Size = 0;

// サイズ決定
m_Size = (((m_Width*24+31)&~31 )/8) * m_Height;

// 設定
BITMAPINFOHEADER bmih = { sizeof(BITMAPINFOHEADER), m_Width, m_Height, 1, 24, BI_RGB, m_Size, 0, 0, 0, 0 };
AVISTREAMINFOA si = { streamtypeVIDEO, comptypeDIB, 0, 0, 0, 0, m_Scale, m_Rate, 0, 0, 0, 0, (DWORD)-1, 0, { 0, 0, m_Width, m_Height }, 0, 0, "VIDEO" };
m_AviStreamInfo = si;

// AVIファイルの初期化
AVIFileInit();

// ファイルオープン
if ( AVIFileOpenA( &m_pAviFile, file, OF_CREATE | OF_WRITE | OF_SHARE_DENY_NONE, NULL ) != 0 )
{
  MessageBox( NULL, TEXT("Error : ファイルが開けませんでした"), TEXT("Error !!"), MB_ICONERROR | MB_OK );
  return false;
}

// ストリーム作成
if ( AVIFileCreateStreamA( m_pAviFile, &m_pAviStream, &m_AviStreamInfo ) != 0 )
{
  MessageBox( NULL, TEXT("Error : 編集用ファイルストリームの作成に失敗しました"), TEXT("Error !!"), MB_ICONERROR | MB_OK );
  return false;
}

// フォーマットをセット
if ( AVIStreamSetFormat( m_pAviStream, 0, &bmih, sizeof(BITMAPINFOHEADER) ) != 0 )
{
  MessageBox( NULL, TEXT("Error : ストリームのフォーマット設定に失敗しました"), TEXT("Error !!"), MB_ICONERROR | MB_OK );
  return false;
}

// PBOを作成
glGenBuffers( 2, m_PboID );
glBindBuffer( GL_PIXEL_PACK_BUFFER, m_PboID[0] );
glBufferData( GL_PIXEL_PACK_BUFFER, m_Size, 0, GL_STREAM_READ );
glBindBuffer( GL_PIXEL_PACK_BUFFER, m_PboID[1] );
glBufferData( GL_PIXEL_PACK_BUFFER, m_Size, 0, GL_STREAM_READ );
glBindBuffer( GL_PIXEL_PACK_BUFFER, 0 );

return true;
}

//----------------------------------------------------------------------------------------------------
// Name : CaptureWindow()
// Desc : 描画結果をキャプチャーしてフレームに書き込み
//----------------------------------------------------------------------------------------------------
bool CAviCreator::CaptureWindow()
{
static int index = 0;
static int nextIndex = 0;

// インデックス決定
index = (index + 1) %2;
nextIndex = (index + 1) %2;

// ピクセルデータの読み取り
glBindBuffer( GL_PIXEL_PACK_BUFFER, m_PboID[index] );
glReadPixels( 0, 0, m_Width, m_Height, GL_BGR, GL_UNSIGNED_BYTE, 0 );
glBindBuffer( GL_PIXEL_PACK_BUFFER, m_PboID[nextIndex] );
m_Pixels = (GLubyte*)glMapBuffer( GL_PIXEL_PACK_BUFFER, GL_READ_ONLY );

// ファイルに書き込み
if ( AVIStreamWrite( m_pAviStream, m_FrameCount++, 1, m_Pixels, m_Size, AVIIF_KEYFRAME, NULL, NULL ) )
{
  return false;
}

// バインドを戻す
glUnmapBuffer( GL_PIXEL_PACK_BUFFER );
glBindBuffer( GL_PIXEL_PACK_BUFFER, 0 );

return true;
}

//----------------------------------------------------------------------------------------------------
// Name : End()
// Desc : ファイル作成終了
//----------------------------------------------------------------------------------------------------
void CAviCreator::End()
{
// ストリームを破棄
AVIStreamRelease( m_pAviStream );

// ファイルを破棄
AVIFileRelease( m_pAviFile );

// ファイル作成終了
AVIFileExit();

// 後片付け
Release();

//
MessageBox( NULL, TEXT("AVIファイルの作成に成功しました"), TEXT("ファイル作成完了"), MB_ICONINFORMATION | MB_OK );
}

| コメント (0) | トラックバック (0)

2008年7月 5日 (土)

いつの間にか

いつの間にか気づくとNVIDIAのDeveloper SiteでFx Composer 2.5とShader Debuggerの新しいバージョンがアップされていますね。(Beta版じゃないやつ)

なんかShader Debuggerのほうは商用でなければフリーで使えるみたいですが,商用の場合はお金払わないといけないみたいですね。

| コメント (0) | トラックバック (0)

2008年6月26日 (木)

いってみたいな~

IGDAからメールが来ていて7/4に研究会があるそうですね。

ちょっといってみたいですね。

http://www.igda.jp/modules/eguide/event.php?eid=55

| コメント (0) | トラックバック (0)

2008年6月23日 (月)

そんなのあったの?

ちまちまと研究を進めているのですが,そろそろマルチスレッドでも使おうかと思っているのですが,いろいろと調べていたらOpenMPっていうのがあるんですね。

昨日のimagireさんの発表を聞くまで存在を知りませんでした。

毎度ですけども情けないですね~。時代に10年のり遅れている感じがしてしょうがないですよ。

| コメント (0) | トラックバック (0)

2008年6月15日 (日)

ばーじょんあっぷ。

Code2Htmlのバージョンアップを行いました。

今までのやつはシェーダファイルをC/C++と混同にして出力するようにしていたのですが,シェーダ使わない人がlengthとか打ち込んで青色になっていたら,さぞおかしいと思うのではないかと思い,出力設定でC/C++, C#, Cg, HLSL, GLSLを個別に指定できるようにしてみました。

それと今回からHLSLとGLSLに対応するようになりました。

HLSLのほうはDirectX 10のエフェクト形式に対応するようになっていますが, GLSLの方はOpenGL Orgにいったら古い資料しかなかったので,ジオメトリに関する関数などはハイライトされませんので,ご注意を。

| コメント (0) | トラックバック (0)

2008年6月 2日 (月)

マテリアルの送り方。

Image1

XNA!XNA!C#!C#!と周りに叫んでいるのですが,最近はちょっとプログラムを組んでいませんでした。

…というのも,自分で書いたエフェクトファイルを使って,シェーダの方に色を渡すやりかたがわからなかったんですよ。

単色とかテクスチャを使ってしまえば,プログラムの方で読み込んで送れば済む話なのですが,テクスチャ作るの面倒なのですよ。できればファイルに格納されているマテリアルを自分で書いたシェーダに渡す方法がわからなくてずっとなやんでいたのですが,「ひにけにXNA」あたりに書いてあるんじゃないかと思い,記事をあさっていたらありました。

http://blogs.msdn.com/ito/archive/2007/12/21/rendering-a-model-with-a-custom-effect.aspx

カスタムエフェクトを使うってやつです。Creators Club OnlineにあるXNAのサンプルを早速ダウンロードしていじってみました。

あとついでにアンチエイリアス(4xAA)もかけてみたのですが,劇的に違いますね。

ポリゴンのジャギーが全然気にならないですよ!

で,マテリアルの送り方なのですが

// ここで任意のエフェクトパラメーターの設定もできる
    
myMaterial.OpaqueData.Add("Shininess", basicMaterial.SpecularPower * 10);

ということろで,

   myMaterial.OpaqueData.Add("ModelDiffuse", basicMaterial.DiffuseColor);

   myMaterial.OpaqueData.Add("ModelSpecular", basicMaterial.SpecularColor);

という風にシェーダに送りたいパラメータを追加してやればよいみたいです。

サンプルなんかでは,エフェクトファイルを直接指定したりしているんですが,使い回すことが多い場合,いちいちcsファイルを立ち上げて変更するのは面倒です。

そんなわけで,プロパティの項目からエフェクトファイルを指定したりできるようにしてみたりしました。

Image2

何も知らない状態だと「XNAって面倒だな~」という風に思うのですが,知っている状態だと「意外と便利!」と思えます。

日本ではXNA GSについての本がやたらと少ない(DirectX 10もそうだけど…)ので,誰か現役のゲームプログラマーさんが書いてくれないかな~なんておもっているんですけどね。ホントだれか書いてくれないですかね?書いてくれたら即買いするんですけど。

| コメント (0) | トラックバック (0)

2008年5月29日 (木)

ひさしぶりに…

ひさしぶりに,ユーザーインターフェースを作ってみました。

昔つくったやつよりは結構気に入っています。

Image0

| コメント (0) | トラックバック (0)