From 40df1da8cf49723c0983421401eb21fac7a50b1f Mon Sep 17 00:00:00 2001 From: IgorA Date: Mon, 22 Dec 2014 09:21:22 +0000 Subject: [PATCH] some fixes git-svn-id: svn://kolibrios.org@5256 a494cfbc-eb01-0410-851d-a64ba20cac60 --- .../TinyGL/asm_fork/examples/test_glu1.asm | 230 ++++++ .../libraries/TinyGL/asm_fork/light.asm | 731 +++++++++++++----- .../libraries/TinyGL/asm_fork/misc.asm | 15 +- .../libraries/TinyGL/asm_fork/specbuf.asm | 111 +++ .../libraries/TinyGL/asm_fork/tinygl.asm | 1 + .../libraries/TinyGL/asm_fork/vertex.asm | 21 +- .../develop/libraries/TinyGL/asm_fork/zgl.inc | 5 + .../libraries/TinyGL/asm_fork/zmath.asm | 306 ++++++-- 8 files changed, 1151 insertions(+), 269 deletions(-) create mode 100644 programs/develop/libraries/TinyGL/asm_fork/examples/test_glu1.asm create mode 100644 programs/develop/libraries/TinyGL/asm_fork/specbuf.asm diff --git a/programs/develop/libraries/TinyGL/asm_fork/examples/test_glu1.asm b/programs/develop/libraries/TinyGL/asm_fork/examples/test_glu1.asm new file mode 100644 index 0000000000..96252f65b6 --- /dev/null +++ b/programs/develop/libraries/TinyGL/asm_fork/examples/test_glu1.asm @@ -0,0 +1,230 @@ +use32 + org 0x0 + db 'MENUET01' + dd 0x1 + dd start + dd i_end + dd mem,stacktop + dd 0,cur_dir_path + +include '../../../../../../programs/proc32.inc' +include '../../../../../../programs/macros.inc' +include '../../../../../../programs/develop/libraries/box_lib/load_lib.mac' +include '../../../../../../programs/dll.inc' +include '../opengl_const.inc' + +@use_library + +align 4 +start: + load_library name_tgl, cur_dir_path, library_path, system_path, \ + err_message_found_lib, head_f_l, import_lib_tinygl, err_message_import, head_f_i + cmp eax,-1 + jz button.exit + + mcall 40,0x27 + +stdcall [kosglMakeCurrent], 10,10,300,225,ctx1 +stdcall [glEnable], GL_DEPTH_TEST +stdcall [gluNewQuadric] +mov [qObj],eax + +stdcall [glClearColor], 0.5,0.5,0.5,0.0 +stdcall [glShadeModel], GL_SMOOTH + +call draw_3d + +align 4 +red_win: + call draw_window + +align 4 +still: + mcall 10 + cmp al,1 + jz red_win + cmp al,2 + jz key + cmp al,3 + jz button + jmp still + +align 4 +draw_window: + pushad + mcall 12,1 + + mov edx,0x33ffffff ;0x73ffffff + mcall 0,(50 shl 16)+330,(30 shl 16)+275,,,caption + stdcall [kosglSwapBuffers] + + mcall 12,2 + popad + ret + +align 4 +key: + mcall 2 + + cmp ah,27 ;Esc + je button.exit + + cmp ah,61 ;+ + jne @f + fld dword[scale] + fadd dword[delt_sc] + fstp dword[scale] + call draw_3d + stdcall [kosglSwapBuffers] + @@: + cmp ah,45 ;- + jne @f + fld dword[scale] + fsub dword[delt_sc] + fstp dword[scale] + call draw_3d + stdcall [kosglSwapBuffers] + @@: + cmp ah,178 ;Up + jne @f + fld dword[angle_y] + fadd dword[delt_size] + fstp dword[angle_y] + call draw_3d + stdcall [kosglSwapBuffers] + @@: + cmp ah,177 ;Down + jne @f + fld dword[angle_y] + fsub dword[delt_size] + fstp dword[angle_y] + call draw_3d + stdcall [kosglSwapBuffers] + @@: + cmp ah,176 ;Left + jne @f + fld dword[angle_z] + fadd dword[delt_size] + fstp dword[angle_z] + call draw_3d + stdcall [kosglSwapBuffers] + @@: + cmp ah,179 ;Right + jne @f + fld dword[angle_z] + fsub dword[delt_size] + fstp dword[angle_z] + call draw_3d + stdcall [kosglSwapBuffers] + @@: + + jmp still + +align 4 +button: + mcall 17 + cmp ah,1 + jne still +.exit: + stdcall [gluDeleteQuadric], [qObj] + mcall -1 + + +align 4 +caption db 'Test gluSphere, [Esc] - exit, [<-],[->],[Up],[Down] - rotate',0 +align 4 +ctx1 db 28 dup (0) ;TinyGLContext or KOSGLContext +;sizeof.TinyGLContext = 28 + +align 4 +draw_3d: +stdcall [glClear], GL_COLOR_BUFFER_BIT + GL_DEPTH_BUFFER_BIT ;очистим буфер цвета и глубины + +stdcall [glColor3f], 1.0, 1.0, 0.0 + +stdcall [glPushMatrix] + call SetLight + + stdcall [glTranslatef], 0.0,0.0,0.5 + stdcall [glScalef], [scale], [scale], [scale] + + stdcall [glRotatef], [angle_z],0.0,0.0,1.0 + stdcall [glRotatef], [angle_y],0.0,1.0,0.0 + stdcall [gluSphere], [qObj], 1.0, 16,16 + + stdcall [glColor3f], 1.0, 0.0, 0.0 + stdcall [glTranslatef], -1.6,0.0,0.0 + stdcall [gluSphere], [qObj], 0.55, 8,8 + + stdcall [glColor3f], 0.0, 0.0, 1.0 + stdcall [glTranslatef], 3.2,0.0,0.0 + stdcall [gluSphere], [qObj], 0.55, 8,8 +stdcall [glPopMatrix] +ret + +align 4 +SetLight: + stdcall [glLightfv], GL_LIGHT0, GL_POSITION, light_position + stdcall [glLightfv], GL_LIGHT0, GL_SPOT_DIRECTION, light_dir + + stdcall [glLightfv], GL_LIGHT0, GL_DIFFUSE, white_light + stdcall [glLightfv], GL_LIGHT0, GL_SPECULAR, white_light + + stdcall [glEnable], GL_COLOR_MATERIAL + stdcall [glColorMaterial], GL_FRONT, GL_AMBIENT_AND_DIFFUSE + stdcall [glMaterialfv], GL_FRONT, GL_SPECULAR, mat_specular + stdcall [glMaterialf], GL_FRONT, GL_SHININESS, mat_shininess + stdcall [glLightModelfv], GL_LIGHT_MODEL_AMBIENT, lmodel_ambient + + stdcall [glEnable],GL_LIGHTING + stdcall [glEnable],GL_LIGHT0 +ret + +qObj dd 0 + +scale dd 0.4 +delt_sc dd 0.05 +angle_z dd 0.0 +angle_y dd 0.0 +delt_size dd 3.0 + +light_position dd 0.0, 0.0, 2.0, 1000.0 ; Расположение источника [0][1][2], чем ближе [3] к 0, тем ярче свет +light_dir dd 0.0,0.0,0.0 ;направление лампы +mat_specular dd 0.3, 0.3, 0.3, 1.0 ; Цвет блика +mat_shininess dd 3.0 ; Размер блика (обратная пропорция) +white_light dd 0.8, 0.8, 0.8, 1.0 ; Цвет и интенсивность освещения, генерируемого источником +lmodel_ambient dd 0.2, 0.2, 0.2, 1.0 ; Параметры фонового освещения + +;-------------------------------------------------- +align 4 +import_lib_tinygl: + +macro E_LIB n +{ + n dd sz_#n +} +include '../export.inc' + dd 0,0 +macro E_LIB n +{ + sz_#n db `n,0 +} +include '../export.inc' + +;-------------------------------------------------- +system_path db '/sys/lib/' +name_tgl db 'tinygl.obj',0 +err_message_found_lib db 'Sorry I cannot load library tinygl.obj',0 +head_f_i: +head_f_l db 'System error',0 +err_message_import db 'Error on load import library tinygl.obj',0 +;-------------------------------------------------- + +i_end: + rb 1024 +stacktop: +cur_dir_path: + rb 4096 +library_path: + rb 4096 +mem: diff --git a/programs/develop/libraries/TinyGL/asm_fork/light.asm b/programs/develop/libraries/TinyGL/asm_fork/light.asm index 546bcd0307..a0517006f2 100644 --- a/programs/develop/libraries/TinyGL/asm_fork/light.asm +++ b/programs/develop/libraries/TinyGL/asm_fork/light.asm @@ -1,51 +1,76 @@ -;include 'msghandling.inc' align 4 -proc glopMaterial, context:dword, p:dword -; int mode=p[1].i; -; int type=p[2].i; -; float *v=&p[3].f; -; int i; -; GLMaterial *m; +proc glopMaterial uses eax ebx ecx edi esi, context:dword, p:dword +; edi -> GLMaterial *m + mov eax,[context] + mov ebx,[p] + mov ecx,[ebx+4] ;ecx = p[1] -; if (mode == GL_FRONT_AND_BACK) { -; p[1].i=GL_FRONT; -; glopMaterial(c,p); -; mode=GL_BACK; -; } -; if (mode == GL_FRONT) m=&c->materials[0]; -; else m=&c->materials[1]; + cmp ecx,GL_FRONT_AND_BACK ;if (mode == GL_FRONT_AND_BACK) + jne @f + mov dword[ebx+4],GL_FRONT ;p[1].i=GL_FRONT + mov edi,ebp + add edi,12 + stdcall glopMaterial,eax,edi + mov ecx,GL_BACK + @@: + mov edi,[eax+offs_cont_materials] + cmp ecx,GL_FRONT ;if (mode == GL_FRONT) m=&context.materials[0] + je @f + add edi,sizeof.GLMaterial ;else m=&context.materials[1] + @@: -; switch(type) { -; case GL_EMISSION: -; for(i=0;i<4;i++) -; m->emission.v[i]=v[i]; -; break; -; case GL_AMBIENT: -; for(i=0;i<4;i++) -; m->ambient.v[i]=v[i]; -; break; -; case GL_DIFFUSE: -; for(i=0;i<4;i++) -; m->diffuse.v[i]=v[i]; -; break; -; case GL_SPECULAR: -; for(i=0;i<4;i++) -; m->specular.v[i]=v[i]; -; break; -; case GL_SHININESS: -; m->shininess=v[0]; -; m->shininess_i = (v[0]/128.0f)*SPECULAR_BUFFER_RESOLUTION; -; break; -; case GL_AMBIENT_AND_DIFFUSE: -; for(i=0;i<4;i++) -; m->diffuse.v[i]=v[i]; -; for(i=0;i<4;i++) -; m->ambient.v[i]=v[i]; -; break; -; default: + mov ecx,4 + mov esi,ebx ;esi = &p + add esi,12 ;esi = &p[3] + mov ebx,[ebx+8] ;ebx = p[2] + cmp ebx,GL_EMISSION + jne @f + ;add edi,offs_mate_emission ;offs_mate_emission=0 + rep movsd + jmp .end_f + @@: + cmp ebx,GL_AMBIENT + jne @f + add edi,offs_mate_ambient + rep movsd + jmp .end_f + @@: + cmp ebx,GL_DIFFUSE + jne @f + add edi,offs_mate_diffuse + rep movsd + jmp .end_f + @@: + cmp ebx,GL_SPECULAR + jne @f + add edi,offs_mate_specular + rep movsd + jmp .end_f + @@: + cmp ebx,GL_SHININESS + jne @f + fld dword[esi] + add edi,offs_mate_shininess + movsd + mov dword[edi],SPECULAR_BUFFER_RESOLUTION + fdiv dword[an180f] + fimul dword[edi] + fistp dword[edi] ;m.shininess_i = (v[0]/128.0f)*SPECULAR_BUFFER_RESOLUTION + jmp .end_f + @@: + cmp ebx,GL_AMBIENT_AND_DIFFUSE + jne @f + add edi,offs_mate_ambient + rep movsd + sub esi,16 + ;edi = &offs_mate_diffuse + mov ecx,4 + rep movsd + jmp .end_f + @@: ;default ; assert(0); -; } + .end_f: ret endp @@ -61,13 +86,15 @@ proc glopColorMaterial uses eax ebx ecx, context:dword, p:dword endp align 4 -proc glopLight uses eax ebx ecx edx, context:dword, p:dword +proc glopLight context:dword, p:dword +locals + pos V4 +endl +pushad mov eax,[context] mov ebx,[p] mov edx,[ebx+4] ;edx = p[1] -; V4 v; - ; assert(edx >= GL_LIGHT0 && edx < GL_LIGHT0+MAX_LIGHTS ); sub edx,GL_LIGHT0 @@ -108,26 +135,40 @@ proc glopLight uses eax ebx ecx edx, context:dword, p:dword @@: cmp ecx,GL_POSITION jne @f -; { -; for(i=0;i<4;i++) v.v[i]=p[3+i].f; -; V4 pos; -; gl_M4_MulV4(&pos,c->matrix_stack_ptr[0],&v); -; -; l->position=pos; -; -; if (l->position.v[3] == 0) { -; l->norm_position.X=pos.X; -; l->norm_position.Y=pos.Y; -; l->norm_position.Z=pos.Z; -; -; gl_V3_Norm(&l->norm_position); -; } -; } + mov edi,ebx ;ebx = [ebp+12] = [p] = &p[0] + add edi,12 ;&p[3] + mov esi,ebp + sub esi,16 ;&pos + stdcall gl_M4_MulV4, esi,dword[eax+offs_cont_matrix_stack_ptr],edi + mov edi,edx + add edi,offs_ligh_position + mov ecx,4 + rep movsd ;l.position=pos + + fld dword[edi-4] ;if(l.position.v[3] == 0) + ftst + fstsw ax + sahf + jne .end_i + ;mov esi,ebp + sub esi,16 ;&pos + mov edi,edx + add edi,offs_ligh_norm_position + mov ecx,3 + rep movsd ;l.norm_position=pos[1,2,3] + + ;mov edi,edx + ;add edi,offs_ligh_norm_position + sub edi,12 + stdcall gl_V3_Norm,edi ;&l.norm_position + .end_i: + ffree st0 + fincstp jmp .end_f @@: cmp ecx,GL_SPOT_DIRECTION jne @f - mov esi,ebx + mov esi,ebx ;&p[0] add esi,12 mov edi,edx add edi,offs_ligh_spot_direction @@ -150,15 +191,25 @@ proc glopLight uses eax ebx ecx edx, context:dword, p:dword jmp .end_f @@: cmp ecx,GL_SPOT_CUTOFF - jne @f -; { -; float a=v.v[0]; + jne .end_spot_c + fld dword[ebp+12] ;float a=v.v[0] ; assert(a == 180 || (a>=0 && a<=90)); -; l->spot_cutoff=a; -; if (a != 180) l->cos_spot_cutoff=cos(a * M_PI / 180.0); -; } + fst dword[edi+offs_ligh_spot_cutoff] ;l.spot_cutoff=a + fcom dword[an180f] ;if (a != 180) + fstsw ax + sahf + jne @f + fldpi + fmulp + fdiv dword[an180f] + fcos + fstp dword[edi+offs_ligh_spot_cutoff] ;l.cos_spot_cutoff=cos(a * M_PI / 180.0) + jmp .end_f + @@: + ffree st0 + fincstp jmp .end_f - @@: + .end_spot_c: cmp ecx,GL_CONSTANT_ATTENUATION mov ecx,[ebx+12] mov [edi+offs_ligh_attenuation],ecx ;l->attenuation[0]=p[3] @@ -176,6 +227,7 @@ proc glopLight uses eax ebx ecx edx, context:dword, p:dword @@: ;default: ; assert(0); .end_f: +popad ret endp @@ -184,46 +236,69 @@ align 4 proc glopLightModel uses ebx ecx esi edi, context:dword, p:dword mov edi,[context] mov ebx,[p] - mov esi,[ebx+8] + mov ebx,[ebx+4] + mov esi,[ebp+12] ;&p[0] + add esi,8 ;&p[2] - cmp dword[ebx+4],GL_LIGHT_MODEL_AMBIENT + cmp ebx,GL_LIGHT_MODEL_AMBIENT jne @f mov ecx,4 - mov edi,dword[edi+offs_cont_ambient_light_model] + add edi,offs_cont_ambient_light_model rep movsd ;for(i=0;i<4;i++) context.ambient_light_model.v[i]=v[i] jmp .end_f @@: - cmp dword[ebx+4],GL_LIGHT_MODEL_LOCAL_VIEWER + cmp ebx,GL_LIGHT_MODEL_LOCAL_VIEWER jne @f - fld dword[esi] ;st0 = p[2].v[0] + fld dword[esi] ;st0 = p[2] fistp dword[edi+offs_cont_local_light_model] jmp .end_f @@: - cmp dword[ebx+4],GL_LIGHT_MODEL_TWO_SIDE + cmp ebx,GL_LIGHT_MODEL_TWO_SIDE jne @f - fld dword[esi] ;st0 = p[2].v[0] + fld dword[esi] ;st0 = p[2] fistp dword[edi+offs_cont_light_model_two_side] jmp .end_f @@: ;default: -; tgl_warning("glopLightModel: illegal pname: 0x%x\n", dword[ebx+4]); +; tgl_warning("glopLightModel: illegal pname: 0x%x\n", ebx); ; //assert(0); .end_f: ret endp -;static inline float clampf(float a,float min,float max) -;{ -; if (amax) return max; -; else return a; -;} +macro clampf a, min, max +{ +local .o_1 +local .o_2 +local .end_m + fld dword a ;if (a<=0.0) + ftst + fstsw ax + sahf + ja .o_1 + ffree st0 + fincstp + mov eax,0.0 + jmp .end_m ;return 0.0 + .o_1: + fld1 ;else if (a>=1.0) + fcompp + fstsw ax + sahf + jb .o_2 + mov eax,1.0 + jmp .end_m ;return 1.0 + .o_2: + mov eax,dword a ;else return a + .end_m: +} align 4 proc gl_enable_disable_light uses eax ebx ecx, context:dword, light:dword, v:dword mov eax,[context] mov ebx,[light] imul ebx,sizeof.GLLight - add ebx,[eax+offs_cont_lights] + add ebx,eax + add ebx,offs_cont_lights xor ecx,ecx cmp dword[ebx+offs_ligh_enabled],0 @@ -231,8 +306,8 @@ proc gl_enable_disable_light uses eax ebx ecx, context:dword, light:dword, v:dwo not ecx @@: and ecx,[v] - cmp ecx,0 - je @f + or ecx,ecx + jz @f ;if (v && !l.enabled) mov dword[ebx+offs_ligh_enabled],1 mov ecx,[eax+offs_cont_first_light] @@ -247,8 +322,8 @@ proc gl_enable_disable_light uses eax ebx ecx, context:dword, light:dword, v:dwo not ecx @@: and ecx,[ebx+offs_ligh_enabled] - cmp ecx,0 - je .end_f + or ecx,ecx + jz .end_f ;else if (!v && l.enabled) mov dword[ebx+offs_ligh_enabled],0 ;l.enabled = 0 mov ecx,[ebx+offs_ligh_next] @@ -269,130 +344,388 @@ proc gl_enable_disable_light uses eax ebx ecx, context:dword, light:dword, v:dwo ret endp +align 4 +fl_1e_3 dd 1.0e-3 + ; non optimized lightening model align 4 proc gl_shade_vertex, context:dword, v:dword +locals + R dd ? ;float + G dd ? ;float + B dd ? ;float + A dd ? ;float + s V3 + d V3 + dist dd ? ;float + tmp dd ? ;float + att dd ? ;float + dot_spot dd ? ;float + lR dd ? ;float + lB dd ? ;float + lG dd ? ;float + twoside dd ? ;int + idx dd ? ;int + n V3 ;ebp-24 + vcoord V3 ;ebp-12 +endl +pushad +; ebx -> GLLight *l +; ecx -> GLMaterial *m +; esi -> GLVertex *v + mov esi,[v] + mov edx,[context] + mov ecx,[edx+offs_cont_materials] ;ecx(m) = &context.materials[0] + mov eax,[edx+offs_cont_light_model_two_side] + mov [twoside],eax -; float R,G,B,A; -; GLMaterial *m; -; GLLight *l; -; V3 n,s,d; -; float dist,tmp,att,dot,dot_spot,dot_spec; -; int twoside = c->light_model_two_side; + add esi,offs_vert_normal + mov edi,ebp + sub edi,24 ;edi = &n + movsd ;n.X=v.normal.X + movsd ;n.Y=v.normal.Y + movsd ;n.Z=v.normal.Z + mov esi,[v] -; m=&c->materials[0]; + fld dword[edx+offs_cont_ambient_light_model] + fmul dword[ecx+offs_mate_ambient] + fadd dword[ecx] ;offs_mate_emission=0 + fstp dword[R] ;R=m.emission.v[0]+m.ambient.v[0]*context.ambient_light_model.v[0] + fld dword[edx+offs_cont_ambient_light_model+4] + fmul dword[ecx+offs_mate_ambient+4] + fadd dword[ecx+offs_mate_emission+4] + fstp dword[G] + fld dword[edx+offs_cont_ambient_light_model+8] + fmul dword[ecx+offs_mate_ambient+8] + fadd dword[ecx+offs_mate_emission+8] + fstp dword[B] + clampf [ecx+offs_mate_diffuse+12],0,1 + mov [A],eax ;A=clampf(m.diffuse.v[3],0,1) -; n.X=v->normal.X; -; n.Y=v->normal.Y; -; n.Z=v->normal.Z; + mov ebx,[edx+offs_cont_first_light] + .cycle_0: ;for(l=context.first_light;l!=NULL;l=l.next) + or ebx,ebx + jz .cycle_0_end -; R=m->emission.v[0]+m->ambient.v[0]*c->ambient_light_model.v[0]; -; G=m->emission.v[1]+m->ambient.v[1]*c->ambient_light_model.v[1]; -; B=m->emission.v[2]+m->ambient.v[2]*c->ambient_light_model.v[2]; -; A=clampf(m->diffuse.v[3],0,1); + ; ambient + fld dword[ecx+offs_mate_ambient] + fmul dword[ebx+offs_ligh_ambient] + fstp dword[lR] ;lR=l.ambient.v[0] * m.ambient.v[0] + fld dword[ecx+offs_mate_ambient+4] + fmul dword[ebx+offs_ligh_ambient+4] + fstp dword[lG] ;lG=l.ambient.v[1] * m.ambient.v[1] + fld dword[ecx+offs_mate_ambient+8] + fmul dword[ebx+offs_ligh_ambient+8] + fstp dword[lB] ;lB=l.ambient.v[2] * m.ambient.v[2] -; for(l=c->first_light;l!=NULL;l=l->next) { -; float lR,lB,lG; + cmp dword[ebx+offs_ligh_position+12],0 ;if (l.position.v[3] == 0) + jne .els_0 + ; light at infinity + mov eax,[ebx+offs_ligh_position] + mov [d],eax ;d.X=l.position.v[0] + mov eax,[ebx+offs_ligh_position+4] + mov [d+4],eax ;d.Y=l.position.v[1] + mov eax,[ebx+offs_ligh_position+8] + mov [d+8],eax ;d.Z=l.position.v[2] + mov dword[att],1.0 + jmp .els_0_end + .els_0: + ; distance attenuation + fld dword[ebx+offs_ligh_position] + fsub dword[esi+offs_vert_ec] + fstp dword[d] ;d.X=l.position.v[0]-v.ec.v[0] + fld dword[ebx+offs_ligh_position+offs_Y] + fsub dword[esi+offs_vert_ec+offs_Y] + fstp dword[d+offs_Y] ;d.Y=l.position.v[1]-v.ec.v[1] + fld dword[ebx+offs_ligh_position+offs_Z] + fsub dword[esi+offs_vert_ec+offs_Z] + fstp dword[d+offs_Z] ;d.Z=l.position.v[2]-v.ec.v[2] + fld dword[d] + fmul st0,st0 + fld dword[d+offs_Y] + fmul st0,st0 + faddp + fld dword[d+offs_Z] + fmul st0,st0 + faddp + fsqrt + fst dword[dist] ;dist=sqrt(d.X^2+d^2+d^2) + fcom dword[fl_1e_3] + fstsw ax + sahf + jbe @f ;if (dist>1.0e-3) + fld1 + fdiv st0,st1 + fld dword[d] + fmul st0,st1 + fstp dword[d] + fld dword[d+offs_Y] + fmul st0,st1 + fstp dword[d+offs_Y] + fld dword[d+offs_Z] + fmul st0,st1 + fstp dword[d+offs_Z] + ffree st0 ;1.0/dist + fincstp + @@: + fld dword[ebx+offs_ligh_attenuation+8] + fmul st0,st1 ;st0 = dist * l.attenuation[2] + fadd dword[ebx+offs_ligh_attenuation+4] + fmul st0,st1 + fadd dword[ebx+offs_ligh_attenuation] + fld1 + fdiv st0,st1 + fstp dword[att] ;att = 1.0f/(l.attenuation[0]+dist*(l.attenuation[1]+dist*l.attenuation[2])) + ffree st0 ;1.0 + fincstp + ffree st0 ;dist + fincstp + .els_0_end: + fld dword[d] + fmul dword[n] + fld dword[d+offs_Y] + fmul dword[n+offs_Y] + faddp + fld dword[d+offs_Z] + fmul dword[n+offs_Z] + faddp ;dot = d.X*n.X+d.Y*n.Y+d.Z*n.Z + cmp dword[twoside],0 ;if (twoside && dot < 0) + je @f + ftst ;if (dot<0) + fstsw ax + sahf + jae @f + fchs ;dot = -dot + @@: + ftst ;if (dot>0) + fstsw ax + sahf + jle .if0_end + ; diffuse light + fld dword[ecx+offs_mate_diffuse] + fmul dword[ebx+offs_ligh_diffuse] + fmul st0,st1 + fadd dword[lR] + fstp dword[lR] ;lR+=dot * l.diffuse.v[0] * m.diffuse.v[0] + fld dword[ecx+offs_mate_diffuse+4] + fmul dword[ebx+offs_ligh_diffuse+4] + fmul st0,st1 + fadd dword[lG] + fstp dword[lG] ;lG+=dot * l.diffuse.v[1] * m.diffuse.v[1] + fld dword[ecx+offs_mate_diffuse+8] + fmul dword[ebx+offs_ligh_diffuse+8] + fmul st0,st1 + fadd dword[lB] + fstp dword[lB] ;lB+=dot * l.diffuse.v[2] * m.diffuse.v[2] + ffree st0 ;dot + fincstp -; /* ambient */ -; lR=l->ambient.v[0] * m->ambient.v[0]; -; lG=l->ambient.v[1] * m->ambient.v[1]; -; lB=l->ambient.v[2] * m->ambient.v[2]; + ; spot light + fld dword[ebx+offs_ligh_spot_cutoff] + fcomp dword[an180f] ;if (l.spot_cutoff != 180) + fstsw ax + sahf + jne .if1_end + fld dword[ebx+offs_ligh_norm_spot_direction] + fmul dword[d] + fld dword[ebx+offs_ligh_norm_spot_direction+4] + fmul dword[d+offs_Y] + faddp + fld dword[ebx+offs_ligh_norm_spot_direction+8] + fmul dword[d+offs_Z] + faddp + fchs + fst dword[dot_spot] + cmp dword[twoside],0 ;if (twoside && dot_spot < 0) + je @f + ftst ;if (dot_spot<0) + fstsw ax + sahf + jae @f + fchs ;dot_spot = -dot_spot + @@: + fcom dword[ebx+offs_ligh_cos_spot_cutoff] ;if (dot_spot < l.cos_spot_cutoff) + fstsw ax + sahf + jae .els_1 + ; no contribution + ffree st0 ;dot_spot + fincstp + mov ebx,[ebx+offs_ligh_next] + jmp .cycle_0 ;continue + .els_1: + ; TODO: optimize + fld dword[ebx+offs_ligh_spot_exponent] + ftst ;if (l.spot_exponent > 0) + fstsw ax + sahf + jbe @f + fxch st1 ;dot_spot <--> l.spot_exponent + ;Вычисляем x^y + ;fld y + ;fld x + fyl2x ;Стек FPU теперь содержит: st0=z=y*log2(x): + ;Теперь считаем 2**z: + fld st0 ;Создаем еще одну копию z + frndint ;Округляем + fsubr st0,st1 ;st1=z, st0=z-trunc(z) + f2xm1 ;st1=z, st0=2**(z-trunc(z))-1 + fld1 + faddp ;st1=z, st0=2**(z-trunc(z)) + fscale ;st1=z, st0=(2**trunc(z))*(2**(z-trunc(z)))=2**t + fxch st1 + fstp st ;Результат остается на вершине стека st0 + fmul dword[att] + fstp dword[att] ;att=att*pow(dot_spot,l.spot_exponent) + jmp .if1_end + @@: + ffree st0 ;l.spot_exponent + fincstp + ffree st0 ;dot_spot + fincstp + .if1_end: -; if (l->position.v[3] == 0) { -; /* light at infinity */ -; d.X=l->position.v[0]; -; d.Y=l->position.v[1]; -; d.Z=l->position.v[2]; -; att=1; -; } else { -; /* distance attenuation */ -; d.X=l->position.v[0]-v->ec.v[0]; -; d.Y=l->position.v[1]-v->ec.v[1]; -; d.Z=l->position.v[2]-v->ec.v[2]; -; dist=sqrt(d.X*d.X+d.Y*d.Y+d.Z*d.Z); -; if (dist>1E-3) { -; tmp=1/dist; -; d.X*=tmp; -; d.Y*=tmp; -; d.Z*=tmp; -; } -; att=1.0f/(l->attenuation[0]+dist*(l->attenuation[1]+ -; dist*l->attenuation[2])); -; } -; dot=d.X*n.X+d.Y*n.Y+d.Z*n.Z; -; if (twoside && dot < 0) dot = -dot; -; if (dot>0) { -; /* diffuse light */ -; lR+=dot * l->diffuse.v[0] * m->diffuse.v[0]; -; lG+=dot * l->diffuse.v[1] * m->diffuse.v[1]; -; lB+=dot * l->diffuse.v[2] * m->diffuse.v[2]; -; -; /* spot light */ -; if (l->spot_cutoff != 180) { -; dot_spot=-(d.X*l->norm_spot_direction.v[0]+ -; d.Y*l->norm_spot_direction.v[1]+ -; d.Z*l->norm_spot_direction.v[2]); -; if (twoside && dot_spot < 0) dot_spot = -dot_spot; -; if (dot_spot < l->cos_spot_cutoff) { -; /* no contribution */ -; continue; -; } else { -; /* TODO: optimize */ -; if (l->spot_exponent > 0) { -; att=att*pow(dot_spot,l->spot_exponent); -; } -; } -; } + ; specular light + cmp dword[edx+offs_cont_local_light_model],0 ;if (c.local_light_model) + je .els_2 + mov eax,[esi+offs_vert_ec] + mov [vcoord],eax ;vcoord.X=v.ec.X + mov eax,[esi+offs_vert_ec+offs_Y] + mov [vcoord+offs_Y],eax ;vcoord.Y=v.ec.Y + mov eax,[esi+offs_vert_ec+offs_Z] + mov [vcoord+offs_Z],eax ;vcoord.Z=v.ec.Z + mov eax,ebp + sub eax,12 ;eax = &vcoord + stdcall gl_V3_Norm, eax + fld dword[d] + fsub dword[vcoord] + fstp dword[s] ;s.X=d.X-vcoord.X + fld dword[d+offs_Y] + fsub dword[vcoord+offs_Y] + fstp dword[s+offs_Y] ;s.Y=d.Y-vcoord.Y + fld dword[d+offs_Z] + fsub dword[vcoord+offs_Z] + fstp dword[s+offs_Z] ;s.Z=d.Z-vcoord.Z + jmp .els_2_end + .els_2: + mov eax,[d] + mov [s],eax ;s.X=d.X + mov eax,[d+offs_Y] + mov [s+offs_Y],eax ;s.Y=d.Y + fld1 + fadd dword[d+offs_Z] + fstp dword[s+offs_Z] ;s.Z=d.Z+1.0 + .els_2_end: + fld dword[n] + fmul st0,st0 + fld dword[n+offs_Y] + fmul st0,st0 + faddp + fld dword[n+offs_Z] + fmul st0,st0 + faddp ;dot_spec = n.X^2 +n.Y^2 +n.Z^2 + cmp dword[twoside],0 ;if (twoside && dot_spec < 0) + je @f + ftst ;if (dot_spec < 0) + fstsw ax + sahf + jae @f + fchs ;dot_spec = -dot_spec + @@: + ftst ;if (dot_spec > 0) + fstsw ax + sahf + jae .if0_end + fld dword[s] + fmul st0,st0 + fld dword[s+offs_Y] + fmul st0,st0 + faddp + fld dword[s+offs_Z] + fmul st0,st0 + faddp + fsqrt + fcom dword[fl_1e_3] + fstsw ax + sahf + jbe @f ;if (tmp > 1.0e-3) + fdiv st1,st0 ;dot_spec /= tmp + @@: + ffree st0 ;tmp + fincstp -; /* specular light */ + ; TODO: optimize + ; testing specular buffer code + ; dot_spec= pow(dot_spec,m.shininess) + stdcall specbuf_get_buffer, edx, dword[ecx+offs_mate_shininess_i], dword[ecx+offs_mate_shininess] + ;eax = specbuf + mov dword[idx],SPECULAR_BUFFER_SIZE + fild dword[idx] + fld1 + fcomp + fstsw ax + sahf + jae @f + fmul st0,st1 + @@: + fistp dword[idx] ;if (dot_spec < 1.0) idx = (int)(dot_spec*SPECULAR_BUFFER_SIZE) + ;else idx = SPECULAR_BUFFER_SIZE; + ffree st0 ;dot_spec + fincstp + shl dword[idx],2 + add eax,dword[idx] + fld dword[eax+offs_spec_buf] ;dot_spec = specbuf.buf[idx] + fld dword[ebx+offs_ligh_specular] + fmul st0,st1 + fmul dword[ecx+offs_mate_specular] + fadd dword[lR] + fstp dword[lR] ;lR+=dot_spec * l.specular.v[0] * m.specular.v[0] + fld dword[ebx+offs_ligh_specular+offs_Y] + fmul st0,st1 + fmul dword[ecx+offs_mate_specular+offs_Y] + fadd dword[lG] + fstp dword[lG] ;lG+=dot_spec * l.specular.v[1] * m.specular.v[1] + fld dword[ebx+offs_ligh_specular+offs_Z] + fmul st0,st1 + fmul dword[ecx+offs_mate_specular+offs_Z] + fadd dword[lB] + fstp dword[lB] ;lB+=dot_spec * l.specular.v[2] * m.specular.v[2] + ffree st0 ;dot_spec + fincstp + jmp .if2_end + .if0_end: + ffree st0 ;dot [or] dot_spec + fincstp + .if2_end: -; if (c->local_light_model) { -; V3 vcoord; -; vcoord.X=v->ec.X; -; vcoord.Y=v->ec.Y; -; vcoord.Z=v->ec.Z; -; gl_V3_Norm(&vcoord); -; s.X=d.X-vcoord.X; -; s.Y=d.Y-vcoord.X; -; s.Z=d.Z-vcoord.X; -; } else { -; s.X=d.X; -; s.Y=d.Y; -; s.Z=d.Z+1.0; -; } -; dot_spec=n.X*s.X+n.Y*s.Y+n.Z*s.Z; -; if (twoside && dot_spec < 0) dot_spec = -dot_spec; -; if (dot_spec>0) { -; GLSpecBuf *specbuf; -; int idx; -; tmp=sqrt(s.X*s.X+s.Y*s.Y+s.Z*s.Z); -; if (tmp > 1E-3) { -; dot_spec=dot_spec / tmp; -; } + fld dword[att] + fld dword[lR] + fmul st0,st1 + fadd dword[R] + fstp dword[R] ;R += att * lR + fld dword[lG] + fmul st0,st1 + fadd dword[G] + fstp dword[G] ;G += att * lG + fld dword[lB] + fmul st0,st1 + fadd dword[B] + fstp dword[B] ;B += att * lB + ffree st0 ;att + fincstp + mov ebx,[ebx+offs_ligh_next] + jmp .cycle_0 + .cycle_0_end: -; /* TODO: optimize */ -; /* testing specular buffer code */ -; /* dot_spec= pow(dot_spec,m->shininess);*/ -; specbuf = specbuf_get_buffer(c, m->shininess_i, m->shininess); -; idx = (int)(dot_spec*SPECULAR_BUFFER_SIZE); -; if (idx > SPECULAR_BUFFER_SIZE) idx = SPECULAR_BUFFER_SIZE; -; dot_spec = specbuf->buf[idx]; -; lR+=dot_spec * l->specular.v[0] * m->specular.v[0]; -; lG+=dot_spec * l->specular.v[1] * m->specular.v[1]; -; lB+=dot_spec * l->specular.v[2] * m->specular.v[2]; -; } -; } - -; R+=att * lR; -; G+=att * lG; -; B+=att * lB; -; } - -; v->color.v[0]=clampf(R,0,1); -; v->color.v[1]=clampf(G,0,1); -; v->color.v[2]=clampf(B,0,1); -; v->color.v[3]=A; + clampf [R],0,1 + mov [esi+offs_vert_color],eax ;v.color.v[0]=clampf(R,0,1) + clampf [G],0,1 + mov [esi+offs_vert_color+4],eax ;v.color.v[1]=clampf(G,0,1) + clampf [B],0,1 + mov [esi+offs_vert_color+8],eax ;v.color.v[2]=clampf(B,0,1) + mov eax,[A] + mov [esi+offs_vert_color+12],eax ;v.color.v[3]=A +popad ret endp diff --git a/programs/develop/libraries/TinyGL/asm_fork/misc.asm b/programs/develop/libraries/TinyGL/asm_fork/misc.asm index 83e82305df..d6e8ab11df 100644 --- a/programs/develop/libraries/TinyGL/asm_fork/misc.asm +++ b/programs/develop/libraries/TinyGL/asm_fork/misc.asm @@ -182,13 +182,14 @@ proc glopEnableDisable uses eax ebx ecx, context:dword, p:dword and dword[eax+offs_cont_offset_states],not TGL_OFFSET_LINE jmp .end_f .polygon_offset_line: ;default: - cmp ebx,GL_LIGHT0 - jl .els_0 - cmp ebx,GL_LIGHT0+MAX_LIGHTS - jge .els_0 ;if (GL_LIGHT0 <= ebx < GL_LIGHT0+MAX_LIGHTS) - stdcall gl_enable_disable_light, eax,ebx-GL_LIGHT0,ecx - jmp .end_f - .els_0: + cmp ebx,GL_LIGHT0 + jl .els_0 + cmp ebx,GL_LIGHT0+MAX_LIGHTS + jge .els_0 ;if (GL_LIGHT0 <= ebx < GL_LIGHT0+MAX_LIGHTS) + sub ebx,GL_LIGHT0 + stdcall gl_enable_disable_light, eax,ebx,ecx + jmp .end_f + .els_0: ;//fprintf(stderr,"glEnableDisable: 0x%X not supported.\n",code); .end_f: ret diff --git a/programs/develop/libraries/TinyGL/asm_fork/specbuf.asm b/programs/develop/libraries/TinyGL/asm_fork/specbuf.asm new file mode 100644 index 0000000000..d0bc3d223b --- /dev/null +++ b/programs/develop/libraries/TinyGL/asm_fork/specbuf.asm @@ -0,0 +1,111 @@ + +align 4 +proc calc_buf uses ebx ecx, buf:dword, shininess:dword +locals + val dd ? ;float + f_inc dd ? ;float +endl + mov dword[val],0.0f + mov dword[f_inc],SPECULAR_BUFFER_SIZE + fld1 + fidiv dword[f_inc] + fstp dword[f_inc] ;f_inc = 1.0f/SPECULAR_BUFFER_SIZE + xor ecx,ecx +align 4 + .cycle_0: ;for (i = 0; i <= SPECULAR_BUFFER_SIZE; i++) + cmp ecx,SPECULAR_BUFFER_SIZE + jg @f + ;Вычисляем x^y + fld dword[shininess] + fld dword[val] + fyl2x ;Стек FPU теперь содержит: st0=z=y*log2(x): + ;Теперь считаем 2**z: + fld st0 ;Создаем еще одну копию z + frndint ;Округляем + fsubr st0,st1 ;st1=z, st0=z-trunc(z) + f2xm1 ;st1=z, st0=2**(z-trunc(z))-1 + fld1 + faddp ;st1=z, st0=2**(z-trunc(z)) + fscale ;st1=z, st0=(2**trunc(z))*(2**(z-trunc(z)))=2**t + fxch st1 + fstp st ;Результат остается на вершине стека st0 + + mov ebx,ecx + shl ebx,2 + add ebx,offs_spec_buf + add ebx,[buf] + fstp dword[ebx] ;buf.buf[i] = pow(val, shininess) + + fld dword[val] + fadd dword[f_inc] + fstp dword[val] ;val += f_inc + inc ecx + jmp .cycle_0 + @@: + ret +endp + +align 4 +proc specbuf_get_buffer uses ebx ecx edx, context:dword, shininess_i:dword, shininess:dword +locals + found dd ? ;GLSpecBuf * + oldest dd ? ;GLSpecBuf * +endl + mov edx,[context] + mov eax,[edx+offs_cont_specbuf_first] + mov [found],eax + mov [oldest],eax + mov ebx,[shininess_i] + .cycle_0: + or eax,eax ;while (found) + jz @f + cmp [eax+offs_spec_shininess_i],ebx ;while (found.shininess_i != shininess_i) + je @f + mov ecx,[oldest] + mov ecx,[ecx+offs_spec_last_used] + cmp [eax+offs_spec_last_used],ecx ;if (found.last_used < oldest.last_used) + jge .end_0 + mov [oldest],eax ;oldest = found + .end_0: + mov eax,[eax+offs_spec_next] ;found = found.next + jmp .cycle_0 + @@: + cmp dword[found],0 ;if (found) /* hey, found one! */ + je @f + mov eax,[found] + mov ecx,[edx+offs_cont_specbuf_used_counter] + mov [eax+offs_spec_last_used],ecx ;found.last_used = context.specbuf_used_counter + inc dword[edx+offs_cont_specbuf_used_counter] + jmp .end_f ;return found + @@: + cmp dword[oldest],0 ;if (oldest == NULL || context.specbuf_num_buffers < MAX_SPECULAR_BUFFERS) + je @f + cmp dword[edx+offs_cont_specbuf_num_buffers],MAX_SPECULAR_BUFFERS + jl @f + jmp .end_1 + @@: + ; create new buffer + stdcall gl_malloc, sizeof.GLSpecBuf +;if (!eax) gl_fatal_error("could not allocate specular buffer") + inc dword[edx+offs_cont_specbuf_num_buffers] + mov ecx,[edx+offs_cont_specbuf_first] + mov [eax+offs_spec_next],ecx + mov [edx+offs_cont_specbuf_first],eax + mov ecx,[edx+offs_cont_specbuf_used_counter] + mov [eax+offs_spec_last_used],ecx + inc dword[edx+offs_cont_specbuf_used_counter] + mov [eax+offs_spec_shininess_i],ebx + stdcall calc_buf, eax,dword[shininess] + jmp .end_f + .end_1: + ; overwrite the lru buffer + ;tgl_trace("overwriting spec buffer :(\n"); + mov eax,[oldest] + mov [eax+offs_spec_shininess_i],ebx + mov ecx,[edx+offs_cont_specbuf_used_counter] + mov [eax+offs_spec_last_used],ecx + inc dword[edx+offs_cont_specbuf_used_counter] + stdcall calc_buf, eax,dword[shininess] + .end_f: + ret +endp diff --git a/programs/develop/libraries/TinyGL/asm_fork/tinygl.asm b/programs/develop/libraries/TinyGL/asm_fork/tinygl.asm index 9e6bb7243b..a1f769d529 100644 --- a/programs/develop/libraries/TinyGL/asm_fork/tinygl.asm +++ b/programs/develop/libraries/TinyGL/asm_fork/tinygl.asm @@ -29,6 +29,7 @@ include 'ztriangle.asm' ;include 'image_util.asm' ;include 'msghandling.asm' include 'arrays.asm' +include 'specbuf.asm' include 'kosgl.asm' include 'glu.asm' diff --git a/programs/develop/libraries/TinyGL/asm_fork/vertex.asm b/programs/develop/libraries/TinyGL/asm_fork/vertex.asm index 09585fb5da..c67acd02d4 100644 --- a/programs/develop/libraries/TinyGL/asm_fork/vertex.asm +++ b/programs/develop/libraries/TinyGL/asm_fork/vertex.asm @@ -137,11 +137,25 @@ endl cmp dword[edx+offs_cont_lighting_enabled],0 ;if(context.lighting_enabled) je @f +if DEBUG ;context.matrix_stack_ptr[0] + stdcall gl_print_matrix,dword[edx+offs_cont_matrix_stack_ptr],4 +end if ; precompute inverse modelview mov ebx,ebp sub ebx,64 - stdcall gl_M4_Inv, ebx, edx+offs_cont_matrix_stack_ptr - stdcall gl_M4_Transpose, edx+offs_cont_matrix_model_view_inv, ebx + stdcall gl_M4_Inv, ebx,dword[edx+offs_cont_matrix_stack_ptr] +if DEBUG ;tmp + stdcall dbg_print,txt_sp,txt_nl + stdcall gl_print_matrix,ebx,4 +end if + push ebx + mov ebx,edx + add ebx,offs_cont_matrix_model_view_inv + stdcall gl_M4_Transpose, ebx +if DEBUG ;context.matrix_model_view_inv + stdcall dbg_print,txt_sp,txt_nl + stdcall gl_print_matrix,ebx,4 +end if jmp .end_if_0 @@: mov ecx,edx @@ -296,7 +310,7 @@ pushad add edi,offs_cont_current_normal mov edx,[v] - fld dword[edi+offs_X] + fld dword[edi] ;edi = &n fld dword[edi+offs_Y] fld dword[edi+offs_Z] @@ -458,7 +472,6 @@ pushad stdcall gl_vertex_transform, edx, ebx ; color - cmp dword[edx+offs_cont_lighting_enabled],0 je .els_0 stdcall gl_shade_vertex, edx,ebx diff --git a/programs/develop/libraries/TinyGL/asm_fork/zgl.inc b/programs/develop/libraries/TinyGL/asm_fork/zgl.inc index f7b4e892bb..6d5abda0b8 100644 --- a/programs/develop/libraries/TinyGL/asm_fork/zgl.inc +++ b/programs/develop/libraries/TinyGL/asm_fork/zgl.inc @@ -47,6 +47,11 @@ struct GLSpecBuf next dd ? ;struct GLSpecBuf* ends +offs_spec_shininess_i equ 0 +offs_spec_last_used equ 4 +offs_spec_buf equ 8 +offs_spec_next equ 8+4*(SPECULAR_BUFFER_SIZE+1) + struct GLLight ambient V4 diffuse V4 diff --git a/programs/develop/libraries/TinyGL/asm_fork/zmath.asm b/programs/develop/libraries/TinyGL/asm_fork/zmath.asm index 61f91e79c4..565bcd5f6f 100644 --- a/programs/develop/libraries/TinyGL/asm_fork/zmath.asm +++ b/programs/develop/libraries/TinyGL/asm_fork/zmath.asm @@ -70,7 +70,6 @@ pushad .cycle_0: ;i xor ebx,ebx .cycle_1: ;j - finit fldz ;sum=0 xor ecx,ecx M4_reg edi,[a],eax,0 @@ -79,7 +78,7 @@ pushad add edi,4 M4_reg esi,[b],ecx,ebx fmul dword[esi] - fadd st0,st1 ;sum += a[i][k] * b[k][j] + faddp ;sum += a[i][k] * b[k][j] inc ecx cmp ecx,4 jl .cycle_2 @@ -91,7 +90,6 @@ pushad inc eax cmp eax,4 jl .cycle_0 - finit if DEBUG ;gl_M4_Mul stdcall dbg_print,f_m4m,txt_nl stdcall gl_print_matrix,[c],4 @@ -187,13 +185,42 @@ endp ; a->Z=b->m[2][0]*c->X+b->m[2][1]*c->Y+b->m[2][2]*c->Z; ;} -;void gl_M4_MulV4(V4 *a,M4 *b,V4 *c) -;{ -; a->X=b->m[0][0]*c->X+b->m[0][1]*c->Y+b->m[0][2]*c->Z+b->m[0][3]*c->W; -; a->Y=b->m[1][0]*c->X+b->m[1][1]*c->Y+b->m[1][2]*c->Z+b->m[1][3]*c->W; -; a->Z=b->m[2][0]*c->X+b->m[2][1]*c->Y+b->m[2][2]*c->Z+b->m[2][3]*c->W; -; a->W=b->m[3][0]*c->X+b->m[3][1]*c->Y+b->m[3][2]*c->Z+b->m[3][3]*c->W; -;} +align 4 +proc gl_M4_MulV4 uses ebx ecx edx, a:dword, b:dword, c:dword ;V4 *a, M4 *b, V4 *c + mov ebx,[b] + mov edx,[c] + fld dword[edx] + fld dword[edx+4] + fld dword[edx+8] + fld dword[edx+12] + mov edx,[a] + mov ecx,4 + .cycle_1: + fld dword[ebx] ;st0 = m[_][0] + fmul st0,st4 ;st0 *= c.X + fld dword[ebx+4] ;st0 = m[_][1] + fmul st0,st4 ;st0 *= c.Y + faddp + fld dword[ebx+8] ;st0 = m[_][2] + fmul st0,st3 ;st0 *= c.Z + faddp + fld dword[ebx+12] ;st0 += m[_][3] + fmul st0,st2 ;st0 *= c.Z + faddp + fstp dword[edx] ;a.X = b.m[_][0]*c.X +b.m[_][1]*c.Y +b.m[_][2]*c.Z +b.m[_][3]*c.W + add ebx,16 ; + add edx,4 ; + loop .cycle_1 + ffree st0 + fincstp + ffree st0 + fincstp + ffree st0 + fincstp + ffree st0 + fincstp + ret +endp ; transposition of a 4x4 matrix align 4 @@ -258,58 +285,219 @@ endp ; Note : m is destroyed align 4 -proc Matrix_Inv uses ecx, r:dword, m:dword, n:dword ;(float *r,float *m,int n) -; int i,j,k,l; -; float max,tmp,t; +proc Matrix_Inv uses ebx ecx edx edi esi, r:dword, m:dword, n:dword ;(float *r,float *m,int n) +locals + max dd ? ;float + tmp dd ? +endl -; /* identite dans r */ -; for(i=0;ifabs(max)) { -; k=i; -; max=m[i*n+j]; -; } + ; identite dans r + mov eax,0.0 + mov ecx,[n] + imul ecx,ecx + mov edi,[r] + rep stosd ;for(i=0;i n + ; ecx -> j + ; edx -> k + ; edi -> i + ; esi -> l + mov ebx,[n] + xor ecx,ecx + .cycle_0: ;for(j=0;jfabs(max)) + fstsw ax + sahf + jbe @f + mov edx,edi ;k=i + fst dword[max] + @@: + ffree st0 + fincstp + inc edi + jmp .cycle_1 + .cycle_1_end: -; /* permutation des lignes j et k */ -; if (k!=j) { -; for(i=0;i