#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#include <GL/freeglut/freeglut.h>
#include <stdio.h>
#include <math.h>
#define WIDTH 320
#define HEIGHT 240
//平行移動用
float x = 0.0f;
float y = 0.0f;
bool flag = false;
bool flag2 = false;
//ライトの位置
GLfloat lightpos[] = { 200.0, 300.0, -500.0, 1.0 };
//3つのベクトル
struct Vector3f{
float x;
float y;
float z;
}vec3d;
Vector3f & operator+(Vector3f &a,Vector3f &b){
a.x+=b.x;
a.y+=b.y;
a.z+=b.z;
return a;
}
Vector3f & operator-(Vector3f &a,Vector3f &b){
a.x-=b.x;
a.y-=b.y;
a.z-=b.z;
return a;
}
//直方体構造体
struct Cuboid{
GLfloat Color[4];//色
Vector3f Radius;//半径
Vector3f Pos;//位置
void Draw();
void make_cuboid(float width,float height,float depth);
};
void Cuboid::Draw(){
glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
glMaterialfv(GL_FRONT, GL_DIFFUSE, Color);
glTranslatef(Pos.x,Pos.y,Pos.z);
make_cuboid(Radius.x,Radius.y,Radius.z);
}
//直方体
void Cuboid::make_cuboid(float width,float height,float depth)
{
glBegin(GL_QUADS);
//前
glNormal3f(0.0,0.0,-1.0);
glVertex3f(width/2,height/2,depth/2);
glVertex3f(-width/2,height/2,depth/2);
glVertex3f(-width/2,-height/2,depth/2);
glVertex3f(width/2,-height/2,depth/2);
//左
glNormal3f(1.0,0.0,0.0);
glVertex3f(width/2,height/2,depth/2);
glVertex3f(width/2,height/2,-depth/2);
glVertex3f(width/2,-height/2,-depth/2);
glVertex3f(width/2,-height/2,depth/2);
//右
glNormal3f(-1.0,0.0,0.0);
glVertex3f(-width/2,height/2,-depth/2);
glVertex3f(-width/2,height/2,depth/2);
glVertex3f(-width/2,-height/2,depth/2);
glVertex3f(-width/2,-height/2,-depth/2);
//後
glNormal3f(0.0,0.0,1.0);
glVertex3f(width/2,height/2,-depth/2);
glVertex3f(-width/2,height/2,-depth/2);
glVertex3f(-width/2,-height/2,-depth/2);
glVertex3f(width/2,-height/2,-depth/2);
//上
glNormal3f(0.0,1.0,0.0);
glVertex3f(width/2,height/2,depth/2);
glVertex3f(-width/2,height/2,depth/2);
glVertex3f(-width/2,height/2,-depth/2);
glVertex3f(width/2,height/2,-depth/2);
//下
glNormal3f(0.0,-1.0,0.0);
glVertex3f(width/2,-height/2,depth/2);
glVertex3f(-width/2,-height/2,depth/2);
glVertex3f(-width/2,-height/2,-depth/2);
glVertex3f(width/2,-height/2,-depth/2);
glEnd();
}
Cuboid Green,Yellow;
//当り判定
bool Calc_Hit(Cuboid& a,Cuboid& b){
Vector3f Min,Min2;
Vector3f Max,Max2;
Min=a.Pos-a.Radius;
Min2=b.Pos-b.Radius;
Max=a.Pos+a.Radius;
Max2=b.Pos+b.Radius;
if(Min.x<Max2.x && Max.x>Min2.x
&& Min.y<Max2.y && Max.y>Min2.y
&& Min.z<Max2.z && Max.z>Min2.z){
return true;
}else{
return false;
}
}
class GLFONT
{
public:
HFONT Hfont;
HDC Hdc;
GLFONT(wchar_t *fontname, int size);
void DrawStringW(int x,int y,wchar_t *format, ...);
};
//コンストラクタ フォント作成
GLFONT::GLFONT(wchar_t *fontname, int size)
{
Hfont = CreateFontW(
size, //フォント高さ
0, //文字幅
0, //テキストの角度
0, //ベースラインとx軸との角度
FW_REGULAR, //フォントの太さ
FALSE, //イタリック体
FALSE, //アンダーライン
FALSE, //打ち消し線
SHIFTJIS_CHARSET, //文字セット
OUT_DEFAULT_PRECIS, //出力精度
CLIP_DEFAULT_PRECIS, //クリッピング精度
ANTIALIASED_QUALITY, //出力品質
FIXED_PITCH | FF_MODERN, //ピッチとファミリー
fontname); //書体名
Hdc = wglGetCurrentDC();
SelectObject(Hdc, Hfont);
}
//ワイド文字列の描画
void GLFONT::DrawStringW(int x,int y,wchar_t *format, ...)
{
wchar_t buf[256];
va_list ap;
int Length=0;
int list=0;
//ポインタがNULLの場合は終了
if ( format == NULL )
return;
//文字列変換
va_start(ap, format);
vswprintf_s(buf, format, ap);
va_end(ap);
Length = wcslen(buf);
list = glGenLists(Length);
for( int i=0; i<Length; i++ ){
wglUseFontBitmapsW(Hdc, buf[i], 1, list + (DWORD)i);
}
glDisable(GL_LIGHTING);
glRasterPos2i(x, y);
//ディスプレイリストで描画
for( int i=0; i<Length; i++ )
{
glCallList(list + i);
}
glEnable(GL_LIGHTING);
//ディスプレイリスト破棄
glDeleteLists(list, Length);
list = 0;
Length = 0;
}
GLFONT *font;
void Line3D(float x1,float y1,float z1,float x2,float y2,float z2){
//線幅
glLineWidth(1.0);
//線
glBegin(GL_LINES);
glVertex3f(x1,y1,z1);
glVertex3f(x2,y2,z2);
glEnd();
}
void DrawMeasure(int measure,float size){
glDisable(GL_LIGHTING);
glColor4f(0.5f, 0.5f, 0.5f, 0.5f);
for(int
x=0;x<=measure;x++){Line3D(x*size-(size*measure/2),0,-(size*measure/2),x*size-(size*measure/2),0,measure*size-(size*measure/2));}
for(int
y=0;y<=measure;y++){Line3D(-(size*measure/2),0,y*size-(size*measure/2),measure*size-(size*measure/2),0,y*size-(size*measure/2));}
glDisable(GL_DEPTH_TEST);
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
Line3D(0,0,0,(measure/2+2)*size,0,0);
glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
Line3D(0,0,0,0,(measure/2+2)*size,0);
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
Line3D(0,0,0,0,0,(measure/2+2)*size);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
}
void set_world(){
glLoadIdentity();
//視点の設定
gluLookAt(200.0,300.0,500.0, //カメラの座標
0.0,0.0,0.0, // 注視点の座標
0.0,1.0,0.0); // 画面の上方向を指すベクトル
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, WIDTH, HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//視野角,アスペクト比(ウィンドウの幅/高さ),描画する範囲(最も近い距離,最も遠い距離)
gluPerspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 2000.0);
glMatrixMode(GL_MODELVIEW);
set_world();
if(Calc_Hit(Green,Yellow)){
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
font->DrawStringW(-200,110,L"Hit !!");
}else{
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
font->DrawStringW(-200,110,L"No Hit !!");
}
DrawMeasure(16,40);
Yellow.Draw();
set_world();
Green.Draw();
glutSwapBuffers();
}
void timer(int value) {
if(flag){x-=1.0f;}else{x+=1.0f;}
if(x>100.0f)flag=true;
if(x<-100.0f)flag=false;
if(flag2){y-=3.0f;}else{y+=3.0f;}
if(y>100.0f)flag2=true;
if(y<-100.0f)flag2=false;
Green.Pos.x=x;
Yellow.Pos.y=y;
glutTimerFunc(10 , timer , 0);
}
void idle(void)
{
glutPostRedisplay();
}
void Init(){
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glEnable(GL_BLEND);//ブレンドの有効化
font = new GLFONT(L"MS明朝", 24);
Green.Color[0]=0.0f;
Green.Color[1]=1.0f;
Green.Color[2]=0.0f;
Green.Color[3]=0.8f;
Green.Pos.x=0.0f;
Green.Pos.y=0.0f;
Green.Pos.z=0.0f;
Green.Radius.x=50.0f;
Green.Radius.y=30.0f;
Green.Radius.z=20.0f;
Yellow.Color[0]=1.0f;
Yellow.Color[1]=1.0f;
Yellow.Color[2]=0.0f;
Yellow.Color[3]=0.8f;
Yellow.Pos.x=0.0f;
Yellow.Pos.y=50.0f;
Yellow.Pos.z=0.0f;
Yellow.Radius.x=80.0f;
Yellow.Radius.y=50.0f;
Yellow.Radius.z=50.0f;
}
int main(int argc, char *argv[])
{
glutInitWindowPosition(100, 100);
glutInitWindowSize(WIDTH, HEIGHT);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow("AABB");
glutDisplayFunc(display);
glutIdleFunc(idle);
glutTimerFunc(10 , timer , 0);
Init();
glutMainLoop();
return 0;
}
|