OpenGL – C++ Bài 7: Render Các Đối Tượng cơ bản

Hi. Chào mừng các bạn đến với chủ đề Học Lập Trình OpenGL Tại blog: Phát Triển Phần Mềm 123-az

Hôm nay chúng ta cùng nghiên cứu cách vẽ các hình học 3d cơ bản trong opengl

Đó là các đối tượng hình học 3d rất cơ bản trong thế giới thực, với kích thường tùy người sử dụng nhập vào.

Note:

+ Khi dùng cho các dự án hay bài tập dài hay các demo của bạn. Hãy nhớ sử dụng display list để tối ưu hơn.

+Tìm hiểu cách sử dụng display list tại đây =>  Sử dụng display list trong OpengGL.

+ Sample code tôi tạo trong hệ tọa độ thuần của opengl.

Trục Y hướng lên trên, do đó khi các bạn áp dụng vào dự án của mình.

Hãy sử dụng các lệnh glRotate và glTranslate để quay hoặc dịch đối tượng cho phù hợp.

I. Render các hình Cad Cơ bản.
1. Opengl Vẽ một hình lập phương (OpenGL render Cube)

GLuint MakeCube(const float& size)
{
  GLuint dp_list;
  dp_list = glGenLists(1);
  glNewList(dp_list, GL_COMPILE);
  glBegin(GL_QUADS);
  // Front Face
  glNormal3f(0.0, 0.0, 1.0);
  glVertex3f(-size, -size, size);
  glVertex3f( size, -size, size);
  glVertex3f( size, size, size);
  glVertex3f(-size, size, size);
  // Back Face
  glNormal3f(0.0, 0.0, -1.0);
  glVertex3f(-size, -size, -size);
  glVertex3f(-size, size, -size);
  glVertex3f(size, size, -size);
  glVertex3f(size, -size, -size);
  // Top Face
  glNormal3f(0.0, 1.0, 0.0);
  glVertex3f(-size, size, -size);
  glVertex3f(-size, size, size);
  glVertex3f( size, size, size);
  glVertex3f( size, size, -size);
  // Bottom Face
  glNormal3f(0.0, -1.0, 0.0);
  glVertex3f(-size, -size, -size);
  glVertex3f( size, -size, -size);
  glVertex3f( size, -size, size);
  glVertex3f(-size, -size, size);
  // Right face
  glNormal3f(1.0, 0.0, 0.0);
  glVertex3f( size, -size, -size);
  glVertex3f( size, size, -size);
  glVertex3f( size, size, size);
  glVertex3f( size, -size, size);
  // Left Face
  glNormal3f(-1.0, 0.0, 0.0);
  glVertex3f(-size, -size, -size);
  glVertex3f(-size, -size, size);
  glVertex3f(-size, size, size);
  glVertex3f(-size, size, -size);

  glEnd();
  glEndList();
  return dp_list;
}
2. Opengl Vẽ một hình hộp chữ nhật (OpenGL render box)

//Phattrienphanmem123az.com
GLuint MakeBox(const float length, const float width, const float height)
{
  GLuint dp_list;
  dp_list = glGenLists(1);
  glNewList(dp_list, GL_COMPILE);
  float x = length;
  float y = height;
  float z = width ;

  //Back
  glBegin(GL_QUADS);
  glNormal3f(0.0f, 0.0f, -1.0f);
  glVertex3f(0, 0, 0);
  glVertex3f(x, 0, 0);
  glVertex3f(x, y, 0);
  glVertex3f(0, y, 0);
  glEnd();

  // left
  glBegin(GL_QUADS);
  glNormal3f(-1.0f, 0.0f, 0.0f);
  glVertex3f(0, 0, 0);
  glVertex3f(0, 0, z);
  glVertex3f(0, y, z);
  glVertex3f(0, y, 0);
  glEnd();

  //front
  glBegin(GL_QUADS);
  glNormal3f(0.0f, 0.0f, 1.0f);
  glVertex3f(0, 0, z);
  glVertex3f(0, y, z);
  glVertex3f(x, y, z);
  glVertex3f(x, 0, z);
  glEnd();

  //// right
  glBegin(GL_QUADS);
  glNormal3f(1.0f, 0.0f, 0.0f);
  glVertex3f(x, 0, z);
  glVertex3f(x, 0, 0);
  glVertex3f(x, y, 0);
  glVertex3f(x, y, z);
  glEnd();

  //Top
  glBegin(GL_QUADS);
  glNormal3f(0.0f, 1.0f, 0.0f);
  glVertex3f(0, y, 0);
  glVertex3f(x, y, 0);
  glVertex3f(x, y, z);
  glVertex3f(0, y, z);

  //Bottom
  glBegin(GL_QUADS);
  glNormal3f(0.0f, -1.0f, 0.0f);
  glVertex3f(0, 0, 0);
  glVertex3f(x, 0, 0);
  glVertex3f(x, 0, z);
  glVertex3f(0, 0, z);

  glEnd();

  glEndList();

  return dp_list;
}
3.Opengl Vẽ một hình Cầu (Opengl render Sphere)

GLuint MakeSphere(const float& radius)
{
 GLuint dp_list;
 dp_list = glGenLists(1);
 glNewList(dp_list, GL_COMPILE);
 glutSolidSphere(radius, 64, 64);
 glEndList();

 return dp_list;
}
3. OpenGL Vẽ một hình trụ (OpenGL Render Cylinder)

GLuint MakeCylinder(const float& radius, const float& length)
{
 GLuint dp_list;
 dp_list = glGenLists(1); 
 glNewList(dp_list, GL_COMPILE);
 GLUquadricObj *quadratic_obj;
 quadratic_obj = gluNewQuadric();
 glRotatef(-90, 1.0, 0.0, 0.0);
 gluCylinder(quadratic_obj, radius, radius, length, 32, 32);
 glEndList();
 return dp_list;
}

 

4. OpenGL vẽ một hình nón cụt (OpenGL Render Truncated Cone)

GLuint MakeTruncatedCone(const float& base_rad, const float & top_rad, const float& length)
{
 GLuint dp_list;
 dp_list = glGenLists(1);
 glNewList(dp_list, GL_COMPILE);
 GLUquadricObj *quadratic_obj;
 quadratic_obj = gluNewQuadric();
 gluCylinder(quadratic_obj, base_rad, top_rad, length, 32, 32);
 glEndList();

 return dp_list;
}
5. OpenGL Vẽ một hình nón thường (OpenGL Cone)

GLuint MakeCone(const float& base_rad, const float& length)
{
  GLuint dp_list;
  dp_list = glGenLists(1);
  glNewList(dp_list, GL_COMPILE);
  GLUquadricObj *quadratic_obj;
  quadratic_obj = gluNewQuadric();
  gluCylinder(quadratic_obj, base_rad, 0.0, length, 32, 32);
  glEndList();

  return dp_list;
}
6. OpenGL Vẽ mộ hình kim tự tháp – hình chóp đều (OpenGL Render pyramid)

GLuint MakePyramid(const float& size, const float& height)
{
  GLuint dp_list;
  dp_list = glGenLists(1);
  glNewList(dp_list, GL_COMPILE);
  double half_size = size*0.5;
  glBegin( GL_TRIANGLES );
  //Front face
  glNormal3f(0.0, 0.0, 1.0f);
  glVertex3f(0.0f, height, 0.0f);
  glVertex3f(-half_size, 0, half_size);
  glVertex3f(half_size, 0, half_size);

  //left face
  glNormal3f(-1.0, 0.0, 0.0f);
  glVertex3f(0.0, height, 0.0);
  glVertex3f(-half_size, 0.0, -half_size);
  glVertex3f(-half_size, 0.0, half_size);

  //back face
  glNormal3f(0.0, 0.0, -1.0f);
  glVertex3f(0.0f, height, 0.0f);
  glVertex3f(-half_size, 0, -half_size);
  glVertex3f(half_size, 0, -half_size);

  //Right face
  glNormal3f(1.0, 0.0, 0.0f);
  glVertex3f(0.0, height, 0.0);
  glVertex3f(half_size, 0.0, -half_size);
  glVertex3f(half_size, 0.0, half_size);
  glEnd();

  //Bottom face
  glBegin(GL_QUADS);
  glNormal3f(0.0, -1.0, 0.0f);
  glVertex3f(half_size, 0.0, half_size);
  glVertex3f(half_size, 0.0, -half_size);
  glVertex3f(-half_size, 0.0, -half_size);
  glVertex3f(-half_size, 0.0, half_size);
  glEnd();
  glEndList();

  return dp_list;
}
7. OpenGL Vẽ một hình chóp cụt (OpenGL Render Frustum Shape).

GLuint MakeFrustumShape(const float& bottom_size, const float& top_size, const float& height)
{
 GLuint dp_list;
 dp_list = glGenLists(1);
 glNewList(dp_list, GL_COMPILE);
 double half_bottom_size = 0.5*bottom_size;
 double half_top_size = 0.5*top_size;

 glBegin(GL_QUADS);
 // Front Face
 glNormal3f(0.0, 0.0, 1.0);
 glVertex3f(-half_bottom_size, 0.0, half_bottom_size);
 glVertex3f(half_bottom_size, 0.0, half_bottom_size);
 glVertex3f(half_top_size, height, half_top_size);
 glVertex3f(-half_top_size, height, half_top_size);
 // Back Face
 glNormal3f(0.0, 0.0, -1.0);
 glVertex3f(-half_bottom_size, 0.0, -half_bottom_size);
 glVertex3f(half_bottom_size, 0.0, -half_bottom_size);
 glVertex3f(half_top_size, height, -half_top_size);
 glVertex3f(-half_top_size, height, -half_top_size);

 // Top Face
 glNormal3f(0.0, 1.0, 0.0);
 glVertex3f(-half_top_size, height, -half_top_size);
 glVertex3f(-half_top_size, height, half_top_size);
 glVertex3f(half_top_size, height, half_top_size);
 glVertex3f(half_top_size, height, -half_top_size);
 // Bottom Face
 glNormal3f(0.0, -1.0, 0.0);
 glVertex3f(-half_bottom_size, 0.0, -half_bottom_size);
 glVertex3f( half_bottom_size, 0.0, -half_bottom_size);
 glVertex3f( half_bottom_size, 0.0, half_bottom_size);
 glVertex3f(-half_bottom_size, 0.0, half_bottom_size);
 // Right face
 glNormal3f(1.0, 0.0, 0.0);
 glVertex3f(half_bottom_size, 0.0, -half_bottom_size);
 glVertex3f(half_bottom_size, 0.0, half_bottom_size);
 glVertex3f(half_top_size, height, half_top_size);
 glVertex3f(half_top_size, height, -half_top_size);
 // Left Face
 glNormal3f(-1.0, 0.0, 0.0);
 glVertex3f(-half_bottom_size, 0.0, -half_bottom_size);
 glVertex3f(-half_bottom_size, 0.0, half_bottom_size);
 glVertex3f(-half_top_size, height, half_top_size);
 glVertex3f(-half_top_size, height, -half_top_size);
 glEnd();

 glEndList();

 return dp_list;
}
8. Opengl Vẽ mộ hình Bát diện đều (OpenGL Render Octagon)

Bát diện đều có 8 mặt bên và 2 mặt đáy là hình bát giác đều

Tính chất của bát giác đều:

+ Tổng các góc là 1080 độ.

+ Góc giữa hai cạnh là 135 độ.

+ 8 cạnh bằng nhau.

//phattrienphanmem123az.com
GLuint MakeOctagon(const float& side, const float& thickness)
{
  GLuint dp_list;
  dp_list = glGenLists(1);
  glNewList(dp_list, GL_COMPILE);
  double anpha = P_PI/4.0;
  float x = sin(anpha) * side;
  float y = 0.5*side;

  float z = thickness;
  float center_to_mid_size = x + y;
  for (int j = 0; j < 8; j++)
  {
    glPushMatrix();
    glTranslatef(-center_to_mid_size, 0.0, 0.0);
    //Draw 8 rectangle side
    glBegin(GL_QUADS);
    glNormal3f(-1.0, 0.0, 0.0);
    glVertex3f(0.0, -y, z);
    glVertex3f(0.0, y, z);
    glVertex3f(0.0, y, 0);
    glVertex3f(0.0, -y, 0);
    glEnd();
    glPopMatrix();

    glBegin(GL_TRIANGLES);
    glNormal3f(0.0, 0.0, 1.0);
    glVertex3f(0.0, 0.0, z);
    glVertex3f(-center_to_mid_size, -y, z);
    glVertex3f(-center_to_mid_size, y, z);

    glNormal3f(0.0, 0.0, -1.0);
    glVertex3f(0.0, 0.0, 0.0);
    glVertex3f(-center_to_mid_size, y, 0.0);
    glVertex3f(-center_to_mid_size, -y, 0.0);
    glEnd();

    glRotatef(45.0, 0.0, 0.0, 1.0);
   }

   glEndList();

   return dp_list;
}
II. Thiết Lập Màu sắc khác nhau trong chế độ lighting cho từng đối tượng.

Trong bài lighting các bạn đã biết cách tọa chiếu sáng và chế độ material để thiết lập màu sắc cho đối tượng khi chiếu sáng.

Nhưng khi chúng ta thiết lập một chế độ vật liệu chung trong hàm Init thì các đối tượng đều có chung nhau một màu sắc vật liệu.

Như vậy câu hỏi đặt ra rằng, Nếu tối muốn tạo màu sắc chiếu sáng riêng cho từng loại đối tượng thì tôi làm thế nào.

Ví dụ tôi muốn cube màu đỏ, cylinder màu vàng, pyramid màu xanh thì làm sao thực hiện được.

Ok. Hãy thực hiện với các bước sau.

1. Định nghĩa ra các màu cơ bản mà bạn muốn như dưới đây.

#define K_MAT_RED            0
#define K_MAT_GREEN       1
#define K_MAT_BLUE          2
#define K_MAT_YELLOW    3
#define K_MAT_PINK          4

2. Viết hai hàm set material như sau:

//Phattrienphanmem123az.com

void SetMaterialColor(GLfloat ambient[4], GLfloat diff_use[4])
{
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff_use);
}

void SetMaterialColor(const int& type)
{
  GLfloat ambien[] = {0.0, 0.0, 0.0, 1.0};
  GLfloat diff_use[] = {0.0, 0.0, 0.0, 1.0};
  switch(type)
  {
    case K_MAT_RED:
    {
      ambien[0] = 1.0f;
      diff_use[0] = 1.0f;
    }
    break;
    case K_MAT_GREEN:
    {
      ambien[1] = 1.0f;
      diff_use[1] = 1.0f;
    }
    break;
    case K_MAT_BLUE:
    {
      ambien[2] = 1.0f;
      diff_use[2] = 1.0f;
    }
    break;
    case K_MAT_YELLOW:
    {
      ambien[0] = 1.0f;
      ambien[1] = 1.0f;
      diff_use[0] = 1.0f;
      diff_use[1] = 1.0f;
     }
     break;
     case K_MAT_PINK:
     {
       ambien[0] = 1.0f;
       ambien[2] = 1.0f;
       diff_use[0] = 1.0f;
       diff_use[1] = 1.0f;
     }
     break;
   default:
   {
     ambien[0] = 1.0f;
     ambien[1] = 1.0f;
     ambien[2] = 1.0f;
     diff_use[0] = 1.0f;
     diff_use[1] = 1.0f;
     diff_use[2] = 1.0f;
   }
   break;
 }

  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambien);
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff_use);
}

Function SetMaterialColor được định nghĩa hai lần với hai kiểu đối số truyền vào.

1 là dành cho các màu cơ bản có thể gọi tên.

2 là dành cho màu bất kỳ mà các bạn sẽ giá trị.

3. Trong hàm renderscene khi tạo dựng đối tượng => Gọi hàm và truyền màu sắc mong muốn.

glPushMatrix();
DrawCoordinate();
SetMaterialColor(K_MAT_RED);
glCallList(g_box);
glPopMatrix();

glPushMatrix();
glTranslatef(3.0, 0.0, 0.0);
SetMaterialColor(K_MAT_YELLOW);
glCallList(g_sphere);
glPopMatrix();

glPushMatrix();
glTranslatef(-3.0, 0.0, 0.0);
SetMaterialColor(K_MAT_BLUE);
glCallList(g_cylinder);
glPopMatrix();

glPushMatrix();
glTranslatef(0.0, 0.0, -3.0);
GLfloat ambien[] = {0.5, 0.3, 0.7, 1.0};
GLfloat diff_use[] = {0.5, 0.2, 0.4, 1.0};
SetMaterialColor(ambien, diff_use);
glCallList(g_pyramid);
glPopMatrix();

Chúng ta có kết quả như sau:

Ok. Trên đây là cơ bản cách render các hình học 3d trong openGL.

Link download sourcode:   Click here

Từ những hình học cơ bản này, chúng ta có thể lắp ghép và tạo dựng các đối tượng phức tạp hơn.

 

9 thoughts on “OpenGL – C++ Bài 7: Render Các Đối Tượng cơ bản

    • 15 November, 2021 at 7:47 am
      Permalink

      hình như anh gửi rồi đúng ko nhỉ

      Reply
    • 22 December, 2021 at 9:49 am
      Permalink

      anh để link download trên bài viết rồi nhé, kéo xuống dưới cùng nhé

      Reply
    • 22 December, 2021 at 9:49 am
      Permalink

      anh để link download trên bài viết rồi nhé, kéo xuống dưới cùng nhé

      Reply
  • 21 December, 2021 at 11:37 am
    Permalink

    Cho em xin full code những bài này được không ạ

    Reply
    • 22 December, 2021 at 9:49 am
      Permalink

      anh để link download trên bài viết rồi nhé, kéo xuống dưới cùng nhé

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.