从0开发游戏引擎之在3D空间中渲染出三维几何体

简介: 这个类里面会使用第9章里的三维体数据来调用OpenGL的接口绘制出来对应的形状。几何体绘制类主要是调试使用的,比如想要更直观的看到一个对象身上的碰撞框。绘制的形状非常多,大家直接看代码吧。

文章写得比较丑,主要是想把代码先给贴出来。等后面有空了文章里面的原理再慢慢的讲解。


这个类里面会使用第9章里的三维体数据来调用OpenGL的接口绘制出来对应的形状。几何体绘制类主要是调试使用的,比如想要更直观的看到一个对象身上的碰撞框。绘制的形状非常多,大家直接看代码吧。


Gizmo.h


#pragma once
#define GL_PI 3.1415926
class Gizmo
{
private:
public:
//2D部分
static void Init();
static void drawPoint(Vector2 point, sColor color);//点
static void drawLine(Vector2 originPoint, Vector2 endPoint, sColor color);//线段
static void drawLine(GLLine &line, sColor color);// 用对象设置的线段
static void drawArrowLine(Vector2 originPoint, Vector2 endPoint, sColor color);//箭头线
static void drawArrowLine(GLLine &line, sColor color); //用对象设置的箭头线
static void drawCirle(Vector2 position, float radius, sColor color);//有圆心点和半径的园
static void drawCirle(GLCircle &circle, sColor color);//用对象设置的园
static void drawGLPolygon(GLPolygon &poly, sColor color);// 用对象设置的多段线
static void drawRay(GLRay &ray, sColor color);//画射线
static void drawAABB(GLAABB &aabb, sColor color);//画AABB盒子
static void drawRectangle(Vector2 &centerPoint,float wid,float hei,sColor color);//画矩形盒子
static void drawRect(RECT rect,sColor color);
/3D部分//
static void drawLine3D(Vector3D &originPoint, Vector3D &endPoint, sColor color);//3D线段
static void drawLine3D(GLLine3D &line, sColor color);//3D线段(对象来画)
static void drawArrowLine3D(Vector3D &originPoint, Vector3D &endPoint, sColor color);//3D箭头线
static void drawArrowLine3D(GLLine3D &line, sColor color); //用对象设置3D箭头线
static void drawFrustum(Vector3D vec[], sColor color);
static void drawSphere(GLSphere &sphere, sColor color);//
static void drawAABB3D(GLAABB3D &aabb3D, sColor color);
static void drawAABB3D(float len, float wid, float hei, Vector3D &point,sColor color);
static void drawAABB3D(Vector3D eightPoint[8], sColor color);
static void drawAabbLine(GLAABB3D aabb, sColor color);
static void drawAABB3D(GLAABB3D *Aabb, sColor color);
static void drawRay(GLRay3D &ray,sColor color);
static void drawTrianglePlane(GLTrianglePlane &TrianglePlane,sColor color);
static void drawPoint(Vector3D &point, sColor color);
  Gizmo();
  ~Gizmo();
};


Gizmo.cpp


#include "Engine.h"
static GLUquadricObj *Quadratic;  // 二次几何体
Gizmo::Gizmo()
{
}
void Gizmo::Init()
{
  Quadratic= gluNewQuadric();
  gluQuadricNormals(Quadratic, GLU_SMOOTH); // 使用平滑法线
  gluQuadricTexture(Quadratic, GL_TRUE);    // 使用纹理
}
void Gizmo::drawPoint(Vector2 point, sColor color)
{
  glPushMatrix();
  glPointSize(6.0f);
  glColor3fv(color.color);
  glBegin(GL_POINTS);
  glVertex2f(point.x, point.y);
  glEnd();
  glPopMatrix();
}
void Gizmo::drawLine(Vector2 originPoint, Vector2 endPoint, sColor color)
{
  glPushMatrix();
  glLineWidth(2.0f);
  glColor3fv(color.color);
  glBegin(GL_LINES);
  glVertex2f(originPoint.x, originPoint.y);
  glVertex2f(endPoint.x, endPoint.y);
  glEnd();
  glPopMatrix();
}
void Gizmo::drawLine(GLLine &line, sColor color)
{
  glPushMatrix();
  glLineWidth(2.0f);
  glColor3fv(color.color);
  glBegin(GL_LINES);
  glVertex2f(line.m_vcOrig.x, line.m_vcOrig.y);
  glVertex2f(line.m_vcOrig.x + line.m_vcDir.x*line.m_len,
    line.m_vcOrig.y + line.m_vcDir.y*line.m_len);
  glEnd();
  glPopMatrix();
}
void Gizmo::drawArrowLine(Vector2 originPoint, Vector2 endPoint, sColor color)
{
    Vector2 ds = endPoint - originPoint;
    float da = 0;
    if (ds.x == 0)
    {
      if (ds.y < 0)  da = GL_PI /2;
      else if (ds.y > 0)  da = GL_PI / 2 * 3;
      else   da = 0;
    }
    else if (ds.x > 0)
    {
      if (ds.y <= 0)
        da = -atan(ds.y / ds.x);
      else
        da = GL_PI * 2 - atan(ds.y / ds.x);
    }
    else
    {
      da = GL_PI - atan(ds.y / ds.x);
    }
    float upAng = da + GL_PI - GL_PI/180 * 30;
    float downAng = da + GL_PI + GL_PI/180 * 30;
    glPushMatrix();
    glLineWidth(2.0f);
    glColor3fv(color.color);
    glBegin(GL_LINES);
    glVertex2f(originPoint.x, originPoint.y);
    glVertex2f(endPoint.x, endPoint.y);
    glEnd();
    glBegin(GL_LINES);
    glVertex2f(endPoint.x, endPoint.y);
    glVertex2f(endPoint.x + cos(upAng) * 15, endPoint.y - sin(upAng) * 15);
    glEnd();
    glBegin(GL_LINES);
    glVertex2f(endPoint.x, endPoint.y);
    glVertex2f(endPoint.x + cos(downAng) * 15, endPoint.y - sin(downAng) * 15);
    glEnd();
    glPopMatrix();
}
void Gizmo::drawArrowLine(GLLine &line, sColor color)
{
Vector2 endPoint;
endPoint.x = line.m_vcOrig.x + line.m_vcDir.x*line.m_len;
endPoint.y = line.m_vcOrig.y + line.m_vcDir.y*line.m_len;
Vector2 originPoint;
originPoint.x = line.m_vcOrig.x;
originPoint.y = line.m_vcOrig.y;
Vector2 ds = endPoint - originPoint;
float da = 0;
if (ds.x == 0)
{
  if (ds.y < 0)
    da = GL_PI / 2;
  else if (ds.y > 0)
    da = GL_PI / 2 * 3;
  else
    da = 0;
}
else if (ds.x > 0)
{
  if (ds.y <= 0)
    da = -atan(ds.y / ds.x);
  else
    da = GL_PI * 2 - atan(ds.y / ds.x);
}
else
{
  da = GL_PI - atan(ds.y / ds.x);
}
float upAng = da + GL_PI - GL_PI / 180 * 30;
float downAng = da + GL_PI + GL_PI / 180 * 30;
glPushMatrix();
glLineWidth(2.0f);
glColor3fv(color.color);
glBegin(GL_LINES);
glVertex2f(originPoint.x, originPoint.y);
glVertex2f(endPoint.x, endPoint.y);
glEnd();
glBegin(GL_LINES);
glVertex2f(endPoint.x, endPoint.y);
glVertex2f(endPoint.x + cos(upAng) * 15, endPoint.y - sin(upAng) * 15);
glEnd();
glBegin(GL_LINES);
glVertex2f(endPoint.x, endPoint.y);
glVertex2f(endPoint.x + cos(downAng) * 15, endPoint.y - sin(downAng) * 15);
glEnd();
glPopMatrix();
}
void Gizmo::drawCirle(Vector2 position, float radius, sColor color)
{
  glPushMatrix();
  glLineWidth(2.0);
  glColor3fv(color.color);
  int angle = 360 / 5;
  for (int i = 0; i < angle;i++)
  {
    glBegin(GL_LINES);
    glVertex2f(position.x+radius*sin(i*5*GL_PI/180),position.y+radius*cos(i*5*GL_PI / 180));
    glVertex2f(position.x+radius*sin((i+1)%angle*5*GL_PI /180),position.y+radius*cos((i+1)%angle*5*GL_PI/180));
    glEnd();
  }
  glPopMatrix();
}
void Gizmo::drawCirle(GLCircle &circle, sColor color)
{
  drawCirle(circle.center, circle.radius, color);
}
void Gizmo::drawGLPolygon(GLPolygon &poly, sColor color)
{
  glPushMatrix();
  glLineWidth(2.0);
  glColor3fv(color.color);
  for (int i = 0;i < poly.m_lineNum;i++)
  {
    drawLine(poly.m_line[i], color);
  }
  glPopMatrix();
}
void Gizmo::drawRay(GLRay &ray, sColor color)
{
  glPushMatrix();
  glLineWidth(2.0);
  glColor3fv(color.color);
  glBegin(GL_LINES);
  glVertex2f(ray.m_vcOrig.x, ray.m_vcOrig.y);
  glVertex2f(ray.m_vcOrig.x + ray.m_vcDir.x * 10000,
    ray.m_vcOrig.y + ray.m_vcDir.y * 10000);
  glEnd();
  glPopMatrix();
}
void Gizmo::drawAABB(GLAABB &aabb, sColor color)
{
  glPushMatrix();
  glColor3fv(color.color);
  glBegin(GL_LINE_LOOP);
  glVertex2f(aabb.m_vcMin.x, aabb.m_vcMin.y);
  glVertex2f(aabb.m_vcMin.x, aabb.m_vcMax.y);
  glVertex2f(aabb.m_vcMax.x,aabb.m_vcMax.y);
  glVertex2f(aabb.m_vcMax.x, aabb.m_vcMin.y);
  glEnd();
  glPopMatrix();
}
void Gizmo::drawRectangle(Vector2 &centerPoint, float wid, float hei, sColor color)//画矩形盒子
{
  Vector2 halfWH;
  halfWH.x = wid*0.5;
  halfWH.y = hei*0.5;
  glPushMatrix();
  glColor3fv(color.color);
  glBegin(GL_TRIANGLE_STRIP);
  glVertex2f(centerPoint.x- halfWH.x, centerPoint.y-halfWH.y);
  glVertex2f(centerPoint.x - halfWH.x, centerPoint.y+halfWH.y);
  glVertex2f(centerPoint.x + halfWH.x, centerPoint.y-halfWH.y);
  glVertex2f(centerPoint.x + halfWH.x, centerPoint.y+halfWH.y);
  glEnd();
  glPopMatrix();
}
void Gizmo::drawRect(RECT rect, sColor color)
{
  glPushMatrix();
  glColor3fv(color.color);
  glBegin(GL_LINE_LOOP);
  glVertex2f(rect.left, rect.top);
  glVertex2f(rect.left, rect.bottom);
  glVertex2f(rect.right, rect.bottom);
  glVertex2f(rect.right, rect.top);
  glEnd();
  glPopMatrix();
}
void Gizmo::drawLine3D(Vector3D &originPoint, Vector3D &endPoint, sColor color)
{
  glPushMatrix();
  glLineWidth(5.0f);
  glColor4fv(color.color);
  glBegin(GL_LINES);
  glVertex3f(originPoint.x, originPoint.y, originPoint.z);
  glVertex3f(endPoint.x, endPoint.y, endPoint.z);
  glEnd();
  glColor4f(1, 1, 1, 1);
  glPopMatrix();
}
void Gizmo::drawLine3D(GLLine3D &line, sColor color)
{
  glPushMatrix();
  glLineWidth(2.0f);
  glColor4fv(color.color);
  glBegin(GL_LINES);
  glVertex3f(line.m_vcOrig.x, line.m_vcOrig.y, line.m_vcOrig.z);
  glVertex3f(line.m_vcOrig.x + line.m_vcDir.x*line.m_len,
    line.m_vcOrig.y + line.m_vcDir.y*line.m_len,
    line.m_vcOrig.z + line.m_vcDir.z*line.m_len);
  glEnd();
  glPopMatrix();
}
void Gizmo::drawArrowLine3D(GLLine3D &line, sColor color)
{
  static GLUquadricObj *quadratic = NULL;
  if (quadratic == NULL)
  {
    quadratic = gluNewQuadric();
  }
  glPushMatrix();
  glLineWidth(4.0f);
  glColor3fv(color.color);
  glBegin(GL_LINES);
  glVertex3f(line.m_vcOrig.x, line.m_vcOrig.y, line.m_vcOrig.z);
  glVertex3f(line.m_vcOrig.x+line.m_vcDir.x*line.m_len, line.m_vcOrig.y+line.m_vcDir.y*line.m_len, line.m_vcOrig.z+line.m_vcDir.z*line.m_len);
  glEnd();
  glTranslatef(line.m_vcDir.x*line.m_len, line.m_vcDir.y*line.m_len, line.m_vcDir.z*line.m_len);
  Matrix3D rotMat = FromToRotation(Vector3D(0, 0, -1), line.m_vcDir*line.m_len - line.m_vcOrig);
  glMultMatrixf(rotMat.mat);
  glTranslatef(0, 0, -0.3f);
  glDisable(GL_TEXTURE_2D);
  glDisable(GL_BLEND);
  //glDisable(GL_LIGHTING);
  glColor4fv(color.color);
  gluCylinder(quadratic, 1.5f, 0.0f, 3.0f, 32, 32);
  glPopMatrix();
}
void Gizmo::drawArrowLine3D(Vector3D &originPoint, Vector3D &endPoint, sColor color)
{
  static GLUquadricObj *quadratic = NULL;
  if (quadratic == NULL)
  {
    quadratic = gluNewQuadric();        // 创建二次几何体
    gluQuadricNormals(quadratic, GLU_SMOOTH);   // 使用平滑法线
  }
  glPushMatrix();
  glLineWidth(4.0f);
  //glEnable(GL_LINE_SMOOTH);
  glColor3fv(color.color);
  glBegin(GL_LINES);
  glVertex3f(originPoint.x, originPoint.y, originPoint.z);
  glVertex3f(endPoint.x, endPoint.y, endPoint.z);
  glEnd();
  glTranslatef(endPoint.x, endPoint.y, endPoint.z);
  Matrix3D rotMat = FromToRotation(Vector3D(0, 0, 1), endPoint - originPoint);
  glMultMatrixf(rotMat.mat);
  glTranslatef(0, 0, -0.3f);
  gluCylinder(quadratic, 2.0f, 0.0f, 0.3f, 32, 32);
  glColor3f(1, 1, 1);
  glLineWidth(2.0f);
  glPopMatrix();
}
void Gizmo::drawFrustum(Vector3D vec[], sColor color)
{ 
  //  //远
  //  //4 5
  //  //7 6
  //
  //  //近
  //  //0 1
  //  //3 2
  glPushMatrix();
  glLineWidth(4.0f);
  glColor4fv(color.color);
  glDisable(GL_CULL_FACE);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_COLOR, GL_DST_COLOR);
  //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  glBegin(GL_QUADS);//近
  glVertex3f(vec[0].x,vec[0].y,vec[0].z);
  glVertex3f(vec[3].x, vec[3].y,vec[3].z);
  glVertex3f(vec[2].x, vec[2].y, vec[2].z);
  glVertex3f(vec[1].x, vec[1].y, vec[1].z);
  glEnd();
  glBegin(GL_QUADS);//远
  glVertex3f(vec[4].x, vec[4].y, vec[4].z);
  glVertex3f(vec[7].x, vec[7].y, vec[7].z);
  glVertex3f(vec[6].x, vec[6].y, vec[6].z);
  glVertex3f(vec[5].x, vec[5].y, vec[5].z);
  glEnd();
  glBegin(GL_QUADS);//左侧
  glVertex3f(vec[4].x, vec[4].y, vec[4].z);
  glVertex3f(vec[7].x, vec[7].y, vec[7].z);
  glVertex3f(vec[3].x, vec[3].y, vec[3].z);
  glVertex3f(vec[0].x, vec[0].y, vec[0].z);
  glEnd();
  glBegin(GL_QUADS);//右侧
  glVertex3f(vec[6].x, vec[6].y, vec[6].z);
  glVertex3f(vec[5].x, vec[5].y, vec[5].z);
  glVertex3f(vec[1].x, vec[1].y, vec[1].z);
  glVertex3f(vec[2].x, vec[2].y, vec[2].z);
  glEnd();
  glBegin(GL_QUADS);//上侧
  glVertex3f(vec[5].x, vec[5].y, vec[5].z);
  glVertex3f(vec[4].x, vec[4].y, vec[4].z);
  glVertex3f(vec[0].x, vec[0].y, vec[0].z);
  glVertex3f(vec[1].x, vec[1].y, vec[1].z);
  glEnd();
  glBegin(GL_QUADS);//下侧
  glVertex3f(vec[6].x, vec[6].y, vec[6].z);
  glVertex3f(vec[7].x, vec[7].y, vec[7].z);
  glVertex3f(vec[3].x, vec[3].y, vec[3].z);
  glVertex3f(vec[2].x, vec[2].y, vec[2].z);
  glEnd();
  glEnable(GL_CULL_FACE);
  glDisable(GL_BLEND);
  //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  glColor4f(1,0, 0, 1);
  glLineWidth(5.0);
  glBegin(GL_LINE_LOOP);//近
  glVertex3f(vec[0].x, vec[0].y, vec[0].z);
  glVertex3f(vec[3].x, vec[3].y, vec[3].z);
  glVertex3f(vec[2].x, vec[2].y, vec[2].z);
  glVertex3f(vec[1].x, vec[1].y, vec[1].z);
  glEnd();
  glBegin(GL_LINE_LOOP);//近
  glVertex3f(vec[4].x, vec[4].y, vec[4].z);
  glVertex3f(vec[7].x, vec[7].y, vec[7].z);
  glVertex3f(vec[6].x, vec[6].y, vec[6].z);
  glVertex3f(vec[5].x, vec[5].y, vec[5].z);
  glEnd();
  glBegin(GL_LINE_LOOP);//近
  glVertex3f(vec[4].x, vec[4].y, vec[4].z);
  glVertex3f(vec[7].x, vec[7].y, vec[7].z);
  glVertex3f(vec[3].x, vec[3].y, vec[3].z);
  glVertex3f(vec[0].x, vec[0].y, vec[0].z);
  glEnd();
  glBegin(GL_LINE_LOOP);//近
  glVertex3f(vec[6].x, vec[6].y, vec[6].z);
  glVertex3f(vec[5].x, vec[5].y, vec[5].z);
  glVertex3f(vec[1].x, vec[1].y, vec[1].z);
  glVertex3f(vec[2].x, vec[2].y, vec[2].z);
  glEnd();
  glBegin(GL_LINE_LOOP);//近
  glVertex3f(vec[5].x, vec[5].y, vec[5].z);
  glVertex3f(vec[4].x, vec[4].y, vec[4].z);
  glVertex3f(vec[0].x, vec[0].y, vec[0].z);
  glVertex3f(vec[1].x, vec[1].y, vec[1].z);
  glEnd();
  glBegin(GL_LINE_LOOP);//近
  glVertex3f(vec[6].x, vec[6].y, vec[6].z);
  glVertex3f(vec[7].x, vec[7].y, vec[7].z);
  glVertex3f(vec[3].x, vec[3].y, vec[3].z);
  glVertex3f(vec[2].x, vec[2].y, vec[2].z);
  glEnd();
  glLineWidth(2.0);
  glColor4f(1, 1, 1, 1);
  glPopMatrix();
}
void Gizmo::drawSphere(GLSphere &sphere, sColor color)
{
  float dtor = PI / 180.0f;
  int dphi = 10; //纬度
  int dtheta = 10; //经度
  glPushMatrix();
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  //glColor4f(1, 0, 0, 0.5);
  glColor4fv(color.color);
  glBegin(GL_LINES);
  for (int phi = 0; phi <= 180 - dphi; phi += dphi)
  {
    for (int theta = 0; theta <= 360 - dtheta; theta += dtheta)
    {
      glVertex3f(sphere.m_radius*sinf(phi*dtor)*cosf(theta*dtor) + sphere.m_center.x,
        sphere.m_radius*cosf(phi*dtor) + sphere.m_center.y,
        sphere.m_radius*sinf(phi*dtor)*sinf(theta*dtor) + sphere.m_center.z);
      glVertex3f(sphere.m_radius*sinf((phi + dphi)*dtor)*cosf(theta*dtor) + sphere.m_center.x,
        sphere.m_radius*cosf((phi + dphi)*dtor) + sphere.m_center.y,
        sphere.m_radius*sinf((phi + dphi)*dtor)*sinf(theta*dtor) + sphere.m_center.z);
      glVertex3f(sphere.m_radius*sinf(phi*dtor)*cosf((theta - dtheta)*dtor) + sphere.m_center.x,
        sphere.m_radius*cosf(phi*dtor) + sphere.m_center.y,
        sphere.m_radius*sinf(phi*dtor)*sinf((theta - dtheta)*dtor) + sphere.m_center.z);
      if (phi >-180 && phi < 180)
      {
        glVertex3f(sphere.m_radius*sinf((phi + dphi)*dtor)*cosf((theta - dtheta)*dtor) + sphere.m_center.x,
          sphere.m_radius*cosf((phi + dphi)*dtor) + sphere.m_center.y,
          sphere.m_radius*sinf((phi + dphi)*dtor)*sinf((theta - dtheta)*dtor) + sphere.m_center.z);
      }
    }
  }
  glEnd();
  glPopMatrix();
下面两个是画经纬度的圆环的///
  glLineWidth(2.0f);
  glColor3fv(sColor(1, 1, 1, 1).color);
  glPushMatrix();
  glBegin(GL_LINE_LOOP);
  for (int theta = 0; theta <= 360; theta += dtheta)
  {
    glVertex3f(sphere.m_radius*cosf(theta*dtor) + sphere.m_center.x,
      sphere.m_center.y,
      sphere.m_radius*sinf(theta*dtor) + sphere.m_center.z);
  }
  glEnd();
  glPopMatrix();
///
  glPushMatrix();
  glBegin(GL_LINE_LOOP);
  for (int phi = 0; phi <= 360; phi += dtheta)
  {
    glVertex3f(sphere.m_center.x,
      sphere.m_radius*sinf(phi*dtor) + sphere.m_center.y,
      sphere.m_radius*cosf(phi*dtor) + sphere.m_center.z);
  }
  glEnd();
  glDisable(GL_BLEND);
  glPopMatrix();
}
后面
7 6
4 5
前面
3 2
0 1
LEN:X WID:Z HEI:Y
//float halfLen = len / 2;
//float halfWid = wid / 2;
//float halfHei = hei / 2;
//
前面
//cornerPoint[0] = { pos.x - halfLen,pos.y - halfHei,pos.z + halfWid };
//cornerPoint[1] = { pos.x + halfLen,pos.y - halfHei,pos.z + halfWid };
//cornerPoint[2] = { pos.x + halfLen,pos.y + halfHei,pos.z + halfWid };
//cornerPoint[3] = { pos.x - halfLen,pos.y + halfHei,pos.z + halfWid };
//
后面
//cornerPoint[4] = { pos.x - halfLen,pos.y - halfHei,pos.z - halfWid };
//cornerPoint[5] = { pos.x + halfLen,pos.y - halfHei,pos.z - halfWid };
//cornerPoint[6] = { pos.x + halfLen,pos.y + halfHei,pos.z - halfWid };
//cornerPoint[7] = { pos.x - halfLen,pos.y + halfHei,pos.z - halfWid };
void Gizmo::drawAABB3D(GLAABB3D &aabb3D, sColor color)
{
  后面
  7 6
  4 5
  前面
  3 2
  0 1
  glPushMatrix();
  glColor4fv(color.color);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
  //前
  glBegin(GL_QUADS);
  glVertex3f(aabb3D.m_vcMin.x, aabb3D.m_vcMin.y, aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMax.x, aabb3D.m_vcMin.y, aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMax.x, aabb3D.m_vcMax.y, aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMin.x, aabb3D.m_vcMax.y, aabb3D.m_vcMax.z);
  glEnd();
  //后
  glBegin(GL_QUADS);
  glVertex3f(aabb3D.m_vcMin.x, aabb3D.m_vcMin.y, aabb3D.m_vcMin.z);
  glVertex3f(aabb3D.m_vcMax.x, aabb3D.m_vcMin.y, aabb3D.m_vcMin.z);
  glVertex3f(aabb3D.m_vcMax.x, aabb3D.m_vcMax.y, aabb3D.m_vcMin.z);
  glVertex3f(aabb3D.m_vcMin.x, aabb3D.m_vcMax.y, aabb3D.m_vcMin.z);
  glEnd();
  //左
  glBegin(GL_QUADS);
  glVertex3f(aabb3D.m_vcMin.x, aabb3D.m_vcMin.y, aabb3D.m_vcMin.z);
  glVertex3f(aabb3D.m_vcMin.x, aabb3D.m_vcMin.y, aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMin.x, aabb3D.m_vcMax.y, aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMin.x, aabb3D.m_vcMax.y, aabb3D.m_vcMin.z);
  glEnd();
  //右
  glBegin(GL_QUADS);
  glVertex3f(aabb3D.m_vcMax.x, aabb3D.m_vcMin.y, aabb3D.m_vcMin.z);
  glVertex3f(aabb3D.m_vcMax.x, aabb3D.m_vcMin.y, aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMax.x, aabb3D.m_vcMax.y, aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMax.x, aabb3D.m_vcMax.y, aabb3D.m_vcMin.z);
  glEnd();
  //上
  glBegin(GL_QUADS);
  glVertex3f(aabb3D.m_vcMin.x, aabb3D.m_vcMax.y, aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMax.x, aabb3D.m_vcMax.y, aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMax.x, aabb3D.m_vcMax.y, aabb3D.m_vcMin.z);
  glVertex3f(aabb3D.m_vcMin.x, aabb3D.m_vcMax.y, aabb3D.m_vcMin.z);
  glEnd();
  //下
  glBegin(GL_QUADS);
  glVertex3f(aabb3D.m_vcMin.x, aabb3D.m_vcMin.y, aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMax.x, aabb3D.m_vcMin.y, aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMax.x, aabb3D.m_vcMin.y, aabb3D.m_vcMin.z);
  glVertex3f(aabb3D.m_vcMin.x, aabb3D.m_vcMin.y, aabb3D.m_vcMin.z);
  glEnd();
  glDisable(GL_BLEND);
  glColor3f(1, 1, 1);
  glPopMatrix();
  glPushMatrix();
  glLineWidth(2.0f);
  glColor4fv(color.color);
  glBegin(GL_LINE_LOOP);
  glVertex3f(aabb3D.m_vcMin.x,  aabb3D.m_vcMin.y, aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMax.x,  aabb3D.m_vcMin.y, aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMax.x,  aabb3D.m_vcMax.y, aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMin.x,  aabb3D.m_vcMax.y, aabb3D.m_vcMax.z);
  glEnd();
  glBegin(GL_LINE_LOOP);
  glVertex3f(aabb3D.m_vcMin.x,  aabb3D.m_vcMin.y, aabb3D.m_vcMin.z);
  glVertex3f(aabb3D.m_vcMax.x,  aabb3D.m_vcMin.y, aabb3D.m_vcMin.z);
  glVertex3f(aabb3D.m_vcMax.x,  aabb3D.m_vcMax.y, aabb3D.m_vcMin.z);
  glVertex3f(aabb3D.m_vcMin.x,  aabb3D.m_vcMax.y, aabb3D.m_vcMin.z);
  glEnd();
  glBegin(GL_LINE_LOOP);
  glVertex3f(aabb3D.m_vcMin.x, aabb3D.m_vcMin.y, aabb3D.m_vcMin.z);
  glVertex3f(aabb3D.m_vcMin.x, aabb3D.m_vcMin.y,aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMin.x,aabb3D.m_vcMax.y, aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMin.x,aabb3D.m_vcMax.y,aabb3D.m_vcMin.z);
  glEnd();
  glBegin(GL_LINE_LOOP);
  glVertex3f(aabb3D.m_vcMax.x, aabb3D.m_vcMin.y, aabb3D.m_vcMin.z);
  glVertex3f(aabb3D.m_vcMax.x, aabb3D.m_vcMin.y, aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMax.x, aabb3D.m_vcMax.y, aabb3D.m_vcMax.z);
  glVertex3f(aabb3D.m_vcMax.x, aabb3D.m_vcMax.y, aabb3D.m_vcMin.z);
  glEnd();
  glColor3f(1, 1, 1);
  glPopMatrix();
}
void Gizmo::drawAABB3D(float len, float wid, float hei, Vector3D &pos, sColor color)
{
  后面
  7 6
  4 5
  前面
  3 2
  0 1
  LEN:X WID:Z HEI:Y
  float halfLen = len / 2;
  float halfWid = wid / 2;
  float halfHei = hei / 2;
  glPushMatrix();
  glColor4fv(color.color);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  //glBegin(GL_QUADS);
  //glVertex3f(pos.x - halfLen, pos.y - halfHei, pos.z + halfWid);
  //glVertex3f(pos.x + halfLen, pos.y - halfHei, pos.z + halfWid);
  //glVertex3f(pos.x + halfLen, pos.y + halfHei, pos.z + halfWid);
  //glVertex3f(pos.x - halfLen, pos.y + halfHei, pos.z + halfWid);
  //glEnd();
  //glBegin(GL_QUADS);
  //glVertex3f(pos.x - halfLen, pos.y - halfHei, pos.z - halfWid);
  //glVertex3f(pos.x + halfLen, pos.y - halfHei, pos.z - halfWid);
  //glVertex3f(pos.x + halfLen, pos.y + halfHei, pos.z - halfWid);
  //glVertex3f(pos.x - halfLen, pos.y + halfHei, pos.z - halfWid);
  //glEnd();
  //glBegin(GL_QUADS);
  //glVertex3f(pos.x - halfLen, pos.y - halfHei, pos.z - halfWid);
  //glVertex3f(pos.x - halfLen, pos.y - halfHei, pos.z + halfWid);
  //glVertex3f(pos.x - halfLen, pos.y + halfHei, pos.z + halfWid);
  //glVertex3f(pos.x - halfLen, pos.y + halfHei, pos.z - halfWid);
  //glEnd();
  //glBegin(GL_QUADS);
  //glVertex3f(pos.x + halfLen, pos.y - halfHei, pos.z - halfWid);
  //glVertex3f(pos.x + halfLen, pos.y - halfHei, pos.z + halfWid);
  //glVertex3f(pos.x + halfLen, pos.y + halfHei, pos.z + halfWid);
  //glVertex3f(pos.x + halfLen, pos.y + halfHei, pos.z - halfWid);
  //glEnd();
  //glBegin(GL_QUADS);
  //glVertex3f(pos.x - halfLen, pos.y + halfHei, pos.z + halfWid);
  //glVertex3f(pos.x + halfLen, pos.y + halfHei, pos.z + halfWid);
  //glVertex3f(pos.x + halfLen, pos.y + halfHei, pos.z - halfWid);
  //glVertex3f(pos.x - halfLen, pos.y + halfHei, pos.z - halfWid);
  //glEnd();
  //glBegin(GL_QUADS);
  //glVertex3f(pos.x - halfLen, pos.y- halfHei, pos.z + halfWid);
  //glVertex3f(pos.x + halfLen, pos.y- halfHei, pos.z + halfWid);
  //glVertex3f(pos.x + halfLen, pos.y - halfHei, pos.z - halfWid);
  //glVertex3f(pos.x - halfLen, pos.y -halfHei, pos.z - halfWid);
  //glEnd();
  glDisable(GL_BLEND);
  glColor3f(1, 1, 1);
  glPopMatrix();
  glPushMatrix();
  glLineWidth(2.0f);
  glColor4fv(color.color);
  glBegin(GL_LINE_LOOP);
  glVertex3f(pos.x - halfLen, pos.y-halfLen, pos.z + halfWid);
  glVertex3f(pos.x + halfLen, pos.y- halfLen, pos.z + halfWid);
  glVertex3f(pos.x + halfLen, pos.y+ halfLen, pos.z + halfWid);
  glVertex3f(pos.x - halfLen, pos.y + halfLen, pos.z + halfWid);
  glEnd();
  glBegin(GL_LINE_LOOP);
  glVertex3f(pos.x - halfLen, pos.y- halfLen, pos.z - halfWid);
  glVertex3f(pos.x + halfLen, pos.y- halfLen, pos.z - halfWid);
  glVertex3f(pos.x + halfLen, pos.y + halfLen, pos.z - halfWid);
  glVertex3f(pos.x - halfLen, pos.y + halfLen, pos.z - halfWid);
  glEnd();
  glBegin(GL_LINE_LOOP);
  glVertex3f(pos.x - halfLen,pos.y- halfLen,pos.z-halfWid);
  glVertex3f(pos.x - halfLen,pos.y- halfLen,pos.z+halfWid);
  glVertex3f(pos.x - halfLen,pos.y+ halfLen,pos.z+halfWid);
  glVertex3f(pos.x - halfLen,pos.y+ halfLen,pos.z-halfWid);
  glEnd();
  glBegin(GL_LINE_LOOP);
  glVertex3f(pos.x + halfLen, pos.y - halfLen, pos.z - halfWid);
  glVertex3f(pos.x + halfLen, pos.y- halfLen, pos.z + halfWid);
  glVertex3f(pos.x + halfLen, pos.y + halfLen, pos.z + halfWid);
  glVertex3f(pos.x + halfLen, pos.y + halfLen, pos.z - halfWid);
  glEnd();
  glColor3f(1, 1, 1);
  glPopMatrix();
}
void Gizmo::drawAABB3D(Vector3D eightPoint[8], sColor color)
{
  后面
  7 6
  4 5
  前面
  3 2
  0 1
  LEN:X WID:Z HEI:Y
  glPushMatrix();
  glLineWidth(2.0f);
  glColor4fv(color.color);
  //画最大面
  glBegin(GL_LINE_LOOP);
  for (int i = 0;i < 4;++i)
    glVertex3f(eightPoint[i].x, eightPoint[i].y, eightPoint[i].z);
  glEnd();
  //画最小面
  glBegin(GL_LINE_LOOP);
  for (int i =4;i <8;++i)
    glVertex3f(eightPoint[i].x, eightPoint[i].y, eightPoint[i].z);
  glEnd();
  glBegin(GL_LINE_LOOP);
  glVertex3f(eightPoint[4].x, eightPoint[4].y, eightPoint[4].z);
  glVertex3f(eightPoint[0].x, eightPoint[0].y, eightPoint[0].z);
  glVertex3f(eightPoint[3].x, eightPoint[3].y, eightPoint[3].z);
  glVertex3f(eightPoint[7].x, eightPoint[7].y, eightPoint[7].z);
  glEnd();
  glBegin(GL_LINE_LOOP);
  glVertex3f(eightPoint[5].x, eightPoint[5].y, eightPoint[5].z);
  glVertex3f(eightPoint[1].x, eightPoint[1].y, eightPoint[1].z);
  glVertex3f(eightPoint[2].x, eightPoint[2].y, eightPoint[2].z);
  glVertex3f(eightPoint[6].x, eightPoint[6].y, eightPoint[6].z);
  glEnd();
  glColor3f(1, 1, 1);
  glPopMatrix();
}
void Gizmo::drawAABB3D(GLAABB3D *Aabb, sColor color)
{
  Vector3D point[8];
  float length = Aabb->m_vcMax.z - Aabb->m_vcMin.z;
  float width = Aabb->m_vcMax.x - Aabb->m_vcMin.x;
  float heigth = Aabb->m_vcMax.y - Aabb->m_vcMin.y;
  point[0] = Aabb->m_vcMax - Vector3D(width, 0, 0);
  point[1] = Aabb->m_vcMax;
  point[2] = Aabb->m_vcMax - Vector3D(0, heigth, 0);
  point[3] = Aabb->m_vcMax - Vector3D(width, heigth, 0);
  point[4] = Aabb->m_vcMin + Vector3D(0, heigth, 0);
  point[5] = Aabb->m_vcMin + Vector3D(width, heigth, 0);
  point[6] = Aabb->m_vcMin + Vector3D(width, 0, 0);
  point[7] = Aabb->m_vcMin;
  glPushMatrix();
  glColor4fv(color.color);
  glFrontFace(GL_CW);//设置顺时针方向为正面
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);
  //前
  glBegin(GL_QUADS);
  glVertex3f(point[0].x, point[0].y, point[0].z);
  glVertex3f(point[1].x, point[1].y, point[1].z);
  glVertex3f(point[2].x, point[2].y, point[2].z);
  glVertex3f(point[3].x, point[3].y, point[3].z);
  //后
  glVertex3f(point[4].x, point[4].y, point[4].z);
  glVertex3f(point[5].x, point[5].y, point[5].z);
  glVertex3f(point[6].x, point[6].y, point[6].z);
  glVertex3f(point[7].x, point[7].y, point[7].z);
  //上
  glVertex3f(point[4].x, point[4].y, point[4].z);
  glVertex3f(point[5].x, point[5].y, point[5].z);
  glVertex3f(point[1].x, point[1].y, point[1].z);
  glVertex3f(point[0].x, point[0].y, point[0].z);
  //下
  glVertex3f(point[7].x, point[7].y, point[7].z);
  glVertex3f(point[6].x, point[6].y, point[6].z);
  glVertex3f(point[2].x, point[2].y, point[2].z);
  glVertex3f(point[3].x, point[3].y, point[3].z);
  //左 
  glVertex3f(point[0].x, point[0].y, point[0].z);
  glVertex3f(point[4].x, point[4].y, point[4].z);
  glVertex3f(point[7].x, point[7].y, point[7].z);
  glVertex3f(point[3].x, point[3].y, point[3].z);
  //右 
  glVertex3f(point[5].x, point[5].y, point[5].z);
  glVertex3f(point[6].x, point[6].y, point[6].z);
  glVertex3f(point[2].x, point[2].y, point[2].z);
  glVertex3f(point[1].x, point[1].y, point[1].z);
  glEnd();
  glFrontFace(GL_CCW);//设置逆时针方向为正面
  drawLine3D(point[0], point[1], sColor(1, 1, 1, 1));
  drawLine3D(point[1], point[2], sColor(1, 1, 1, 1));
  drawLine3D(point[2], point[3], sColor(1, 1, 1, 1));
  drawLine3D(point[3], point[0], sColor(1, 1, 1, 1));
  drawLine3D(point[5], point[6], sColor(1, 1, 1, 1));
  drawLine3D(point[6], point[7], sColor(1, 1, 1, 1));
  drawLine3D(point[7], point[4], sColor(1, 1, 1, 1));
  drawLine3D(point[4], point[5], sColor(1, 1, 1, 1));
  drawLine3D(point[0], point[4], sColor(1, 1, 1, 1));
  drawLine3D(point[1], point[5], sColor(1, 1, 1, 1));
  drawLine3D(point[3], point[7], sColor(1, 1, 1, 1));
  drawLine3D(point[2], point[6], sColor(1, 1, 1, 1));
  glColor4f(1,1,1,1);
  glDisable(GL_BLEND);
  glPopMatrix();
}
void Gizmo::drawAabbLine(GLAABB3D aabb, sColor color)
{
  glLineWidth(3.0f);
  glPushMatrix();
  glColor3fv(color.color);
  glBegin(GL_LINES);
  glDisable(GL_LIGHTING);
  glVertex3f(aabb.m_vcMin.x, aabb.m_vcMax.y, aabb.m_vcMax.z);
  glVertex3f(aabb.m_vcMax.x, aabb.m_vcMax.y, aabb.m_vcMax.z);
  glVertex3f(aabb.m_vcMax.x, aabb.m_vcMax.y, aabb.m_vcMax.z);
  glVertex3f(aabb.m_vcMax.x, aabb.m_vcMax.y, aabb.m_vcMin.z);
  glVertex3f(aabb.m_vcMax.x, aabb.m_vcMax.y, aabb.m_vcMin.z);
  glVertex3f(aabb.m_vcMin.x, aabb.m_vcMax.y, aabb.m_vcMin.z);
  glVertex3f(aabb.m_vcMin.x, aabb.m_vcMax.y, aabb.m_vcMin.z);
  glVertex3f(aabb.m_vcMin.x, aabb.m_vcMax.y, aabb.m_vcMax.z);
  glVertex3f(aabb.m_vcMin.x, aabb.m_vcMax.y, aabb.m_vcMax.z);
  glVertex3f(aabb.m_vcMin.x, aabb.m_vcMin.y, aabb.m_vcMax.z);
  glVertex3f(aabb.m_vcMax.x, aabb.m_vcMax.y, aabb.m_vcMax.z);
  glVertex3f(aabb.m_vcMax.x, aabb.m_vcMin.y, aabb.m_vcMax.z);
  glVertex3f(aabb.m_vcMax.x, aabb.m_vcMax.y, aabb.m_vcMin.z);
  glVertex3f(aabb.m_vcMax.x, aabb.m_vcMin.y, aabb.m_vcMin.z);
  glVertex3f(aabb.m_vcMin.x, aabb.m_vcMax.y, aabb.m_vcMin.z);
  glVertex3f(aabb.m_vcMin.x, aabb.m_vcMin.y, aabb.m_vcMin.z);
  glVertex3f(aabb.m_vcMin.x, aabb.m_vcMin.y, aabb.m_vcMax.z);
  glVertex3f(aabb.m_vcMin.x, aabb.m_vcMin.y, aabb.m_vcMin.z);
  glVertex3f(aabb.m_vcMin.x, aabb.m_vcMin.y, aabb.m_vcMin.z);
  glVertex3f(aabb.m_vcMax.x, aabb.m_vcMin.y, aabb.m_vcMin.z);
  glVertex3f(aabb.m_vcMax.x, aabb.m_vcMin.y, aabb.m_vcMin.z);
  glVertex3f(aabb.m_vcMax.x, aabb.m_vcMin.y, aabb.m_vcMax.z);
  glVertex3f(aabb.m_vcMax.x, aabb.m_vcMin.y, aabb.m_vcMax.z);
  glVertex3f(aabb.m_vcMin.x, aabb.m_vcMin.y, aabb.m_vcMax.z);
  glColor4f(1, 1, 1, 1);
  glEnd();
  glPopMatrix();
}
void Gizmo::drawRay(GLRay3D& ray, sColor color)
{
  glPushMatrix();
  glLineWidth(2.0);
  glColor3fv(color.color);
  glBegin(GL_LINES);
  glVertex3f(ray.m_vcOrig.x, ray.m_vcOrig.y, ray.m_vcOrig.z);
  glVertex3f(ray.m_vcOrig.x + ray.m_vcDir.x * 10000,
    ray.m_vcOrig.y + ray.m_vcDir.y * 10000,
    ray.m_vcOrig.z+ray.m_vcDir.z*10000);
  glColor3f(1.0f, 1.0f, 1.0f);
  glEnd();
  glPopMatrix();
}
void Gizmo::drawTrianglePlane(GLTrianglePlane &trianglePlane,sColor color)
{
  glPushMatrix();
  glColor4fv(color.color);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glBegin(GL_TRIANGLES);
  glVertex3f(trianglePlane.m_v0.x, trianglePlane.m_v0.y, trianglePlane.m_v0.z);
  glVertex3f(trianglePlane.m_v1.x, trianglePlane.m_v1.y, trianglePlane.m_v1.z);
  glVertex3f(trianglePlane.m_v2.x, trianglePlane.m_v2.y, trianglePlane.m_v2.z);
  glColor3f(1.0f, 1.0f, 1.0f);
  glEnd();
  glDisable(GL_BLEND);
  glBegin(GL_LINE_LOOP);
  glLineWidth(2.0);
  glVertex3f(trianglePlane.m_v0.x, trianglePlane.m_v0.y, trianglePlane.m_v0.z);
  glVertex3f(trianglePlane.m_v1.x, trianglePlane.m_v1.y, trianglePlane.m_v1.z);
  glVertex3f(trianglePlane.m_v2.x, trianglePlane.m_v2.y, trianglePlane.m_v2.z);
  glEnd();
  glPopMatrix();
}
void Gizmo::drawPoint(Vector3D &point, sColor color)
{
  glPushMatrix();
  glPointSize(6.0f);
  glColor3fv(color.color);
  glBegin(GL_POINTS);
  glVertex3f(point.x, point.y,point.z);
  glEnd();
  glColor3f(1, 1, 1);
  glPopMatrix();
}
Gizmo::~Gizmo()
{
}


相关文章
|
22天前
|
前端开发 API vr&ar
Android开发之OpenGL绘制三维图形的流程
即将连载的系列文章将探索Android上的OpenGL开发,这是一种用于创建3D图形和动画的技术。OpenGL是跨平台的图形库,Android已集成其API。文章以2D绘图为例,解释了OpenGL的3个核心元素:GLSurfaceView(对应View)、GLSurfaceView.Renderer(类似Canvas)和GL10(类似Paint)。通过将这些结合,Android能实现3D图形渲染。文章介绍了Renderer接口的三个方法,分别对应2D绘图的构造、测量布局和绘制过程。示例代码展示了如何在布局中添加GLSurfaceView并注册渲染器。
28 1
Android开发之OpenGL绘制三维图形的流程
|
4月前
|
监控 vr&ar Swift
visionOS空间计算实战开发教程Day 5 纹理和材质
本文中我们会通过纹理和材质对这个立方体的六个面分别进行不同的绘制。首先我们将ImmersiveView分拆出来,先新建一个ImmersiveView.swift文件,这是一个视图文件,所以请选择User Interface下的Swift View完成创建,其中的内容待我们编写完ViewModel中的代码后再进行修改。
23 0
|
缓存 JavaScript 前端开发
【图形基础篇】04 # GPU与渲染管线:如何用WebGL绘制最简单的几何图形?
【图形基础篇】04 # GPU与渲染管线:如何用WebGL绘制最简单的几何图形?
268 0
【图形基础篇】04 # GPU与渲染管线:如何用WebGL绘制最简单的几何图形?
从0开发游戏引擎之三维几何体数据类
Shape类只是单纯的形状数据,并不能用具真正的绘制,真正的绘制工作是Gizmo类去做的。该类只是作为Gizmo的一个成员去使用的。Shape的函数只是提供了加工数据的,然后把加工后的数据存下来。不多哔哔了,直接贴代码。原理有空了再详细写。
从0开发游戏引擎之使用OpenGL绘制三维球体
绘制球体的难点主要在于 要在遍历循环中 根据经纬度反复的使用Cos、Sin函数算出球面上的XYZ三个顶点坐标,一直反复计算,最终三角面多的形成了一个球的形状。
|
缓存 BI API
从0开发游戏引擎之纹理管理器实现 纹理数据绑定OpenGL滤波方式选择线性滤波
从0开发游戏引擎之纹理管理器实现 纹理数据绑定OpenGL滤波方式选择线性滤波
【ThreeJs】(1)四大组件:场景、相机、物体、渲染器 | 创建一个矩形 | THREE脑图
【ThreeJs】(1)四大组件:场景、相机、物体、渲染器 | 创建一个矩形 | THREE脑图
327 0
【ThreeJs】(1)四大组件:场景、相机、物体、渲染器 | 创建一个矩形 | THREE脑图
|
JavaScript 前端开发 程序员
Threejs - 几行代码带你创建三维地球
Threejs - 几行代码带你创建三维地球
Threejs - 几行代码带你创建三维地球
|
前端开发 数据可视化 定位技术
Threejs - 搭建三维场景
Threejs - 搭建三维场景
Threejs - 搭建三维场景