Category Archives: Modern OpenGL

simage library



COIN3D simage library (http://www.coin3d.org/lib/simage)


  • COIN3D simage가 제공하는 이미지 포멧은 JPEG, PNG, GIF, TIFF, RGB, PIC, TGA, EPS등 다양하다.
  • COIN3D의 simage library를 사용하려면, 프로젝트에 additional library and include directory를 추가해야한다. 프로젝트 폴더 안에 include 와 lib 디렉토리를 생성하고 simage.h 과 simage1d.lib를 복사한다.
  • 그리고, 프로젝트에 simage1.lib 라이브러리를 링크한다.


simage include와 library directory 추가, 라이브러리 링크

Project->Properties(ALT+F7)->Configuration Properties->C/C++->General에
Additional Include Directories에 ./include를 넣는다.

Project->Properties(ALT+F7)->Configuration Properties->C/C++->Preprocessor에 Preprocessor Definitions에 ;SIMAGE_DLL를 추가한다.

Project->Properties(ALT+F7)->Configuration Properties->Linker->General에
Additional Library Directories에 ./lib/debug를 넣는다.

Project->Properties(ALT+F7)->Configuration Properties->Linker->Input에
Additional Dependencies에 simage1.lib을 추가한다.

Camera Movement

7253740286.cppcamera class를 사용하여 x/y/x축 카메라의 위치이동과 x/y/x축 카메라의 방향이동
F1&F2 – x축 카메라 위치이동
F3&F4 – y축 카메라 위치이동
F5&F6 – z축 카메라 위치이동
F7&F8 – x축 카메라 방향이동 (PITCH)
F9&F10 – y축 카메라 방향이동 (YAW)
HOME&END – z축 카메라 방향이동 (ROLL)



// main.cpp ——————————————
Camera camera1(FLY);

void init( void )
{
// 중간생략..
 View = camera1.lookAt(g_eye, g_at, g_up);

}

void display( void )
{

// 중간생략..
 View = camera1.View();

}

void specialkey(int key, int x, int y)
{
 if (key == GLUT_KEY_F1)   // x-movement
        camera1.strafe(0.5);
 else if (key == GLUT_KEY_F2)
        camera1.strafe(-0.5);
 else if (key == GLUT_KEY_F3) // y-movement
        camera1.fly(0.5);
 else if (key == GLUT_KEY_F4)
        camera1.fly(-0.5);
 else if (key == GLUT_KEY_F5) // z-movement
        camera1.walk(0.5);
    else if (key == GLUT_KEY_F6)
        camera1.walk(-0.5);


 else if (key == GLUT_KEY_F7) // yaw (by y-axis)
        camera1.yaw(2.5);
 else if (key == GLUT_KEY_F8)
        camera1.yaw(-2.5);
 else if (key == GLUT_KEY_F9) // pitch (by x-axis)
        camera1.pitch(2.5);
    else if (key == GLUT_KEY_F10)
        camera1.pitch(-2.5);
 else if (key == GLUT_KEY_HOME) // roll (by z-axis)
        camera1.roll(2.5);
    else if (key == GLUT_KEY_END)
        camera1.roll(-2.5);


 else if (key == GLUT_KEY_LEFT) // same as town
        camera1.yaw(2.5);
 else if (key == GLUT_KEY_RIGHT)
        camera1.yaw(-2.5);
 else if (key == GLUT_KEY_UP)
        camera1.walk(0.5);
    else if (key == GLUT_KEY_DOWN)
        camera1.walk(-0.5);


 glutPostRedisplay();
}


http://dis.dankook.ac.kr/lectures/cg12/entry/OpenGL-Camera

Hierarchical Transformation

Hierarchical Transformation

SimpleCar사용자 삽입 이미지


9797097777.cppSimpleRobot사용자 삽입 이미지9161556913.cppSimpleSolar사용자 삽입 이미지1208850020.cpp



//main.cpp ———————————————-
SimpleCar* car;
SimpleSolar* solar;
SimpleRobot* robot;


void init()
{
// 중간생략
 car = new SimpleCar();
 robot = new SimpleRobot();
 solar = new SimpleSolar();
}


void display()
{
// 중간생략
 MVP = Projection * View * World;
 car->draw(&spMain, MVP);
 solar->draw(&spMain, MVP);
 robot->draw(&spMain, MVP);
}


void update()
{
// 중간생략
 car->update((float)deltaTime);
 robot->update((float)deltaTime);
 solar->update((float)deltaTime);


 glutPostRedisplay();
}


void specialkey(int key, int x, int y )
{
 switch (key) 
 {   
 case GLUT_KEY_LEFT:
  robot->setTheta(g_theta-=10.0f);
  break; 
 case GLUT_KEY_RIGHT:   
  robot->setTheta(g_theta+=10.0f);
  break; 
// 중간생략
 }
 glutPostRedisplay();
}

GLM Vector and Matrix Class

void mprint(glm::mat4 Mat)
{
 printf(“\n %f %f %f %f\n %f %f %f %f\n %f %f %f %f\n %f %f %f %f\n\n”,
            Mat[0][0], Mat[1][0], Mat[2][0], Mat[3][0],
         Mat[0][1], Mat[1][1], Mat[2][1], Mat[3][1],
         Mat[0][2], Mat[1][2], Mat[2][2], Mat[3][2],
         Mat[0][3], Mat[1][3], Mat[2][3], Mat[3][3]);
}


float theta(const glm::vec3 &v1,  const glm::vec3 &v2)
{
 float len1 = (float)sqrtf(v1[0]*v1[0] + v1[1]*v1[1] + v1[2]*v1[2]);
 float len2 = (float)sqrtf(v2[0]*v2[0] + v2[1]*v2[1] + v2[2]*v2[2]);
 return (float)acosf(dot(v1, v2)/len1*len2);
}


glm::vec3 computeNormal(glm::vec3& a, glm::vec3& b, glm::vec3& c)
{
 glm::vec3 normal = glm::normalize(glm::cross(c – a, b – a));
 return normal;
}


void vec3Test()
{
    const float v[3] = { 1.0f, 2.0f, 3.0f };
    vec3 a(0.0f, 0.0f, 0.0f), b(1.0f, 2.0f, 3.0f), c(b);
    vec3 d = c;
    vec3 e = c;
 vec3 f = a;
    cout << “a = ” << a[0] << ” ” << a[1] << ” ” << a[2] << endl;
    cout << “b = ” << b[0] << ” ” << b[1] << ” ” << b[2] << endl;
    cout << “c = ” << c[0] << ” ” << c[1] << ” ” << c[2] << endl;
    cout << “d = ” << d[0] << ” ” << d[1] << ” ” << d[2] << endl;
    cout << “e = ” << e[0] << ” ” << e[1] << ” ” << e[2] << endl;
    a[0] = 4;
    a[1] = 5;
    a[2] = 6;
    cout << “after assignments, a (4,5,6) ” << endl;
    cout << “a = ” << a[0] << ” ” << a[1] << ” ” << a[2] << endl;
    cout << “b = ” << b[0] << ” ” << b[1] << ” ” << b[2] << endl;


 cout << “Unary Operation” << endl;
    a += b;
    cout << “a += b  ” << endl;
    cout << “a = ” << a[0] << ” ” << a[1] << ” ” << a[2] << endl;
    a -= b;
    cout << “a -= b  ” << endl;
    cout << “a = ” << a[0] << ” ” << a[1] << ” ” << a[2] << endl;
    a *= 1.5;
    cout << “a *= 1.5  ” << endl;
    cout << “a = ” << a[0] << ” ” << a[1] << ” ” << a[2] << endl;
    a /= 1.5;
    cout << “a /= 1.5  ” << endl;
    cout << “a = ” << a[0] << ” ” << a[1] << ” ” << a[2] << endl;


 cout << “Binary Operation” << endl;
    c = a + b;
    cout << “c = a + b  ->  c ” << endl;
    cout << “c = ” << c[0] << ” ” << c[1] << ” ” << c[2] << endl;
    c = a – b;
    cout << “c = a – b  ->  c ” << endl;
    cout << “c = ” << c[0] << ” ” << c[1] << ” ” << c[2] << endl;


    cout << “a == b” << endl;
    if (a == b)
        cout << ” is true” << endl;
    else
        cout << ” is false” << endl;


    cout << “b == d” << endl;
    if (b == d)
        cout << ” is true” << endl;
    else
        cout << ” is false” << endl;


 // magnitude
 cout << “a = ” << a[0] << ” ” << a[1] << ” ” << a[2] << endl;
    cout << “b = ” << b[0] << ” ” << b[1] << ” ” << b[2] << endl;
    cout << “a magnitude = ” << (float)sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2]) << endl;
    cout << “b magnitude = ” << (float)sqrt(b[0]*b[0] + b[1]*b[1] + b[2]*b[2]) << endl;
 
 // normalize
 c = normalize(a);
 cout << “c = normalize(a) = ” << c[0] << ” ” << c[1] << ” ” << c[2] << endl;
 cout << “c magnitude = ” << (float)sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]) << endl;


 d = normalize(b);
 cout << “d = normalize(b) = ” << d[0] << ” ” << d[1] << ” ” << d[2] << endl;
 cout << “d magnitude = ” << (float)sqrt(d[0]*d[0] + d[1]*d[1] + d[2]*d[2]) << endl;
 
 // dot product, theta, cross product, compute normal
 cout << “dot(a, b) = ” << dot(a, b) << endl;
 cout << “a,b angle = ” << degrees(theta(a, b)) << endl;
 e = cross(a, b);
 cout << “e = cross(a, b) = ” << e[0] << ” ” << e[1] << ” ” << e[2] << endl;
 f = cross(vec3(1.0f, 3.0f, -4.0f), vec3(2.0f, -5.0f, 8.0f));
 cout << “(1, 3, -4) x (2, -5, 8) = ” << f[0] << ” ” << f[1] << ” ” << f[2] << endl;
 glm::vec3 g = computeNormal(glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(1.0f, 1.0f, 0.0f), glm::vec3(1.0f, 2.0f, 3.0f));
 cout << “g = ” << g[0] << ” ” << g[1] << ” ” << g[2] << endl;
}


void mat4Test()
{
 // matrix test
 glm::mat4 A(1.0f, 0.0f, 0.0f, 0.0f, // column1
                0.0f, 2.0f, 0.0f, 0.0f, // column2
          0.0f, 0.0f, 4.0f, 0.0f, // column3
          1.0f, 2.0f, 3.0f, 1.0f); // column4
 cout << “A = ”               << endl;
 mprint(A);


 glm::mat4 B(1.0f, 0.0f, 0.0f, 0.0f, // column1
                0.0f, 1.0f, 0.0f, 0.0f, // column2
          0.0f, 0.0f, 1.0f, 0.0f, // column3
          2.0f, 2.0f, 2.0f, 1.0f); // column4
 cout << “B = ”               << endl;
 mprint(B);


 glm::mat4 C = A * B; // multiplication
 cout << “C = A*B = ”         << endl;
 mprint(C);
 glm::mat4 D = B * A; // multiplication
 cout << “D = B*A = ”         << endl;
 mprint(D);
 glm::mat4 E = glm::inverse(A);  // inverse
 cout << “E = inverse(A) = ”  << endl;
 mprint(E);
 glm::mat4 I = A * E;   // multiplication
 cout << “I = A*E = ”         << endl;
 mprint(I);


 glm::vec4 p = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
 glm::vec4 q = A * p;
 glm::vec4 r = B * p;
 glm::vec4 s = C * p;
 glm::vec4 t = D * p;
 cout << “q = A*p = ”         << endl;
 printf(“(1, 0, 0, 1) => (%f, %f, %f, %f)\n”, q[0], q[1], q[2], q[3]);
 cout << “r = B*p = ”         << endl;
 printf(“(1, 0, 0, 1) => (%f, %f, %f, %f)\n”, r[0], r[1], r[2], r[3]);
 cout << “s = A*B*p = ”         << endl;
 printf(“(1, 0, 0, 1) => (%f, %f, %f, %f)\n”, s[0], s[1], s[2], s[3]);
 cout << “t = B*A*p = ”         << endl;
 printf(“(1, 0, 0, 1) => (%f, %f, %f, %f)\n”, t[0], t[1], t[2], t[3]);


 glm::mat4 Tx, Ty, Tz;
 Tx = glm::translate(glm::mat4(1.0f), glm::vec3(2.0f, 0.0f, 0.0f)); // RHS x+ right
 Ty = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 2.0f, 0.0f)); // RHS y+ up
 Tz = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 2.0f)); // RHS z+ front
 printf(“Tx\n”);
 mprint(Tx);
 
 glm::vec4 Position = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
 glm::vec4 tV = Tx * Position;
 printf(“(1, 0, 0, 1) => (%f, %f, %f, %f)\n”, tV[0], tV[1], tV[2], tV[3]);


 glm::mat4 Rx, Ry, Rz, Ra;
 Rx = glm::rotate(glm::mat4(1.0f), 30.0f, glm::vec3(1.0f, 0.0f, 0.0f));
 Ry = glm::rotate(glm::mat4(1.0f), 60.0f, glm::vec3(0.0f, 1.0f, 0.0f));
 Rz = glm::rotate(glm::mat4(1.0f), 45.0f, glm::vec3(0.0f, 0.0f, 1.0f));
 Ra = glm::rotate(glm::mat4(1.0f), 45.0f, glm::vec3(1.0f, 1.0f, 1.0f));
 printf(“R\n”);
 mprint(Rx);
 mprint(Ry);
 mprint(Rz);
 mprint(Ra);


 glm::vec4 tV1 = Ra * Position;
 printf(“Ra * Position(1, 0, 0, 1) => (%f, %f, %f, %f)\n”, tV1[0], tV1[1], tV1[2], tV1[3]);


 glm::mat4 Sx, Sy, Sz;
 Sx = glm::scale(glm::mat4(1.0f), glm::vec3(2, 1, 1));
 Sy = glm::scale(glm::mat4(1.0f), glm::vec3(1, 2, 1));
 Sz = glm::scale(glm::mat4(1.0f), glm::vec3(1, 1, 2));
 printf(“Sy\n”);
 mprint(Sy);


 glm::vec4 tV2 = Sy * Position;
 printf(“(1, 0, 0, 1) => (%f, %f, %f, %f)\n”, tV2[0], tV2[1], tV2[2], tV2[3]);


 glm::mat4 TR = Tx * Rz; // Rotate Z and then Translate X
 printf(“TR\n”);
 mprint(TR);


 glm::vec4 tV3 = TR * Position;
 printf(“(1, 0, 0, 1) => (%f, %f, %f, %f)\n”, tV3[0], tV3[1], tV3[2], tV3[3]);


 mat4 RT = Rz * Tx; // Translate X and then Rotate Z
 printf(“RT\n”);
 mprint(RT);


 glm::vec4 tV4 = RT * Position;
 printf(“(1, 0, 0, 1) => (%f, %f, %f, %f)\n”, tV4[0], tV4[1], tV4[2], tV4[3]);
}

OpenGL/GLM Transformation (Column-Major Order)

glm::mat4 A(1.0f, 0.0f, 0.0f, 0.0f, // column1
                       0.0f, 2.0f, 0.0f, 0.0f, // column2
                       0.0f, 0.0f, 4.0f, 0.0f, // column3
                      
1.0f, 2.0f, 3.0f, 1.0f); // column4
// A =
// 1 0 0 1
// 0 2 0 2
// 0 0 4 3
// 0 0 0 1


glm::mat4 B(1.0f, 0.0f, 0.0f, 0.0f, // column1
                       0.0f, 1.0f, 0.0f, 0.0f,
// column2
                       0.0f, 0.0f, 1.0f, 0.0f,
// column3
                       2.0f, 2.0f, 2.0f, 1.0f); // column4
// B =
// 1 0 0 2
// 0 1 0 2
// 0 0 1 2
// 0 0 0 1


glm::mat4 C = A*B;
// C = A*B =
// 1 0 0 3
// 0 2 0 6
// 0 0 4 11
// 0 0 0 1


glm::mat4 D = B*A;
// D = B*A =
// 1 0 0 3
// 0 2 0 4
// 0 0 4 5
// 0 0 0 1


glm::mat4 E = glm::inverse(A);  // inverse
// E = inverse(A) =
// 1 0 0 -1
// 0 0.5 0 -1
// 0 0 0.25 -0.75
// 0 0 0 1


glm::mat4 I = A * E;   // I = A * A-1
// I = A*E =
// 1 0 0 0
// 0 1 0 0
// 0 0 1 0
// 0 0 0 1


// p’ = M * p (OpenGL/GLM uses Column-Major Order)
glm::vec4 p = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
// p = (1, 0, 0)


glm::vec4 q = A * p;
// q = A * p = (2, 2, 3)

glm::vec4 r = B * p;
// r = B * p = (3, 2, 2)

glm::vec4 s = C * p;
// s = A * B * p = (4, 6, 11)

glm::vec4 t = D * p;
// t = B * A * p = (4, 4, 5)


glm::mat4 Tx,Ty,Tz;
Tx = glm::translate(glm::mat4(1.0f), glm::vec3(2.0f, 0.0f, 0.0f)); // RHS x+ right
Ty = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 2.0f, 0.0f)); // RHS y+ up
Tz = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 2.0f)); // RHS z+ front
// Tx =
// 1 0 0 2
// 0 1 0 0
// 0 0 1 0
// 0 0 0 1


glm::mat4 Rx,Ry,Rz,Ra;
Rx = glm::rotate(glm::mat4(1.0f), 30.0f, glm::vec3(1.0f, 0.0f, 0.0f)); // RHS x+ (Y->Z rotation) OpenGL uses DEGREE angle
Ry = glm::rotate(glm::mat4(1.0f), 60.0f, glm::vec3(0.0f, 1.0f, 0.0f)); // RHS y+ (Z->X rotation)
Rz = glm::rotate(glm::mat4(1.0f), 45.0f, glm::vec3(0.0f, 0.0f, 1.0f)); // RHS z+ (X->Y rotation)
Ra = glm::rotate(glm::mat4(1.0f), 45.0f, glm::vec3(1.0f, 1.0f, 1.0f)); // RHS (arbitrary axis)
// Rx =
// 1 0 0 0
// 0 0.999958 -0.0091384 0
// 0 0.0091384 0.999958 0
// 0 0 0 1


// Ry =
// 0.999833 0 0.018276 0
// 0 1 0 0
// -0.018276 0 0.999833 0
// 0 0 0 1


// Rz =
// 0.999906 -0.0137074 0 0
// 0.0137074 0.999906 0 0
// 0 0 1 0
// 0 0 0 1


// Ra =
// 0.999937 -0.00788263 0.00794526 0
// 0.00794526 0.999937 -0.00788263 0
// -0.00788263 0.00794526 0.999937 0
// 0 0 0 1


glm::mat4 Sx,Sy,Sz;
Sx = glm::scale(glm::mat4(1.0f), glm::vec3(2, 1, 1)); // RHS
Sy = glm::scale(glm::mat4(1.0f), glm::vec3(1, 2, 1)); // RHS
Sz = glm::scale(glm::mat4(1.0f), glm::vec3(1, 1, 2)); // RHS
// Sy =
// 1 0 0 0
// 0 2 0 0
// 0 0 1 0
// 0 0 0 1


// p’ = M3 * M2 * M1 * p (OpenGL uses Column-Major Order)
glm::mat4 TR = Tx * Rz; // Rotate Z, and then Translate X
glm::mat4 RT = Rz * Tx; // Translate X, and then Rotate Z
glm::mat4 TRS = Tx * Rz * Sy; // Scale Y, and then Rotate Z, and then Translate X
glm::mat4 SRT = Sy * Rz * Tx; // Translate X, and then Rotate Z, and then Scale Y
// Tx*Rz =
// 0.707107 -0.707107 0 2
// 0.707107 0.707107 0 0
// 0 0 1 0
// 0 0 0 1


// Rz*Tx =
// 0.707107 -0.707107 0 1.41421
// 0.707107 0.707107 0 1.41421
// 0 0 1 0
// 0 0 0 1


// Tx*Rz*Sy =
// 0.707107 -1.41421 0 2
// 0.707107 1.41421 0 0
// 0 0 1 0
// 0 0 0 1


// Sy*Rz*Tx =
// 0.707107 -0.707107 0 1.41421
// 1.41421 1.41421 0 2.82843
// 0 0 1 0
// 0 0 0 1