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"); }
/* 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 */
/* Функция построения объекта анимации. * АРГУМЕНТЫ: * - указатель на "себя" - сам объект анимации: * 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 */
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; }
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); */ }
/* 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 */
/* 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 */
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);
/* ‘ункци¤ загрузки геометрического объекта из 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 */
/* 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 */