#include <iostream>
#include <gl/glew.h>//未定義トークン使用のため
#include <gl/glut.h>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <Cg/cg.h>
#include <Cg/cgGL.h>
#pragma comment (lib,"cg.lib")
#pragma comment (lib,"cgGL.lib")
#pragma comment (lib,"cv200.lib")
#pragma comment (lib,"cxcore200.lib")
#pragma comment (lib,"highgui200.lib")
//画像ファイル
const char *filename[]={"posx.jpg","negx.jpg","posy.jpg","negy.jpg","posz.jpg","negz.jpg"};
//テクスチャID
GLuint texId;
GLUquadricObj *quadric;
//-------- 各種外部変数 -------------//
//Cg用変数
CGcontext CgContext; //コンテキスト
CGprofile CgVertexProfile;//頂点プロファイル
CGprogram CgVertexProgram;
CGprofile CgFragmentProfile;//フラグメントプロファイル
CGprogram CgFragmentProgram;
CGparameter CgModelViewProj; //CGparameter型(ModelProj行列を取得)
CGparameter CgVertexRotAngle;//頂点シェーダ回転角度
CGparameter CgFs_CubeDecal;
//-------- プロトタイプ宣言 -----//
void display();
void reshape(int w, int h);
void drawXYZ();
//-------- Cgの初期設定 -----------//
//頂点シェーダ設定
void setUpCgVertex()
{
//プロファイルの取得
CgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
if(CgVertexProfile == CG_PROFILE_UNKNOWN)
{
std::cerr << "Invalid profile type\n";
exit(0);
}
cgGLSetOptimalOptions(CgVertexProfile);
//ファイルを読んでコンパイル
CgVertexProgram
= cgCreateProgramFromFile(
CgContext,//コンテキスト
CG_SOURCE,//Cgソースコード
"vertex.cg", //「.cgファイル名」
CgVertexProfile, //プロファイル
"CgVertexMain", //「.cgファイル」で最初にいく関数
NULL); //NULLでよい
cgGLLoadProgram(CgVertexProgram);//プログラムのロード
if(CgVertexProgram==NULL){
std::cerr <<"Vertex Program Err. \n";
exit(0);
}
//パラメータの関連付け
CgModelViewProj = cgGetNamedParameter(CgVertexProgram, "modelViewProj");
CgVertexRotAngle = cgGetNamedParameter(CgVertexProgram, "rotAngle");
}
//フラグメントの初期設定
void setUpCgFragment()
{
//プロファイルの取得
CgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
if(CgFragmentProfile == CG_PROFILE_UNKNOWN){
std::cerr << "Fragment : profile is unknown\n";
exit(0);
}
cgGLSetOptimalOptions(CgFragmentProfile);
//プログラムのコンパイル
CgFragmentProgram
= cgCreateProgramFromFile(
CgContext,//コンテキスト
CG_SOURCE,//Cgソースコード
"fragment.cg", //「.cgファイル名」
CgFragmentProfile, //プロファイル
"CgFragmentMain", //「.cgファイル」で最初にいく関数
NULL); //NULLでよい
cgGLLoadProgram(CgFragmentProgram); //プログラムのロード
if(CgFragmentProgram==NULL){
std::cerr <<"Fragment Program Err. \n";
exit(0);
}
CgFs_CubeDecal = cgGetNamedParameter(CgFragmentProgram, "cubeDecal");
cgGLSetTextureParameter(CgFs_CubeDecal, texId); //テクスチャとの関連付け
}
void CgINIT()
{
//コンテキスト作成
CgContext = cgCreateContext();
if(CgContext == NULL){
std::cerr << "Can't Create Context\n";
exit(0);
}
setUpCgVertex();
setUpCgFragment();
}
void idle()
{
glutPostRedisplay();
}
//------------ GLUTの初期設定 ---------------//
void GLUT_CALL_FUNC()
{
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
}
void OtherMyInit()
{
glClearColor(1,1,1,1);
glEnable(GL_DEPTH_TEST);
quadric = gluNewQuadric();
gluQuadricDrawStyle(quadric,GLU_FILL);
gluQuadricNormals(quadric,GLU_SMOOTH);
gluQuadricTexture(quadric,GLU_TRUE);
}
//テクスチャ読み込み
void LoadTexture()
{
GLenum cubefaces[6] = {
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
};
//6つを1つにまとめて扱う事ができる
glGenTextures(1,&texId);
glBindTexture(GL_TEXTURE_CUBE_MAP,texId);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
cv::Ptr<IplImage> imgA;
for(int loop = 0;loop < 6;++loop)
{
imgA = cvLoadImage(filename[loop]);
if(imgA.empty())
{
std::cerr << filename[loop] << " : Can't Load Image\n";
exit(EXIT_FAILURE);
}
glTexImage2D(cubefaces[loop],0,GL_RGB,imgA->width,imgA->height,0,GL_BGR,GL_UNSIGNED_BYTE,imgA->imageData);
imgA.release();
}
glBindTexture(GL_TEXTURE_CUBE_MAP,0);
}
void GLUT_INIT(int argc,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(640,480);
glutCreateWindow("simple animation");
GLUT_CALL_FUNC();
OtherMyInit();
LoadTexture();
}
//---------- メイン関数 ---------------//
int main(int argc,char **argv)
{
GLUT_INIT(argc,argv);
CgINIT();//Cgセットアップ
glutMainLoop();
return 0;
}
//----------- ここから各種コールバック -----------------//
void display()
{
static int angle = 0;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(2,3,5,0,0,0,0,1,0);
//Cgの有効化
cgGLBindProgram(CgVertexProgram);
cgGLEnableProfile(CgVertexProfile);
cgGLBindProgram(CgFragmentProgram);
cgGLEnableProfile(CgFragmentProfile);
cgGLEnableTextureParameter(CgFs_CubeDecal);//テクスチャのバインド
cgSetParameter1f(CgVertexRotAngle, static_cast<float>(angle)); //GPUで使う回転角度値の設定
//現在のmodelview,projection行列を取得
cgGLSetStateMatrixParameter(
CgModelViewProj,
CG_GL_MODELVIEW_PROJECTION_MATRIX,
CG_GL_MATRIX_IDENTITY);
cgUpdateProgramParameters(CgVertexProgram);//プログラムのパラメータの更新
gluSphere(quadric,1,60,60);
//glutSolidCube(1);
//Cgの無効化
cgGLDisableTextureParameter(CgFs_CubeDecal);//無効化
cgGLDisableProfile(CgVertexProfile);
cgGLDisableProfile(CgFragmentProfile);
drawXYZ();
glutSwapBuffers();
if(++angle >= 360)
{
angle = 0;
}
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0, (double)w / (double)h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void drawXYZ()
{
glBegin(GL_LINES);
glColor3f(1,0,0);
glVertex3f(0,0,0);
glVertex3f(200,0,0);
glColor3f(0,1,0);
glVertex3f(0,0,0);
glVertex3f(0,200,0);
glColor3f(0,0,1);
glVertex3f(0,0,0);
glVertex3f(0,0,200);
glEnd();
glColor3f(1,1,1);
}