struct GLUquadricObj DrawStyle dd ? ; GLU_FILL, LINE, SILHOUETTE, or POINT Orientation dd ? ; GLU_INSIDE or GLU_OUTSIDE TextureFlag dd ? ; Generate texture coords? Normals dd ? ; GLU_NONE, GLU_FLAT, or GLU_SMOOTH ErrorFunc dd ? ; Error handler callback function ends offs_qobj_DrawStyle equ 0 offs_qobj_Orientation equ 4 offs_qobj_TextureFlag equ 8 offs_qobj_Normals equ 12 offs_qobj_ErrorFunc equ 16 ;Так как некоторые извращенческие функции OpenGL воспринимают только параметры ;типа double (8 байт) то придется пихать их в стек макросом glpush macro glpush GLDoubleVar { push dword[GLDoubleVar+4] push dword[GLDoubleVar] } ;void drawTorus(float rc, int numc, float rt, int numt) ;{ ;} ;static void normal3f(GLfloat x, GLfloat y, GLfloat z ) ;{ ;} align 4 an360f dd 360.0 align 16 proc gluPerspective, fovy:qword, aspect:qword, zNear:qword, zFar:qword locals mfW dq ? fW dq ? mfH dq ? fH dq ? endl fldpi fmul qword[fovy] fdiv dword[an360f] fptan ffree st0 ;выкидываем 1.0 которая осталось после вычисления тангенса fincstp fmul qword[zNear] fld st0 fchs fstp qword[mfH] fst qword[fH] fmul qword[aspect] fld st0 fchs fstp qword[mfW] fstp qword[fW] glpush zFar glpush zNear glpush fH glpush mfH glpush fW glpush mfW call glFrustum ret endp ;void gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, ; GLdouble centerx, GLdouble centery, GLdouble centerz, ; GLdouble upx, GLdouble upy, GLdouble upz) ;{ ;} align 16 gluNewQuadric: stdcall gl_malloc, sizeof.GLUquadricObj or eax,eax jz @f mov dword[eax+offs_qobj_DrawStyle],GLU_FILL mov dword[eax+offs_qobj_Orientation],GLU_OUTSIDE mov dword[eax+offs_qobj_TextureFlag],GL_FALSE mov dword[eax+offs_qobj_Normals],GLU_SMOOTH mov dword[eax+offs_qobj_ErrorFunc],0 ;NULL @@: ret align 16 proc gluDeleteQuadric, state:dword cmp dword[state],0 je @f stdcall gl_free,[state] @@: ret endp ; ; Set the drawing style to be GLU_FILL, GLU_LINE, GLU_SILHOUETTE, ; or GLU_POINT. ; align 16 proc gluQuadricDrawStyle uses eax ebx, qobj:dword, drawStyle:dword mov eax,[qobj] or eax,eax jz .err_q mov ebx,[drawStyle] cmp ebx,GLU_FILL je @f cmp ebx,GLU_LINE je @f cmp ebx,GLU_SILHOUETTE je @f cmp ebx,GLU_POINT je @f jmp .err_q align 4 @@: mov dword[eax+offs_qobj_DrawStyle],ebx jmp @f align 4 .err_q: stdcall dbg_print,sz_gluQuadricDrawStyle,err_9 @@: ret endp ; ; Set the orientation to GLU_INSIDE or GLU_OUTSIDE. ; align 16 proc gluQuadricOrientation uses eax ebx, qobj:dword, orientation:dword mov eax,[qobj] or eax,eax jz .err_q mov ebx,[orientation] cmp ebx,GLU_INSIDE je @f cmp ebx,GLU_OUTSIDE je @f jmp .err_q align 4 @@: mov dword[eax+offs_qobj_Orientation],ebx jmp @f align 4 .err_q: stdcall dbg_print,sz_gluQuadricOrientation,err_9 @@: ret endp align 16 proc gluQuadricTexture uses eax ebx, qobj:dword, texture:dword mov eax,[qobj] or eax,eax jz .err_q mov ebx,[texture] cmp ebx,GL_TRUE je @f cmp ebx,GL_FALSE je @f @@: mov dword[eax+offs_qobj_TextureFlag],ebx jmp @f align 4 .err_q: stdcall dbg_print,sz_gluQuadricTexture,err_9 @@: ret endp align 16 proc gluCylinder qobj:dword, baseRadius:dword, topRadius:dword, height:dword,\ slices:dword, stacks:dword locals da dq ? ;double r dq ? ;double dr dq ? ;double dz dq ? ;double x dd ? ;float y dd ? ;float z dd ? ;float nz dd ? ;float nsign dd ? ;float i dd ? ;GLint j dd ? ;GLint du dd ? ;float dv dd ? ;float tcx dd ? ;float tcy dd ? ;float x2 dd ? ;float y2 dd ? ;float endl pushad mov edx,[qobj] fld1 cmp dword[edx+offs_qobj_Orientation],GLU_INSIDE jne @f fchs @@: fstp dword[nsign] fldpi fadd st0,st0 fidiv dword[slices] fstp qword[da] ;da = 2.0*M_PI / slices mov ebx,[topRadius] fld qword[ebx] mov ecx,[baseRadius] fsub qword[ecx] fld st0 ;copy: topRadius-baseRadius fidiv dword[stacks] fstp qword[dr] ;dr = (topRadius-baseRadius) / stacks mov eax,[height] fld qword[eax] fidiv dword[stacks] fstp qword[dz] ;dz = height / stacks fchs fdiv qword[eax] fstp dword[nz] ;nz = (baseRadius-topRadius) / height ; Z component of normal vectors cmp dword[edx+offs_qobj_DrawStyle],GLU_POINT jne .else0 stdcall glBegin,GL_POINTS mov ebx,[slices] mov dword[i],0 align 4 .cycle_0: ;for (i=0;i0.0) fld st0 fmul dword[nz] fstp dword[esp-4] fld st0 fmul dword[y] fstp dword[esp-8] fmul dword[x] fstp dword[esp-12] sub esp,12 call glNormal3f ;x1*nsign, y1*nsign, nz*nsign cmp dword[edx+offs_qobj_TextureFlag],0 ;if (qobj.TextureFlag) je @f stdcall glTexCoord2f, [tcx],[tcy] @@: mov eax,[z] mov [esp-4],eax fld qword[r] fld st0 fmul dword[y] fstp dword[esp-8] fmul dword[x] fstp dword[esp-12] sub esp,12 call glVertex3f ;x1*r, y1*r, z fld dword[nsign] fld st0 fmul dword[nz] fstp dword[esp-4] fld st0 fmul dword[y2] fstp dword[esp-8] fmul dword[x2] fstp dword[esp-12] sub esp,12 call glNormal3f ;x2*nsign, y2*nsign, nz*nsign cmp dword[edx+offs_qobj_TextureFlag],0 ;if (qobj.TextureFlag) je @f push dword[tcy] fld dword[tcx] fadd dword[du] fstp dword[esp-4] sub esp,4 call glTexCoord2f ;tcx+du, tcy @@: mov eax,[z] mov [esp-4],eax fld qword[r] fld st0 fmul dword[y2] fstp dword[esp-8] fmul dword[x2] fstp dword[esp-12] sub esp,12 call glVertex3f ;x2*r, y2*r, z jmp .else3_end .else3: fld st0 fmul dword[nz] fstp dword[esp-4] fld st0 fmul dword[y2] fstp dword[esp-8] fmul dword[x2] fstp dword[esp-12] sub esp,12 call glNormal3f ;x2*nsign, y2*nsign, nz*nsign cmp dword[edx+offs_qobj_TextureFlag],0 ;if (qobj.TextureFlag) je @f stdcall glTexCoord2f, [tcx],[tcy] @@: mov eax,[z] mov [esp-4],eax fld qword[r] fld st0 fmul dword[y2] fstp dword[esp-8] fmul dword[x2] fstp dword[esp-12] sub esp,12 call glVertex3f ;x2*r, y2*r, z fld dword[nsign] fld st0 fmul dword[nz] fstp dword[esp-4] fld st0 fmul dword[y] fstp dword[esp-8] fmul dword[x] fstp dword[esp-12] sub esp,12 call glNormal3f ;x1*nsign, y1*nsign, nz*nsign cmp dword[edx+offs_qobj_TextureFlag],0 ;if (qobj.TextureFlag) je @f push dword[tcy] fld dword[tcx] fadd dword[du] fstp dword[esp-4] sub esp,4 call glTexCoord2f ;tcx+du, tcy @@: mov eax,[z] mov [esp-4],eax fld qword[r] fld st0 fmul dword[y] fstp dword[esp-8] fmul dword[x] fstp dword[esp-12] sub esp,12 call glVertex3f ;x1*r, y1*r, z .else3_end: fld dword[z] fadd qword[dz] fstp dword[z] ;z += dz fld qword[r] fadd qword[dr] fstp qword[r] ;r += dr fld dword[tcy] fadd dword[dv] fstp dword[tcy] ;tcy += dv dec ecx jnz .cycle_8 call glEnd fld dword[tcx] fadd dword[du] fstp dword[tcx] ;tcx += du jmp .cycle_7 align 4 .cycle_7_end: .end_f: popad ret endp ; Disk (adapted from Mesa) ;void gluDisk(GLUquadricObj *qobj, GLdouble innerRadius, GLdouble outerRadius, GLint slices, GLint loops ) ;{ ;} ; ; Sphere (adapted from Mesa) ; ;input: ; float radius, int slices, int stacks align 16 proc gluSphere qobj:dword, radius:dword, slices:dword, stacks:dword locals rho dd ? ;float drho dd ? theta dd ? dtheta dd ? x dd ? ;float y dd ? ;float z dd ? ;float s dd ? ;float t dd ? ;float d_s dd ? ;float d_t dd ? ;float i dd ? ;int j dd ? ;int imax dd ? ;int normals dd ? ;int nsign dd ? ;float endl pushad mov eax,[qobj] cmp dword[eax+offs_qobj_Normals],GLU_NONE ;if (qobj.Normals==GLU_NONE) jne .els_0 mov dword[normals],GL_FALSE jmp @f align 4 .els_0: mov dword[normals],GL_TRUE @@: cmp dword[eax+offs_qobj_Orientation],GLU_INSIDE ;if (qobj.Orientation==GLU_INSIDE) jne .els_1 mov dword[nsign],-1.0 jmp @f align 4 .els_1: mov dword[nsign],1.0 @@: fldpi fidiv dword[stacks] fstp dword[drho] fld1 fldpi fscale fidiv dword[slices] fstp dword[dtheta] ffree st0 fincstp cmp dword[eax+offs_qobj_DrawStyle],GLU_FILL ;if (qobj.DrawStyle==GLU_FILL) jne .if_glu_line ; draw +Z end as a triangle fan stdcall glBegin,GL_TRIANGLE_FAN cmp dword[normals],GL_TRUE jne @f stdcall glNormal3f, 0.0, 0.0, 1.0 @@: cmp dword[eax+offs_qobj_TextureFlag],0 ;if (qobj.TextureFlag) je @f stdcall glTexCoord2f, 0.5,1.0 @@: sub esp,4 fld dword[nsign] fmul dword[radius] fstp dword[esp] stdcall glVertex3f, 0.0, 0.0 ;, nsign * radius fld dword[drho] fcos fmul dword[nsign] fstp dword[z] ;z = nsign * cos(drho) mov dword[j],0 mov ecx,[slices] align 4 .cycle_0: ;for (j=0;j<=slices;j++) cmp dword[j],ecx jg .cycle_0_end fld dword[drho] fsin je @f fild dword[j] fmul dword[dtheta] jmp .t0_end align 4 @@: fldz .t0_end: fst dword[theta] ;theta = (j==slices) ? 0.0 : j * dtheta fsin fchs fmul st0,st1 fstp dword[x] ;x = -sin(theta) * sin(drho) fld dword[theta] fcos fmulp fstp dword[y] ;y = cos(theta) * sin(drho) cmp dword[normals],GL_TRUE jne @f fld dword[nsign] fld dword[z] fmul st0,st1 fstp dword[esp-4] fld dword[y] fmul st0,st1 fstp dword[esp-8] fld dword[x] fmulp fstp dword[esp-12] sub esp,12 stdcall glNormal3f ;x*nsign, y*nsign, z*nsign @@: fld dword[radius] fld dword[z] fmul st0,st1 fstp dword[esp-4] fld dword[y] fmul st0,st1 fstp dword[esp-8] fld dword[x] fmulp fstp dword[esp-12] sub esp,12 call glVertex3f ;x*radius, y*radius, z*radius inc dword[j] jmp .cycle_0 align 4 .cycle_0_end: call glEnd fld1 fidiv dword[slices] fstp dword[d_s] ;1.0 / slices fld1 fidiv dword[stacks] fstp dword[d_t] ;1.0 / stacks mov dword[t],1.0 ; because loop now runs from 0 mov ebx,[stacks] cmp dword[eax+offs_qobj_TextureFlag],0 ;if (qobj.TextureFlag) je .els_2 mov dword[i],0 mov [imax],ebx jmp @f align 4 .els_2: mov dword[i],1 dec ebx mov [imax],ebx @@: ; draw intermediate stacks as quad strips mov ebx,[imax] align 4 .cycle_1: ;for (i=imin;i=0;j--) cmp dword[j],0 jl .cycle_3_end fld dword[rho] fsin je @f fild dword[j] fmul dword[dtheta] jmp .t2_end align 4 @@: fldz .t2_end: fst dword[theta] ;theta = (j==slices) ? 0.0 : j * dtheta fsin fchs fmul st0,st1 fstp dword[x] ;x = -sin(theta) * sin(rho) fld dword[theta] fcos fmulp fstp dword[y] ;y = cos(theta) * sin(rho) cmp dword[normals],GL_TRUE jne @f fld dword[nsign] fld dword[z] fmul st0,st1 fstp dword[esp-4] fld dword[y] fmul st0,st1 fstp dword[esp-8] fld dword[x] fmul st0,st1 fstp dword[esp-12] sub esp,12 ffree st0 fincstp stdcall glNormal3f ;x*nsign, y*nsign, z*nsign @@: cmp dword[eax+offs_qobj_TextureFlag],0 ;if (qobj.TextureFlag) je @f stdcall glTexCoord2f, [s],[t] fld dword[s] fsub dword[d_s] fstp dword[s] @@: fld dword[radius] fld dword[z] fmul st0,st1 fstp dword[esp-4] fld dword[y] fmul st0,st1 fstp dword[esp-8] fld dword[x] fmulp fstp dword[esp-12] sub esp,12 call glVertex3f ;x*radius, y*radius, z*radius dec dword[j] jmp .cycle_3 align 4 .cycle_3_end: call glEnd jmp .end_f align 4 .if_glu_line: cmp dword[eax+offs_qobj_DrawStyle],GLU_LINE ;if (qobj.DrawStyle==GLU_LINE) je @f cmp dword[eax+offs_qobj_DrawStyle],GLU_SILHOUETTE ;if (qobj.DrawStyle==GLU_SILHOUETTE) je @f jmp .if_glu_point align 4 @@: ; draw stack lines mov dword[i],1 mov ebx,[stacks] mov ecx,[slices] align 4 .cycle_4: ;for (i=1;i