Beispiel #1
0
VOID AL5_AnimInit( HWND hWnd )
{ 
  INT i;
  PIXELFORMATDESCRIPTOR pfd = {0};

  LARGE_INTEGER t;
  
 
  AL5_Anim.NumOfUnits = 0;
  
  memset(&AL5_Anim, 0, sizeof(al5ANIM));
  AL5_Anim.hWnd = hWnd;
  AL5_Anim.hDC = GetDC(hWnd);

    /*** openGl ***/
  pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
  pfd.nVersion = 1;
  pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL;
  pfd.cColorBits = 32;
  pfd.cDepthBits = 32;
  i = ChoosePixelFormat(AL5_Anim.hDC, &pfd);
  DescribePixelFormat(AL5_Anim.hDC, i, sizeof(pfd), &pfd);
  SetPixelFormat(AL5_Anim.hDC, i, &pfd);
    /* OpenGL init: setup rendering context */
  AL5_Anim.hGLRC = wglCreateContext(AL5_Anim.hDC);
  wglMakeCurrent(AL5_Anim.hDC, AL5_Anim.hGLRC);
  /* OpenGL init: setup extensions: GLEW library */
  if (glewInit() != GLEW_OK ||
      !(GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader))
  {
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(AL5_Anim.hGLRC);
    ReleaseDC(AL5_Anim.hWnd, AL5_Anim.hDC);
    exit(0);
  }

    /*** init timer ***/
  QueryPerformanceFrequency(&t);
  AL5_TimePerSec = t.QuadPart;
  QueryPerformanceCounter(&t);
  AL5_StartTime = AL5_OldTime = AL5_OldTimeFPS = t.QuadPart;
  AL5_PauseTime = 0;

  AL5_RndMatrProj = MatrFrustum(-1, 1, -1, 1, 1, 100);
  AL5_RndMatrWorld = MatrIdentity();
  AL5_RndMatrView  = MatrMulMatr(MatrIdentity(), MatrTranslate(VecSet(-1, -1, 0)));

  /* OpenGL specific initialization */
  glClearColor(0.3, 0.5, 0.7, 1);
  glEnable(GL_DEPTH_TEST );
  /* glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); */

  AL5_RndPrg = AL5_RndShaderLoad("a");
}
Beispiel #2
0
/* Begin of 'WinMain' function */
INT WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, CHAR *CmdLine, INT ShowCmd )
{
  MATR m =
  {{
    {2, 0, 0, 0},
    {1, 2, 0, 0},
    {1, 1, 2, 0},
    {1, 1, 1, 2}
  }};
  DBL g;

  m = MatrIdentity();
  m = MatrTranslate(VecSet(1, 2, 3));
  m = MatrScale(VecSet(1, 2, 3));
  m = MatrRotateX(30);
  m = MatrRotateY(30);
  m = MatrRotateZ(30);
  m = MatrRotate(30, VecSet(1, 2, 3));
  m = MatrMulMatr(MatrRotateX(90), MatrScale(VecSet(2, 2, 2)));
  m = MatrInverse(m);
  g = MatrDeterm(m);
  m = MatrTranspose(m);

  return 0;
}/* Begin of 'WinMain' function */
Beispiel #3
0
/* Функция построения объекта анимации.
 * АРГУМЕНТЫ:
 *   - указатель на "себя" - сам объект анимации:
 *       vg4UNIT_CTRL *Uni;
 *   - указатель на контекст анимации:
 *       vg4ANIM *Ani;
 * ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Нет.
 */
static VOID VG4_AnimUnitRender( vg4UNIT_CTRL *Uni, vg4ANIM *Ani )
{
  HFONT hFntOld = SelectObject(Ani->hDC, Uni->hFnt);
  static DBL count = 30;
  static CHAR Buf[1000];

  count += Ani->GlobalDeltaTime;
  if (count > 1)
  {
    count = 0;
    sprintf(Buf, "FPS: %.3f", Ani->FPS);
    SetWindowText(Ani->hWnd, Buf);
  }

  /* вертолет */
  VG4_RndMatrWorld =
    MatrMulMatr(MatrMulMatr(MatrMulMatr(
      MatrRotateX(-Ani->JY * 30), MatrRotateZ(Ani->JX * 59)),
      MatrRotateY(Uni->Head)), MatrTranslate(Uni->Pos.X, Uni->Pos.Y, Uni->Pos.Z));
  VG4_GeomDraw(&Uni->Helic);

  /* оси */
  VG4_RndMatrWorld = MatrIdentity();
  VG4_GeomDraw(&Uni->Axes);

  //VG4_RndMatrWorld = MatrTranslate(Uni->At.X, Uni->At.Y, Uni->At.Z);
  //VG4_PrimDraw(&Uni->Sph);

} /* End of 'VG4_AnimUnitRender' function */
Beispiel #4
0
BOOL SS3_AnimInit( HWND hWnd )
{
  INT i;
  LARGE_INTEGER li;
  PIXELFORMATDESCRIPTOR pfd = {0};

  SS3_Anim.hDC = GetDC(hWnd);
  SS3_Anim.hWnd = hWnd;
  SS3_Anim.W = 30;
  SS3_Anim.H = 30;
  SS3_Anim.NumOfUnits = 0;
  
  pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
  pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI | PFD_DOUBLEBUFFER;
  pfd.iPixelType = PFD_TYPE_RGBA;
  pfd.cColorBits = 32;
  i = ChoosePixelFormat(SS3_Anim.hDC, &pfd);
  DescribePixelFormat(SS3_Anim.hDC, i, sizeof(pfd), &pfd);
  SetPixelFormat(SS3_Anim.hDC, i, &pfd);

  /* создаем контекст построения */
  SS3_Anim.hRC = wglCreateContext(SS3_Anim.hDC);

  /* делаем текущими контексты */
  wglMakeCurrent(SS3_Anim.hDC, SS3_Anim.hRC);

  if (glewInit() != GLEW_OK ||
      !(GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader))
  {
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(SS3_Anim.hRC);
    ReleaseDC(SS3_Anim.hWnd, SS3_Anim.hDC);
    memset(&SS3_Anim, 0, sizeof(ss3ANIM));
    return FALSE;
  }

  QueryPerformanceFrequency(&li);
  TimeFreq = li.QuadPart;

  QueryPerformanceCounter(&li);
  TimeStart = TimeOld = TimeFPS = li.QuadPart;
  TimePause = 0;
  FrameCounter = 0;

  /* Параметры проецирования */
  SS3_Anim.Wp = 4, SS3_Anim.Hp = 3,     /* размеры обрасти проецирования */
  SS3_Anim.ProjDist = 5;              /* расстояние до плоскости проекции */
  SS3_Anim.MatrWorld =  
    SS3_Anim.MatrView = 
    SS3_Anim.MatrProjection = MatrIdentity();
  SS3_Anim.ProjSize = 1;
  SS3_Anim.PosCam.X = SS3_Anim.PosCam.Y = SS3_Anim.PosCam.Z = 50;

  //SS3_hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, SS3_MouseHook, GetModuleHandle(NULL), 0);
  return TRUE;
}
Beispiel #5
0
VOID IK3_AnimUnit( HWND hWnd )
{
  INT i;
  LARGE_INTEGER t;
  PIXELFORMATDESCRIPTOR pfd = {0};
 
  memset(&IK3_Anim, 0, sizeof(ik3Anim));

  /* Store window and create memory device context */
  IK3_Anim.hWnd = hWnd;
  IK3_Anim.hDC = GetDC(hWnd);
  /* OpenGL init: pixel format setup */
  pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
  pfd.nVersion = 1;
  pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL;
  pfd.cColorBits = 32;
  pfd.cDepthBits = 32;
  i = ChoosePixelFormat(IK3_Anim.hDC, &pfd);
  DescribePixelFormat(IK3_Anim.hDC, i, sizeof(pfd), &pfd);
  SetPixelFormat(IK3_Anim.hDC, i, &pfd);

  /* OpenGL init: setup rendering context */
  IK3_Anim.hGLRC = wglCreateContext(IK3_Anim.hDC);
  wglMakeCurrent(IK3_Anim.hDC, IK3_Anim.hGLRC);

  /* OpenGL init: setup extensions: GLEW library */
  if (glewInit() != GLEW_OK ||
      !(GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader))
  {
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(IK3_Anim.hGLRC);
    ReleaseDC(IK3_Anim.hWnd, IK3_Anim.hDC);
    exit(0);
  }

  QueryPerformanceFrequency(&t);
  IK3_TimePerSec = t.QuadPart;
  QueryPerformanceCounter(&t);
  IK3_StartTime = IK3_OldTime = IK3_OldTimeFPS = t.QuadPart;
  IK3_PauseTime = 0;

  IK3_RndMatrWorld  = MatrIdentity();
  IK3_RndMatrView = MatrView(VecSet(0, 1, 0), VecSet(0, 0, 0), VecSet(0, 1, 0));
  IK3_RndMatrProj = MatrFrustum(-1, 1, -1, 1, 1, 100);
  IK3_RndProjDist = 3;
  IK3_RndFarClip = 3000;
  IK3_RndProjSize = 3;
  /* OpenGL specific initialization */
  glClearColor(0.3, 0.5, 0.7, 1);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  IK3_RndPrg = IK3_RndShaderLoad("a");
  /* glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); */
}
Beispiel #6
0
/* Draw object functioln.
 * ARGUMENTS:
 *   - context of the window:
 *       HDC hDC;
 *   - the size of the window:
 *       INT W, H;
 * RETURNS: None.
 */
VOID ObjDraw( HDC hDC, INT X, INT Y, DWORD Color, PK2ANIM *Ani )
{
  INT i;
  DBL x = sin(30);

  srand(30);
  for (i = 0; i < ObjNumOfV; i++)
  {
    if (!Ani->IsPause)
      ObjV[i] = VecMulMatr3(ObjV[i], MatrMulMatr(MatrRotateY(sin(Ani->Time * 0.5)), MatrRotateX(sin(Ani->Time * 3))));
    else
      ObjV[i] = VecMulMatr3(ObjV[i], MatrIdentity());

    SetDCBrushColor(hDC, Color);
    Ellipse(hDC,X + ObjV[i].X - 4, Y - ObjV[i].Y - 4, X + ObjV[i].X + 4, Y - ObjV[i].Y + 4);
  }

} /* End of 'ObjDraw' function */
Beispiel #7
0
/* Primitive create function.
 * ARGUMENTS:
 *   - primitive structure pointer:
 *      avdPRIM *Pr;
 *   - vertex array:
 *       avdVERTEX *V;
 *   - vertex array size:
 *       INT NumOfV;
 *   - index array:
 *       INT *I;
 *   - INT array size:
 *       INT NumOfI;
 * RETURNS: None.
 */
VOID AVD_RndPrimCreate( avdPRIM *Pr, avdVERTEX *V, INT NumOfV, INT *I, INT NumOfI )
{
  INT i;

  memset(Pr, 0, sizeof(avdPRIM));

  Pr->M = MatrIdentity();
  Pr->NumOfI = NumOfI;

  /* Get min-max primitive info */
  Pr->Min = Pr->Max = V[0].P;
  for (i = 1; i < NumOfV; i++)
  {
    Pr->Min.X = AVD_MIN(Pr->Min.X, V[i].P.X);
    Pr->Min.Y = AVD_MIN(Pr->Min.Y, V[i].P.Y);
    Pr->Min.Z = AVD_MIN(Pr->Min.Z, V[i].P.Z);
    Pr->Max.X = AVD_MAX(Pr->Max.X, V[i].P.X);
    Pr->Max.Y = AVD_MAX(Pr->Max.Y, V[i].P.Y);
    Pr->Max.Z = AVD_MAX(Pr->Max.Z, V[i].P.Z);
  }
  /* Set central point */
  Pr->Center = VecDivNum(VecAddVec(Pr->Min, Pr->Max), 2);

  /* Create OpenGL buffers */
  glGenVertexArrays(1, &Pr->VA);
  glGenBuffers(1, &Pr->VBuf);
  glGenBuffers(1, &Pr->IBuf);

  /* Activate vertex array */
  glBindVertexArray(Pr->VA);
  /* Activate vertex buffer */
  glBindBuffer(GL_ARRAY_BUFFER, Pr->VBuf);
  /* Store vertex data */
  glBufferData(GL_ARRAY_BUFFER, sizeof(avdVERTEX) * NumOfV, V, GL_STATIC_DRAW);

  /* Setup data order */
  /*                    layout,
   *                      components count,
   *                          type
   *                                    should be normalize,
   *                                           vertex structure size in bytes (stride),
   *                                               offset in bytes to field start */
  glVertexAttribPointer(0, 3, GL_FLOAT, FALSE, sizeof(avdVERTEX),
                        (VOID *)0); /* position */
  glVertexAttribPointer(1, 2, GL_FLOAT, FALSE, sizeof(avdVERTEX),
                        (VOID *)sizeof(VEC)); /* texture coordinates */
  glVertexAttribPointer(2, 3, GL_FLOAT, FALSE, sizeof(avdVERTEX),
                        (VOID *)(sizeof(VEC) + sizeof(VEC2))); /* normal */
  glVertexAttribPointer(3, 4, GL_FLOAT, FALSE, sizeof(avdVERTEX),
                        (VOID *)(sizeof(VEC) * 2 + sizeof(VEC2))); /* color */

  /* Enable used attributes */
  glEnableVertexAttribArray(0);
  glEnableVertexAttribArray(1);
  glEnableVertexAttribArray(2);
  glEnableVertexAttribArray(3);

  /* Indices */
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Pr->IBuf);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(INT) * NumOfI, I, GL_STATIC_DRAW);

  /* Disable vertex array */
  glBindVertexArray(0);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
} /* End of 'VG4_RndPrimCreate' function */
Beispiel #8
0
  mtl.Ka = VecSet(0.1, 0.1, 0.1);
  mtl.Kd = VecSet(1, 1, 1);
  mtl.Ks = VecSet(0, 0, 0);
  mtl.Phong = 30;
  mtl.Trans = 1;
  mtl.TexNo = 0;
  mtl.MapD[0] = 0;
  strcpy(mtl.MapD, "map2-hf.bmp");
  strcpy(mtl.Name, "Height Field Material");
  prim.Mtl = VG4_GeomAddMaterial(&Unit->Obj, &mtl);

  VG4_GeomAddPrim(&Unit->Obj, &prim);

. . .

  Ani->MatrWorld = MatrIdentity();
  Ani->MatrView =
    MatrViewLookAt(
      VecMulMatr(VecMulMatr(VecSet(25, 25, 25), MatrRotateY(Ani->JR * 180)), MatrRotateZ(Ani->JY * 180)),
      VecSet(0, 0, 0), VecSet(0, 1, 0));
  WVP = MatrMulMatr(VG4_Anim.MatrWorld,
    MatrMulMatr(VG4_Anim.MatrView, VG4_Anim.MatrProjection));
  glLoadMatrixf(WVP.A[0]);
. . .
  Ani->MatrWorld = MatrMulMatr(MatrRotateX(-0), MatrTranslate(0, 0, 0.30 * sin(Ani->Time)));
  VG4_GeomDraw(&Unit->Obj);



Beispiel #9
0
/* ‘ункци¤ загрузки геометрического объекта из G3D файла.
 * ј–√”ћ≈Ќ“џ:
 *   - указатель на геометрический объект:
 *       am1GEOM *G;
 *   - им¤ файла:
 *       CHAR *FileName;
 * ¬ќ«¬–јўј≈ћќ≈ «Ќј„≈Ќ»≈:
 *   (BOOL) TRUE при успехе, иначе - FALSE.
 */
BOOL AM1_GeomLoad( am1GEOM *G, CHAR *FileName )
{
  FILE *F;
  INT i, j, n;
  CHAR Sign[4];
  MATR M;
  static CHAR MtlName[300];
  static CHAR
    path_buffer[_MAX_PATH],
    drive[_MAX_DRIVE],
    dir[_MAX_DIR],
    fname[_MAX_FNAME],
    ext[_MAX_EXT];

  _splitpath(FileName, drive, dir, fname, ext);

  memset(G, 0, sizeof(am1GEOM));
  if ((F = fopen(FileName, "rb")) == NULL)
    return FALSE;

  M = MatrTranspose(MatrInverse(AM1_RndPrimMatrConvert));

  /* читаем сигнатуру */
  fread(Sign, 1, 4, F);
  if (*(DWORD *)Sign != *(DWORD *)"G3D")
  {
    fclose(F);
    return FALSE;
  }

  /* читаем количество примитивов в объекте */
  fread(&n, 4, 1, F);
  fread(MtlName, 1, 300, F);

  /* читаем и загружаем библиотеку материалов */
  _makepath(path_buffer, drive, dir, MtlName, "");
  AM1_MtlLoad(path_buffer);

  /* читаем примитивы */
  for (i = 0; i < n; i++)
  {
    INT nv, ni, *Ind;
    am1VERTEX *Vert;
    am1PRIM P;

    /* читаем количество вершин и индексов */
    fread(&nv, 4, 1, F);
    fread(&ni, 4, 1, F);
    /* читаем им¤ материала текущего примитива */
    fread(MtlName, 1, 300, F);

    /* выдел¤ем пам¤ть под вершины и индексы */
    if ((Vert = malloc(sizeof(am1VERTEX) * nv + sizeof(INT) * ni)) == NULL)
      break;
    Ind = (INT *)(Vert + nv);

    /* читаем данные */
    fread(Vert, sizeof(am1VERTEX), nv, F);
    /* конвертируем геометрию */
    for (j = 0; j < nv; j++)
    {
      Vert[j].P = VecMulMatr(Vert[j].P, AM1_RndPrimMatrConvert);
      Vert[j].N = VecMulMatr3(Vert[j].N, M);
    }
    fread(Ind, sizeof(INT), ni, F);

    /* заносим в примитив */
    AM1_PrimCreate(&P, AM1_PRIM_TRIMESH, nv, ni, Vert, Ind);
    P.MtlNo = AM1_MtlFind(MtlName);

    free(Vert);

    /* добавл¤ем примитив к объекту */
    AM1_GeomAddPrim(G, &P);
  }
  fclose(F);
  AM1_RndPrimMatrConvert = MatrIdentity();
  return TRUE;
} /* End of 'AM1_GeomDraw' function */
Beispiel #10
0
/* Load object from '*.g3d' file function.
 * ARGUMENTS:
 *   - object structure pointer:
 *       vg4OBJ *Obj;
 *   - file name:
 *       CHAR *FileName;
 * RETURNS:
 *   (BOOL) TRUE is success, FALSE otherwise.
 */
BOOL VG4_RndObjLoad( vg4OBJ *Obj, CHAR *FileName )
{
  FILE *F;
  DWORD Sign;
  INT NumOfPrimitives;
  CHAR MtlFile[300];
  INT NumOfV;
  INT NumOfI;
  CHAR Mtl[300];
  INT p;
  vg4VERTEX *V;
  INT *I;

  memset(Obj, 0, sizeof(vg4OBJ));

  F = fopen(FileName, "rb");
  if (F == NULL)
    return FALSE;

  /* File structure:
   *   4b Signature: "G3D\0"    CHAR Sign[4];
   *   4b NumOfPrimitives       INT NumOfPrimitives;
   *   300b material file name: CHAR MtlFile[300];
   *   repeated NumOfPrimitives times:
   *     4b INT NumOfV; - vertex count
   *     4b INT NumOfI; - index (triangles * 3) count
   *     300b material name: CHAR Mtl[300];
   *     repeat NumOfV times - vertices:
   *         !!! float point -> FLT
   *       typedef struct
   *       {
   *         VEC  P;  - Vertex position
   *         VEC2 T;  - Vertex texture coordinates
   *         VEC  N;  - Normal at vertex
   *         VEC4 C;  - Vertex color
   *       } VERTEX;
   *     repeat (NumOfF / 3) times - facets (triangles):
   *       INT N0, N1, N2; - for every triangle (N* - vertex number)
   */
  fread(&Sign, 4, 1, F);
  if (Sign != *(DWORD *)"G3D")
  {
    fclose(F);
    return FALSE;
  }
  fread(&NumOfPrimitives, 4, 1, F);
  fread(MtlFile, 1, 300, F);
  VG4_RndLoadMaterials(MtlFile);

  /* Allocate mnemory for primitives */
  if ((Obj->Prims = malloc(sizeof(vg4PRIM) * NumOfPrimitives)) == NULL)
  {
    fclose(F);
    return FALSE;
  }
  Obj->NumOfPrims = NumOfPrimitives;

  for (p = 0; p < NumOfPrimitives; p++)
  {
    /* Read primitive info */
    fread(&NumOfV, 4, 1, F);
    fread(&NumOfI, 4, 1, F);
    fread(Mtl, 1, 300, F);

    /* Allocate memory for primitive */
    if ((V = malloc(sizeof(vg4VERTEX) * NumOfV + sizeof(INT) * NumOfI)) == NULL)
    {
      while (p-- > 0)
      {
        glBindVertexArray(Obj->Prims[p].VA);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glDeleteBuffers(1, &Obj->Prims[p].VBuf);
        glBindVertexArray(0);
        glDeleteVertexArrays(1, &Obj->Prims[p].VA);
        glDeleteBuffers(1, &Obj->Prims[p].IBuf);
      }
      free(Obj->Prims);
      memset(Obj, 0, sizeof(vg4OBJ));
      fclose(F);
      return FALSE;
    }
    I = (INT *)(V + NumOfV);
    Obj->Prims[p].NumOfI = NumOfI;
    Obj->Prims[p].M = MatrIdentity();
    Obj->Prims[p].MtlNo = VG4_RndFindMaterial(Mtl);
    fread(V, sizeof(vg4VERTEX), NumOfV, F);
    fread(I, sizeof(INT), NumOfI, F);

    /* Create OpenGL buffers */
    glGenVertexArrays(1, &Obj->Prims[p].VA);
    glGenBuffers(1, &Obj->Prims[p].VBuf);
    glGenBuffers(1, &Obj->Prims[p].IBuf);

    /* Activate vertex array */
    glBindVertexArray(Obj->Prims[p].VA);
    /* Activate vertex buffer */
    glBindBuffer(GL_ARRAY_BUFFER, Obj->Prims[p].VBuf);
    /* Store vertex data */
    glBufferData(GL_ARRAY_BUFFER, sizeof(vg4VERTEX) * NumOfV, V, GL_STATIC_DRAW);

    /* Setup data order */
    /*                    layout,
     *                      components count,
     *                          type
     *                                    should be normalize,
     *                                           vertex structure size in bytes (stride),
     *                                               offset in bytes to field start */
    glVertexAttribPointer(0, 3, GL_FLOAT, FALSE, sizeof(vg4VERTEX),
                          (VOID *)0); /* position */
    glVertexAttribPointer(1, 2, GL_FLOAT, FALSE, sizeof(vg4VERTEX),
                          (VOID *)sizeof(VEC)); /* texture coordinates */
    glVertexAttribPointer(2, 3, GL_FLOAT, FALSE, sizeof(vg4VERTEX),
                          (VOID *)(sizeof(VEC) + sizeof(VEC2))); /* normal */
    glVertexAttribPointer(3, 4, GL_FLOAT, FALSE, sizeof(vg4VERTEX),
                          (VOID *)(sizeof(VEC) * 2 + sizeof(VEC2))); /* color */

    /* Enable used attributes */
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);
    glEnableVertexAttribArray(3);

    /* Indices */
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Obj->Prims[p].IBuf);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(INT) * NumOfI, I, GL_STATIC_DRAW);

    /* Disable vertex array */
    glBindVertexArray(0);

    free(V);
  }
  fclose(F);
  return TRUE;
} /* End of 'VG4_RndObjLoad' function */