Вечер 25.04.2026. Сорок лет Во вложении - пятак РБМК на самопальном OpenGL-движке Ходить - стрелками, летать - PgUp/PgDn, крутить объект - WSAD, крутить камеру - кнопки мыши и колесо, колесо можно крутить и нажимать F1 для справки Bonus0: то же самое на VBA для Excel. Тот случай, когда пишешь на ассемблере, но это VBA Bonus1: то же самое на С. Перевод на С с ассемблера
ОБАЛДЕТЬ ! ! ! ! ! ! Вот это проект, так проект ! ! ! ! Можно сказать, что ПРОЕКТИЩЕ !!!!! Я аж прослезился от радости за автора этого проекта - от БЕЛОЙ ЗАВИСТИ ! ! ! :=) P.S. По-моему, в шапку нужно добавить, что есть проект для MASM x64 ! ! ! !
Чтобы не менять название темы, я добавил движок под 32 бита. По идее, должен запускаться на всём, что имеет SSE, т.е. PIII Katmai и новее. Летает на Compaq Presario 1700T с Celeron 700E, 128Мб RAM и ATI Rage Mobility-M1. Дописал пока не всё. Как и в случае с "Москвичом", упёрся в парсер. Я не могу определиться, что я хочу от этого парсера, поэтому не могу решить несформулированную задачу. Что касается геометрии, то тут всё в порядке. Я не использую штатные glTranslatef и glRotatef. Всё своими ручками. Матрицу Projection я настраиваю на перспективу и больше не трогаю. Матрицу ModelView не преобразую вообще. Просто загружаю в неё результаты обработки двух кастомных матриц. А кастомные матрицы - это разделённые Model и View, только я их для различия назвал ObjectVolatile и CameraVolatile соответственно. Разделение позволяет независимо преобразовывать координаты модели и координаты камеры - К.О. Плюс для быстрого сброса я добавил ещё две матрицы: ObjectDefault и CameraDefault. Их я сразу проинициализировал в сегменте .code значениями, которые подбирал весь предыдущий год. Вот так мы ходим на SSE (матрица Camera): Спойлер: Перенос со сменой базиса Код (ASM): ;dx_local = dStep * mtxCameraVolatile(0i) ;dy_local = dStep * mtxCameraVolatile(1i) ;dz_local = dStep * mtxCameraVolatile(2i) mulss xmm0,dword ptr[eax+0*4] mulss xmm1,dword ptr[eax+4*4] mulss xmm2,dword ptr[eax+8*4] ;Fill all 4 xmm lanes shufps xmm0,xmm0,0 ;dx_local shufps xmm1,xmm1,0 ;dy_local shufps xmm2,xmm2,0 ;dz_local ;Accumulate world-space displacement ;dx contributes to world via column 0 ;dy contributes to world via column 1 ;dz contributes to world via column 2 ;dx_world = dx_local*m[00] + dy_local*m[04] + dz_local*m[08] ;dy_world = dx_local*m[01] + dy_local*m[05] + dz_local*m[09] ;dz_world = dx_local*m[02] + dy_local*m[06] + dz_local*m[10] movaps xmm3,oword ptr[ecx+0*4] ;old[00..03] movaps xmm4,oword ptr[ecx+4*4] ;old[04..07] movaps xmm5,oword ptr[ecx+8*4] ;old[08..11] mulps xmm0,xmm3 mulps xmm1,xmm4 mulps xmm2,xmm5 addps xmm0,xmm1 addps xmm0,xmm2 ;Add to the Translation Column ;x_world = x_world + dx_world ;y_world = y_world + dy_world ;z_world = z_world + dz_world movaps xmm6,oword ptr[ecx+12*4] ;old[12..15] addps xmm0,xmm6 Вот так мы поворачиваем модель на SSE (матрица Object): Спойлер: Поворот в другом базисе Код (ASM): Rx: ;1 0 0 0 ;0 cos -sin 0 ;0 sin cos 0 ;0 0 0 1 ;Load Values movaps xmm2,oword ptr[ecx+4*4] ;old[04..07] movaps xmm3,oword ptr[ecx+8*4] ;old[08..11] movaps xmm4,xmm2 ;old[04..07] movaps xmm5,xmm3 ;old[08..11] ;new[04] = c * old[04] + s * old[08] ;new[05] = c * old[05] + s * old[09] ;new[06] = c * old[06] + s * old[10] ;new[07] = c * old[07] + s * old[11] mulps xmm2,xmm1 ;old[04..07]*cos mulps xmm3,xmm0 ;old[08..11]*sin addps xmm2,xmm3 movaps oword ptr[ecx+4*4],xmm2 ;new[04..07] ;new[08] = c * old[08] - s * old[04] ;new[09] = c * old[09] - s * old[05] ;new[10] = c * old[10] - s * old[06] ;new[11] = c * old[11] - s * old[07] mulps xmm5,xmm1 ;old[08..11]*cos mulps xmm4,xmm0 ;old[04..07]*sin subps xmm5,xmm4 movaps oword ptr[ecx+8*4],xmm5 ;new[08..11] jmp ModelRotate_End Ry: ; cos 0 sin 0 ; 0 1 0 0 ;-sin 0 cos 0 ; 0 0 0 1 ;Load Values movaps xmm2,oword ptr[ecx+0*4] ;old[00..03] movaps xmm3,oword ptr[ecx+8*4] ;old[08..11] movaps xmm4,xmm2 ;old[00..03] movaps xmm5,xmm3 ;old[08..11] ;new[00] = c * old[00] - s * old[08] ;new[01] = c * old[01] - s * old[09] ;new[02] = c * old[02] - s * old[10] ;new[03] = c * old[03] - s * old[11] mulps xmm2,xmm1 ;old[00..03]*cos mulps xmm3,xmm0 ;old[08..11]*sin subps xmm2,xmm3 movaps oword ptr[ecx+0*4],xmm2 ;new[00..03] ;new[08] = s * old[00] + c * old[08] ;new[09] = s * old[01] + c * old[09] ;new[10] = s * old[02] + c * old[10] ;new[11] = s * old[03] + c * old[11] mulps xmm4,xmm0 ;old[00..03]*sin mulps xmm5,xmm1 ;old[08..11]*cos addps xmm4,xmm5 movaps oword ptr[ecx+8*4],xmm4 ;new[08..11] jmp ModelRotate_End Rz: ;cos -sin 0 0 ;sin cos 0 0 ; 0 0 1 0 ; 0 0 0 1 ;Load Values movaps xmm2,oword ptr[ecx+0*4] ;old[00..03] movaps xmm3,oword ptr[ecx+4*4] ;old[04..07] movaps xmm4,xmm2 ;old[00..03] movaps xmm5,xmm3 ;old[04..07] ;new[00] = c * old[00] + s * old[04] ;new[01] = c * old[01] + s * old[05] ;new[02] = c * old[02] + s * old[06] ;new[03] = c * old[03] + s * old[07] mulps xmm2,xmm1 ;old[00..03]*cos mulps xmm3,xmm0 ;old[04..07]*sin addps xmm2,xmm3 movaps oword ptr[ecx+0*4],xmm2 ;new[00..03] ;new[04] = c * old[04] - s * old[00] ;new[05] = c * old[05] - s * old[01] ;new[06] = c * old[06] - s * old[02] ;new[07] = c * old[07] - s * old[03] mulps xmm4,xmm0 ;old[00..03]*sin mulps xmm5,xmm1 ;old[04..07]*cos subps xmm5,xmm4 movaps oword ptr[ecx+4*4],xmm5 ;new[04..07] Управление WSAD (поворот модели) + стрелки, PgUp, PgDn (движение камеры) + shift (ускорение)
ml64, спасибо вам от всех любителей ассемблеров ! :=) К сожалению, ваш EXE-файл у меня выдаёт не то, что нужно, а сам я пока не компилировал, нужно будет MASM32 на досуге установить.
Так это и есть то, что нужно! Там просто болванка - белый прямоугольник, на нём можно проверить работу всех матриц. Я же говорю: будет парсер - будет графика, а сейчас пока красоту надо искать в чистоте решений. Это же поэзия: Код (ASM): ;2.1. Activate the ModelView Matrix push 1700h ;GL_MODELVIEW call glMatrixMode ;2.2. Load the current Camera matrix push offset mtxCameraVolatile call glLoadMatrixf ;2.3. Multiply by the current Object matrix push offset mtxObjectVolatile call glMultMatrixf Вместо всех конских преобразований в матрицах Projection и ModelView ...Для того, чтобы повернуть матрицу в другом базисе, нужно всего лишь 12 инструкций. А на современных процессорах - ещё меньше
- А, понятно. - А у вас нет такого-же, но с парсером, без крыльев и с перламутровыми пуговицами? - Нет, да. Ну, будем искать. Будем искать.