***mylib.asm*** global _mul_m44f_v4f section .text use32 _mul_m44f_v4f: mov eax, dword [esp+4] ; ptr result mov ecx, dword [esp+8] ; ptr A mov edx, dword [esp+12] ; ptr vec movaps xmm0, [ecx] ; A[0] movaps xmm1, [ecx+16] ; A[1] movaps xmm2, [ecx+32] ; A[2] movaps xmm3, [ecx+48] ; A[3] movaps xmm4, [edx] ; v mulps xmm0, xmm4 ; A[0]=vec*A[0] mulps xmm1, xmm4 ; A[1]=vec*A[1] mulps xmm2, xmm4 ; A[2]=vec*A[2] mulps xmm3, xmm4 ; A[3]=vec*A[3] haddps xmm0, xmm1 ; функция складывает упакованные числа так что: haddps xmm2, xmm3 ; X={X0,X1,X2,X3} и Y={Y0,Y1,Y2,Y3} при таком сложении haddps xmm0, xmm2 ; при таком сложении станут {X0+X1,X2+X3,Y0+Y1,Y2+Y3} ;применив это три раза можно сложить строки матрицы в вектор movaps [eax], xmm0 ; save to result ret ***mylib.asm*** ***main.c*** #include #include "mylib.h" int main() { //так как в 3d пространстве 4 координата не нужна то она будет 0 v4f a[8] = {{-1.0f, 1.0f, 1.0f, 0.0f},{1.0f, 1.0f, 1.0f, 0.0f},{1.0f, -1.0f, 1.0f, 0.0f},{-1.0f, -1.0f, 1.0f, 0.0f}, {-1.0f, -1.0f, -1.0f, 0.0f},{1.0f, -1.0f, -1.0f, 0.0f},{1.0f, 1.0f, -1.0f, 0.0f},{-1.0f, 1.0f, -1.0f, 0.0f}}; //объявим и инициализируем массив точек куба v4f b[8]; //матрица поворота на 30 градусов по оси X m44f rotateX = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.86602540378f, 0.5f, 0.0f, 0.0f, -0.5f, 0.86602540378f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; //матрица поворота на 30 градусов по оси Y m44f rotateY = {0.86602540378f, 0.0f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.86602540378f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}; float x[12][2],y[12][2]; //объявим массивы точек граней куба int i; //поворот точек через умножение на матрицу for (i=0;i<8;i++){ b[i]=mul_m44f_v4f(&rotateX, &a[i]); } for (i=0;i<8;i++){ a[i]=mul_m44f_v4f(&rotateY, &b[i]); } //сделаем грани //семь граней можно сделать в цикле если указать точки в нужном порядке for (i=0;i<7;i++){ x[i][0]=a[i].x; x[i][1]=a[i+1].x; y[i][0]=a[i].y; y[i][1]=a[i+1].y; } //остальные пять граней вручную x[7][0]=a[0].x; x[7][1]=a[7].x; y[7][0]=a[0].y; y[7][1]=a[7].y; x[8][0]=a[0].x; x[8][1]=a[3].x; y[8][0]=a[0].y; y[8][1]=a[3].y; x[9][0]=a[7].x; x[9][1]=a[4].x; y[9][0]=a[7].y; y[9][1]=a[4].y; x[10][0]=a[6].x; x[10][1]=a[1].x; y[10][0]=a[6].y; y[10][1]=a[1].y; x[11][0]=a[5].x; x[11][1]=a[2].x; y[11][0]=a[5].y; y[11][1]=a[2].y; FILE *fp; char* name="cube.svg"; fp = fopen( name, "w+" ); //начало файла fprintf(fp,"\n\n"); //линии for (i=0;i<12;i++) { fprintf(fp,"\n\n", x[i][0], y[i][0], x[i][1], y[i][1]); } //конец файла fprintf(fp,"\n"); fclose(fp); return 0; } ***main.c*** ***mylib.h*** #ifndef _MYLIB_H_ #define _MYLIB_H_ #ifdef _MSC_VER # define _ALIGN16_ __declspec(align(16)) #else # define _ALIGN16_ __attribute__ ((aligned(16))) #endif typedef _ALIGN16_ struct v4f_s { float x; float y; float z; float w; } v4f; typedef _ALIGN16_ struct m44f_s { float e[4][4]; } m44f; v4f mul_m44f_v4f(m44f *A, v4f *v); v4f add_v4f_v4f(v4f *a, v4f *b); #endif // _MYLIB_H_ ***mylib.h*** ***CmakeLists.txt*** cmake_minimum_required(VERSION 2.8.12) project(lab74 C ASM_NASM) add_executable(lab74 "main.c" "mylib.h" "mylib.asm") set_target_properties(lab74 PROPERTIES LINKER_LANGUAGE C) ***CmakeLists.txt***