Category Archives: Modern OpenGL

TextureSquare




//—-textureSquare.cpp
// 중간생략…
GLuint SetSquareData()
{
 // Vertice Positions
 squareVertices.push_back(glm::vec3(-0.75f, -0.75f, 0.0f));
 squareVertices.push_back(glm::vec3(0.75f, -0.75f, 0.0f));
 squareVertices.push_back(glm::vec3(0.75f, 0.75f, 0.0f));
 squareVertices.push_back(glm::vec3(-0.75f, 0.75f, 0.0f));
 // Vertices Textures
 squareTextureCoords.push_back(glm::vec2(0.0f, 0.0f));
 squareTextureCoords.push_back(glm::vec2(1.0f, 0.0f));
 squareTextureCoords.push_back(glm::vec2(1.0f, 1.0f));
 squareTextureCoords.push_back(glm::vec2(0.0f, 1.0f));

 // Vertice Indices
 squareIndices.push_back(0);
 squareIndices.push_back(1);
 squareIndices.push_back(2);
 squareIndices.push_back(0);
 squareIndices.push_back(2);
 squareIndices.push_back(3);


 // VAO
 GLuint vao;
 glGenVertexArrays(1, &vao);
 glBindVertexArray(vao);


 // VBO
 GLuint vbo[2];
 glGenBuffers(2, &vbo[0]);
 glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
 glBufferData(GL_ARRAY_BUFFER, 4*sizeof(glm::vec3), &squareVertices[0], GL_STATIC_DRAW);
 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
 glEnableVertexAttribArray(0);
 glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
 glBufferData(GL_ARRAY_BUFFER, 4*sizeof(glm::vec2), &squareTextureCoords[0], GL_STATIC_DRAW);
 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
 glEnableVertexAttribArray(1);


 // IBO
 GLuint ibo;
 glGenBuffers(1, &ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6*sizeof(int), &squareIndices[0], GL_STATIC_DRAW);


 squareVertices.clear();
 squareTextureCoords.clear();


 return vao;
}




//————-TransformVertexShader.vert
#version 330


// Input vertex data
layout (location = 0) in vec3 vPosition; // vertex position (in model space)
layout (location = 1) in vec2 vTexCoord; // texture coordinate (in model space)


// Output data will be interpolated for each fragment.
out vec2 TexCoordPass;


// Values that stay constant for the whole mesh.
uniform mat4 gMVP;


void main()
{
 // Output position of the vertex, in clip space : gMVP * position
 gl_Position =  gMVP * vec4(vPosition,1);


 TexCoordPass = vTexCoord;
}




//———-TextureFragmentShader.frag
#version 330


// Interpolated values from the vertex shaders
in vec2 TexCoordPass;


// Ouput data
out vec4 Color;


// Values that stay constant for the whole mesh.
uniform sampler2D gTextureSampler;


void main()
{
 // Output color = color of the texture at the specified UV
 Color = texture2D(gTextureSampler, TexCoordPass);
}




lighting

사용자 삽입 이미지
Ambient/Diffuse/Specular (From left to right: diffuse; ambient; diffuse + ambient; diffuse+ambient+specular) from lighthouse3d.com


사용자 삽입 이미지Light sources (From left to right: directional; point; and spotlights) from lighthouse3d.com

Camera & View Matrix





camera.cpp camera.h
camera 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

사용자 삽입 이미지
3744046228.cpp
SimpleRobot
사용자 삽입 이미지
6981026919.cpp
SimpleSolar



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


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


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

}


void update()
{
// 중간생략
 car->update((float)deltaTime);
 robot->update((float)deltaTime);
 solar->update((float)deltaTime);
 mobile->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();
}

OpenGL/GLM Transformation

 // MVP matrix
 Projection = glm::perspective(g_fovy, g_aspect, g_zNear, g_zFar);
 View = glm::lookAt(g_eye, g_at, g_up);
 spMain.useProgram();
 spMain.setUniform(“gProjection”, Projection);
 spMain.setUniform(“gView”, View);

 // p’ = M3 * M2 * M1 * p (OpenGL uses Column-Major Order)
 glm::mat4 Tx = glm::translate(glm::mat4(1.0f), glm::vec3(3.0f, 0.0f, 0.0f)); // RHS x+ right
 glm::mat4 Rz = glm::rotate(glm::mat4(1.0f), 45.0f, glm::vec3(0.0f, 0.0f, 1.0f)); // RHS z+ (X->Y rotation)
 glm::mat4 S = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f, 0.7f, 1.0f)); // RHS

 World = glm::mat4(1.0f);
 spMain.setUniform(“gModel”, World);
 cube1->draw();

 
 // p’= R T p (red) => translate, and then rotate
 glm::mat4 RT = Rz * Tx; // Translate X, and then Rotate Z
 World = RT;
 spMain.setUniform(“gModel”, World);
 cube2->draw();

 
 // p’= T R p (green) => rotate, and then translate
 glm::mat4 TR = Tx * Rz; // Rotate Z, and then Translate X
 World = TR;
 spMain.setUniform(“gModel”, World);
 cube3->draw();

 
 // p’= T R S p (blue) => scale, and then rotate, and then translate
 glm::mat4 TRS = Tx * Rz * S; // Scale XY, and then Rotate Z, and then Translate X
 World = TRS;
 spMain.setUniform(“gModel”, World);
 cube4->draw();

사용자 삽입 이미지

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