⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 3d 映射原理 .txt

📁 会变语言实现的一些程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:
                mov   eax,Move1X
                mov   ebx,Move1Y
                sub   eax,MoveX
                sub   ebx,MoveY
                mov   ls,eax
                mov   ls1,ebx
                finit
                ;------------------
                ;屏幕x轴参考向量改变角度等于lsrad
                ;rad是改变快慢的系数
                fild   ls
                fld   rad
                fdiv
                ;------------------
                fsincos
                fld   dword ptr VectorU
                fld   dword ptr VectorU+4
                fld   dword ptr VectorU+8
                fmul   st(0),st(3)
                fstp   dword ptr VectorA+8
                fmul   st(0),st(2)
                fstp   dword ptr VectorA+4
                fmul
                fstp   dword ptr VectorA
                fld   dword ptr VectorR
                fld   dword ptr VectorR+4
                fld   dword ptr VectorR+8
                fmul   st(0),st(3)
                fstp   dword ptr VectorB+8
                fmul   st(0),st(2)
                fstp   dword ptr VectorB+4
                fmul
                fstp   dword ptr VectorB
                movaps   XMM0,VectorA
                addps   XMM0,VectorB
                movaps   VectorU,XMM0
                ;屏幕x轴改变方向
                invoke   VecMul,addr VectorU,addr VectorV,addr VectorR
;屏幕x轴改变方向后要立即重新计算屏幕法向量
                finit
                fild   ls1
                fld   rad
                fdiv
                fsincos
                fld   dword ptr VectorV
                fld   dword ptr VectorV+4
                fld   dword ptr VectorV+8
                fmul   st(0),st(3)
                fstp   dword ptr VectorA+8
                fmul   st(0),st(2)
                fstp   dword ptr VectorA+4
                fmul
                fstp   dword ptr VectorA
                fld   dword ptr VectorR
                fld   dword ptr VectorR+4
                fld   dword ptr VectorR+8
                fmul   st(0),st(3)
                fstp   dword ptr VectorB+8
                fmul   st(0),st(2)
                fstp   dword ptr VectorB+4
                fmul
                fstp   dword ptr VectorB
                movaps   XMM0,VectorA
                addps   XMM0,VectorB
                movaps   VectorV,XMM0
                ;屏幕y轴改变方向
                invoke   VecMul,addr VectorU,addr VectorV,addr VectorR
;屏幕y轴改变方向后要立即重新计算屏幕法向量
                ret
rad             dd      100.0
Circumgyrate   endp
_ProcWinMain   proc   uses ebx edi esi hWnd,uMsg,wParam,lParam
                local   ls
                local   ls1
                local   ls2
                mov   eax,uMsg
                .if   eax ==   WM_TIMER
                push   y
                mov   ebx,100
                lp
                push   ebx
                push   x
                mov   ecx,100
                @@
                push   ecx
;===================================================================
;核心代码段,原理在上面的理论分析中已经讲了
                invoke   Function,addr x;计算函数的z轴坐标
                invoke   VecMul,addr x,addr VectorR,addr VectorL
                ;计算原点到函数点所够成的向量与屏幕法向量的法向量
                invoke   VecMul,addr VectorL,addr VectorR,addr VectorT
                ;计算上面得出向量与屏幕法向量的法向量
                ;此向量落在屏幕上,与屏幕法向量,原点到函数点所够成
                ;向量是共面的
                invoke   Projection,addr x,addr VectorT,addr VectorT 
                ;求原点到函数点所够成向量在屏幕上的投影向量,
                ;此向量是三维向量,不是我们要的二维向量。
invoke   VectorAbs,addr VectorT
;计算投影向量的模长
                mov   ls,eax
                invoke   IntstAngle,addr VectorT,addr VectorU
                ;计算投影向量与屏幕x轴参考向量的夹角余弦值
                mov   ls1,eax
                invoke   IntstAngle,addr VectorT,addr VectorV
                ;计算投影向量与屏幕y轴参考向量的夹角余弦值
                mov   ls2,eax
                finit
                fld   ls
                fld   ls1
                fld   ls
                fld   ls2
                fmul
                fistp   ls2
                fmul
                fistp   ls1
                add   ls2,300;加上y轴偏移值,因为屏幕是不显示负坐标的
                add   ls1,300;加上x轴偏移值
                ;此时ls1是屏幕x轴坐标,ls2是屏幕y轴坐标
                invoke   SetBmpPixel,lpBmp,ls1,ls2
;把计算好的象素坐标设置到32bit位图中
;===================================================================
                finit
                fld   x
                fadd   add2
                fst   x
                pop   ecx
                dec   ecx
                jnz   @b
                pop   x
                finit
                fld   y
                fadd   add2
                fst   y
                pop   ebx
                dec   ebx
                jnz   lp
                pop   y
                ;----------------------------------
                mov   edi,lpBmp
                mov   ecx,lpBmp
                mov   edx,lpBmp
                add   ecx,40
                invoke   SetDIBitsToDevice,hdc,0,0,dword ptr[edi+4],
                   dword ptr[edi+8],0,0,0,   dword ptr[edi+8],
                   ecx,edx,DIB_RGB_COLORS;绘制处理好的图象
                mov   edi,lpBmp
                mov   ecx,600600
                mov   eax,-1
                add   edi,40
                rep   stosd;把位图涂成白色
      .elseif   eax ==   WM_MOUSEMOVE
                cmp   DownJh,0;当鼠标左键按下时允许变换图象
                jz   @f
                mov   eax,lParam
                mov   edx,lParam
                and   eax,0ffffh
                shr   edx,16
                mov   MoveX,eax
                mov   MoveY,edx
                push   eax
                push   edx
                invoke   Circumgyrate
;变换屏幕所在平面的坐标从而使图象变换
                pop   Move1Y
                pop   Move1X
                @@
      .elseif   eax ==   WM_LBUTTONDOWN
                invoke   SetTimer,hWnd,1,1,0;设置最快的速度刷新屏幕图象
                mov   DownJh,1;当鼠标左键按下时设置允许变换图象标记
                mov   eax,lParam
                mov   edx,lParam
                and   eax,0ffffh
                shr   edx,16
                mov   Move1X,eax
                mov   Move1Y,edx
      .elseif   eax ==   WM_LBUTTONUP
                invoke   KillTimer,hWnd,1;停止刷新屏幕图象
                mov   DownJh,0;当鼠标左键弹起时设置不允许变换图象标记
      .elseif   eax ==   WM_NCMOUSEMOVE
                invoke   KillTimer,hWnd,1;停止刷新屏幕图象
                mov   DownJh,0;当鼠标指针移到边框时设置不允许变换图象标记
      .elseif   eax ==   WM_CREATE
                invoke   VecMul,addr VectorU,addr VectorV,addr VectorR
;计算屏幕法向量
;在映射时这个向量非常重要
                invoke   SetTimer,hWnd,1,1,0
                invoke   GetDC,hWnd
                mov   hdc,eax
      .elseif   eax ==   WM_CLOSE
                invoke   DestroyWindow,hWinMain
                invoke   PostQuitMessage,NULL
      .else
                invoke   DefWindowProc,hWnd,uMsg,wParam,lParam
                ret
      .endif
      xor   eax,eax
      ret
_ProcWinMain   endp
_WinMain   proc
      local   @stWndClassWNDCLASSEX
      local   @stMsgMSG
      invoke   GetModuleHandle,NULL
      mov   hInstance,eax
      invoke   RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
      invoke   LoadCursor,0,IDC_ARROW
      mov   @stWndClass.hCursor,eax
      push   hInstance
      pop   @stWndClass.hInstance
      mov   @stWndClass.cbSize,sizeof WNDCLASSEX
      mov   @stWndClass.style,CS_HREDRAW or CS_VREDRAW
      mov   @stWndClass.lpfnWndProc,offset _ProcWinMain
      mov   @stWndClass.hbrBackground,COLOR_WINDOW + 1
      mov   @stWndClass.lpszClassName,offset szClassName
      invoke   RegisterClassEx,addr @stWndClass
      invoke   CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,
                WS_SYSMENU,
                0,0,625,650,
                NULL,NULL,hInstance,NULL
      mov   hWinMain,eax
      invoke   ShowWindow,hWinMain,SW_SHOWNORMAL
      invoke   UpdateWindow,hWinMain
      .while   TRUE
                invoke   GetMessage,addr @stMsg,NULL,0,0
                .break   .if eax   == 0
                invoke   TranslateMessage,addr @stMsg
                invoke   DispatchMessage,addr @stMsg
      .endw
      ret
_WinMain   endp
start
      invoke   GlobalAlloc,0,4600600+40;为600600分辨率的32bit位图分配内存空间
      ;一般情况下存储的是24bit位图,所谓的32bit位图只有低24bit是有用的,
      ;用32bit是为了与内存4BYTE对齐,加快处理速度。
      mov   lpBmp,eax
      mov   edi,eax
      mov   dword ptr[edi],40;头文件大小
      mov   dword ptr[edi+4],600;水平分辨率
      mov   dword ptr[edi+8],600;垂直分辨率
      mov   dword ptr[edi+12],200001h;设置平面数为1,20h(32)bit的位图
      mov   ecx,600600
      mov   eax,-1;白色
      add   edi,40
      rep   stosd;把位图涂成白色
      call   _WinMain
      invoke   GlobalFree,lpBmp;释放位图空间
      invoke   ExitProcess,NULL
      end   start 

    看到这里,你一定迫不及待想要看到结果了吧~ 使用MasmPlus 可以很容易帮助你编译。不过需要做一点点修改:

    在MASMPLUS的安装目录下找到 IDE.INI ,在段[ASM]中修改下面的语句:
    #Compiler=ml.exe $(CParam) Fo$(FileName).obj $(FileDir)$(FileName).$(FileExt)

    修改为
    #Compiler=ml615.exe $(CParam) Fo$(FileName).obj $(FileDir)$(FileName).$(FileExt)

    当然还要在MASMPlusBin 中放一个 ml615.exe

    之后使用 新建 Win32 EXE 模板,新建一个EXE工程,用上面的代码取代模板中的就可以了。

    另外,还可以尝试编写自己的函数,比如下面的函数

Function        proc  lpVector
;          _______ 
;f(x,y)=(√x^2+y^2)20
                mov   edi,lpVector
                finit
                fld   _10
                fld   dword ptr[edi+4]
                fld   dword ptr[edi]
                fmul   st,st
                fxch
                fmul   st,st
                fadd
                fdiv   DWORD PTR [_10]
                fst   dword ptr[edi+8]
                ret
_10             dd   20.0
Function        endp 


--------------------------------------------------------------------------------
上一篇  欢迎访问AoGo汇编小站httpwww.aogosoft.com 下一篇  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -