/* 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 */
/* Функция преобразования вершин. * АРГУМЕНТЫ: * - геометрический объект: * as4GEOM *G; * - матрица преобразования: * MATR M; * ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: Нет. */ VOID AS4_GeomTransform( as4GEOM *G, MATR M ) { INT i, j; MATR InvM = MatrTranspose(MatrInverse(M)); InvM.A[3][0] = InvM.A[3][1] = InvM.A[3][2] = 0; for (i = 0; i < G->NumOfPrims; i++) for (j = 0; j < G->Prims[i].NumOfV; j++) { G->Prims[i].V[j].P = PointTransform(G->Prims[i].V[j].P, M); G->Prims[i].V[j].N = PointTransform(G->Prims[i].V[j].N, InvM); } } /* End of 'AS4_GeomTransform' function */
/* ‘ункци¤ загрузки геометрического объекта из 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 */
/* ‘ункци¤ рисовани¤. * ј–√”ћ≈Ќ“џ: * - геометрический объект: * ap6GEOM *G; * ¬ќ«¬–јўј≈ћќ≈ «Ќј„≈Ќ»≈: Ќет. */ VOID AP6_GeomDraw( ap6GEOM *G ) { INT i, loc; MATR WVP, MatrWorldInvTrans = {{{0}}}; VEC V; UINT SaveProgId; /* вычислили матрицы преобразовани¤ */ WVP = MatrMulMatr(AP6_Anim.MatrWorld, MatrMulMatr(AP6_Anim.MatrView, AP6_Anim.MatrProjection)); MatrWorldInvTrans = MatrTranspose(MatrInverse(AP6_Anim.MatrWorld)); /* отладочный вывод */ glLoadMatrixf(WVP.A[0]); /* ѕерезагружаем шейдера раз в секунду */ if (G->ProgName[0] != 0) { if (G->ProgTime + 1.0 < AP6_Anim.GlobalTime) { static CHAR Buf[2][MAX_STR]; AP6_ShadProgClose(G->ProgId); sprintf(Buf[0], "SHADERS\\%s.vert", G->ProgName); sprintf(Buf[1], "SHADERS\\%s.frag", G->ProgName); G->ProgTime = AP6_Anim.GlobalTime; G->ProgId = AP6_ShadProgInit(Buf[0], Buf[1]); } } /* сохран¤ем шейдера */ if (G->ProgId != 0) { SaveProgId = AP6_ShaderProg; AP6_ShaderProg = G->ProgId; } /* выбор программы шейдеров вывода примитивов */ glUseProgram(AP6_ShaderProg); loc = glGetUniformLocation(AP6_ShaderProg, "MatrWVP"); if (loc != -1) glUniformMatrix4fv(loc, 1, FALSE, WVP.A[0]); loc = glGetUniformLocation(AP6_ShaderProg, "MatrWorldInverseTranspose"); if (loc != -1) glUniformMatrix4fv(loc, 1, FALSE, MatrWorldInvTrans.A[0]); loc = glGetUniformLocation(AP6_ShaderProg, "MatrWorld"); if (loc != -1) glUniformMatrix4fv(loc, 1, FALSE, AP6_Anim.MatrWorld.A[0]); loc = glGetUniformLocation(AP6_ShaderProg, "MatrView"); if (loc != -1) glUniformMatrix4fv(loc, 1, FALSE, AP6_Anim.MatrView.A[0]); loc = glGetUniformLocation(AP6_ShaderProg, "Time"); if (loc != -1) glUniform1f(loc, AP6_Anim.Time); V = VecSet(-AP6_Anim.MatrView.A[0][2], -AP6_Anim.MatrView.A[1][2], -AP6_Anim.MatrView.A[2][2]); loc = glGetUniformLocation(AP6_ShaderProg, "ViewDir"); if (loc != -1) glUniform3fv(loc, 1, &V.X); V = VecSet(AP6_Anim.MatrView.A[3][0], AP6_Anim.MatrView.A[3][1], AP6_Anim.MatrView.A[3][2]); loc = glGetUniformLocation(AP6_ShaderProg, "ViewPos"); if (loc != -1) glUniform3fv(loc, 1, &V.X); loc = glGetUniformLocation(AP6_ShaderProg, "NumOfParts"); if (loc != -1) glUniform1f(loc, G->NumOfPrims); for (i = 0; i < G->NumOfPrims; i++) { INT mtl = G->Prims[i].Mtl; loc = glGetUniformLocation(AP6_ShaderProg, "PartNo"); if (loc != -1) glUniform1f(loc, i); /* подготавливаем материал */ if (G->Mtls != NULL && mtl >= 0 && mtl < G->NumOfMtls) { INT loc; if (G->Mtls[mtl].TexNo == 0 && G->Mtls[mtl].MapD[0] != 0) { INT j; IMAGE Img; ImageLoad(&Img, G->Mtls[mtl].MapD); /* получаем свободный номер текстуры */ glGenTextures(1, &G->Mtls[mtl].TexNo); /* делаем ее активной */ glBindTexture(GL_TEXTURE_2D, G->Mtls[mtl].TexNo); for (j = 0; j < Img.W * Img.H; j++) Img.Bits[j] |= 0xFF000000; /* отправл¤ем картинку в видеопам¤ть */ gluBuild2DMipmaps(GL_TEXTURE_2D, 4, Img.W, Img.H, GL_BGRA_EXT, GL_UNSIGNED_BYTE, Img.Bits); /* ѕараметры вывода */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); } /* передаем параметры */ if (G->Mtls[mtl].TexNo != 0) { loc = glGetUniformLocation(AP6_ShaderProg, "IsTextureUsed"); if (loc != -1) glUniform1f(loc, 1); loc = glGetUniformLocation(AP6_ShaderProg, "DrawTexture"); if (loc != -1) glUniform1i(loc, 0); //glEnable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, G->Mtls[mtl].TexNo); //glActiveTexture(GL_TEXTURE1); //glBindTexture(GL_TEXTURE_2D, G->Mtls[mtl].TexNo); } else { loc = glGetUniformLocation(AP6_ShaderProg, "IsTextureUsed"); if (loc != -1) glUniform1f(loc, 0); } loc = glGetUniformLocation(AP6_ShaderProg, "Ka"); if (loc != -1) glUniform3fv(loc, 1, &G->Mtls[mtl].Ka.X); loc = glGetUniformLocation(AP6_ShaderProg, "Kd"); if (loc != -1) glUniform3fv(loc, 1, &G->Mtls[mtl].Kd.X); loc = glGetUniformLocation(AP6_ShaderProg, "Ks"); if (loc != -1) glUniform3fv(loc, 1, &G->Mtls[mtl].Ks.X); loc = glGetUniformLocation(AP6_ShaderProg, "Phong"); if (loc != -1) glUniform1f(loc, G->Mtls[mtl].Phong); loc = glGetUniformLocation(AP6_ShaderProg, "Trans"); if (loc != -1) glUniform1f(loc, G->Mtls[mtl].Trans); } loc = glGetUniformLocation(AP6_ShaderProg, "PartNo"); if (loc != -1) glUniform1f(loc, i); AP6_PrimDraw(G->Prims + i); glDisable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); } /* восстанавливаем шейдера */ if (G->ProgId != 0) AP6_ShaderProg = SaveProgId; } /* End of 'AP6_GeomDraw' function */
VOID PK2_PrimDraw( PK2PRIM *Prim ) { INT loc; MATR M; PK2_RndMatrWorldViewProj = MatrMulMatr(MatrMulMatr(PK2_RndMatrWorld, PK2_RndMatrView), PK2_RndMatrProj); glLoadMatrixf(PK2_RndMatrWorldViewProj.A[0]); glBindVertexArray(Prim->VA); glUseProgram(PK2_RndProg); loc = glGetUniformLocation(PK2_RndProg, "MatrWorld"); if (loc != -1) glUniformMatrix4fv(loc, 1, FALSE, PK2_RndMatrWorld.A[0]); loc = glGetUniformLocation(PK2_RndProg, "MatrView"); if (loc != -1) glUniformMatrix4fv(loc, 1, FALSE, PK2_RndMatrView.A[0]); loc = glGetUniformLocation(PK2_RndProg, "MatrProj"); if (loc != -1) glUniformMatrix4fv(loc, 1, FALSE, PK2_RndMatrProj.A[0]); loc = glGetUniformLocation(PK2_RndProg, "MatrWVP"); if (loc != -1) glUniformMatrix4fv(loc, 1, FALSE, PK2_RndMatrWorldViewProj.A[0]); M = MatrTranspose(MatrInverse(MatrMulMatr(PK2_RndMatrWorld, PK2_RndMatrView))); loc = glGetUniformLocation(PK2_RndProg, "MatrWVInverse"); if (loc != -1) glUniformMatrix4fv(loc, 1, FALSE, M.A[0]); M = MatrTranspose(MatrInverse(PK2_RndMatrWorld)); loc = glGetUniformLocation(PK2_RndProg, "MatrWInverse"); if (loc != -1) glUniformMatrix4fv(loc, 1, FALSE, M.A[0]); M = MatrMulMatr(PK2_RndMatrWorld, PK2_RndMatrView); loc = glGetUniformLocation(PK2_RndProg, "MatrWV"); if (loc != -1) glUniformMatrix4fv(loc, 1, FALSE, M.A[0]); loc = glGetUniformLocation(PK2_RndProg, "Time"); if (loc != -1) glUniform1f(loc, PK2_Anim.Time); loc = glGetUniformLocation(PK2_RndProg, "Ka"); if (loc != -1) glUniform3fv(loc, 1, &PK2_MtlLib[Prim->MtlNo].Ka.X); loc = glGetUniformLocation(PK2_RndProg, "Kd"); if (loc != -1) glUniform3fv(loc, 1, &PK2_MtlLib[Prim->MtlNo].Kd.X); loc = glGetUniformLocation(PK2_RndProg, "Ks"); if (loc != -1) glUniform3fv(loc, 1, &PK2_MtlLib[Prim->MtlNo].Ks.X); loc = glGetUniformLocation(PK2_RndProg, "Kp"); if (loc != -1) glUniform1f(loc, PK2_MtlLib[Prim->MtlNo].Kp); loc = glGetUniformLocation(PK2_RndProg, "Kt"); if (loc != -1) glUniform1f(loc, PK2_MtlLib[Prim->MtlNo].Kt); loc = glGetUniformLocation(PK2_RndProg, "IsTextureUse"); if (PK2_MtlLib[Prim->MtlNo].TexId == 0) glUniform1f(loc, 0); else { glUniform1f(loc, 1); glBindTexture(GL_TEXTURE_2D, PK2_MtlLib[Prim->MtlNo].TexId); } glPrimitiveRestartIndex(0xFFFFFFFF); if (Prim->Type == PK2_PRIM_GRID) glDrawElements(GL_TRIANGLE_STRIP, Prim->NumOfI, GL_UNSIGNED_INT, NULL); else glDrawElements(GL_TRIANGLES, Prim->NumOfI, GL_UNSIGNED_INT, NULL); glUseProgram(0); glBindVertexArray(0); } /* End of 'PK2_PrimDraw' function */