MASM32 и OpenGL
Это не так сложно, как на самом деле

Параллелепипед

Чтобы построить параллелепипед с центром в начале координат, необходимо в первую очередь определить это самое начало. Все просто - делим длину, ширину и высоту параллелепипеда пополам и перемещаем полученную точку в точку с координатами (0,0,0). Затем последовательно строим каждую грань по четырем вершинам, для первой вершины рассчитываем нормаль как векторное произведение двух ребер параллелограмма, исходящих из этой вершины. Функция построения параллелограмма (код для наглядности не оптимизирован):

; #########################################################################
SolidBox PROC ListNumber:DWORD,Leng:DWORD,Wid:DWORD,Hei:DWORD
LOCAL nLn:DWORD,nWd:DWORD,nHg:DWORD
LOCAL pLn:DWORD,pWd:DWORD,pHg:DWORD


fld [Leng]
fdiv [dva]
fst [pLn]
fld [pLn]
fchs
fst [nLn]


fld [Wid]
fdiv [dva]
fst [pWd]

fld [pWd]
fchs
fst [nWd]

fld [Hei]
fdiv [dva]
fst [pHg]

fld [pHg]
fchs
fst [nHg]

invoke glNewList,ListNumber,GL_COMPILE_AND_EXECUTE
invoke glEnable,GL_COLOR_MATERIAL
invoke glBegin,GL_QUADS


invoke Normals,DWORD PTR nLn,DWORD PTR nWd,DWORD PTR nHg,DWORD PTR pLn,DWORD PTR nWd,DWORD PTR nHg,DWORD PTR pLn,DWORD PTR pWd,DWORD PTR nHg

invoke glVertex3f,DWORD PTR nLn,DWORD PTR nWd,DWORD PTR nHg
invoke glVertex3f,DWORD PTR pLn,DWORD PTR nWd,DWORD PTR nHg
invoke glVertex3f,DWORD PTR pLn,DWORD PTR pWd,DWORD PTR nHg
invoke glVertex3f,DWORD PTR nLn,DWORD PTR pWd,DWORD PTR nHg


invoke Normals,DWORD PTR nLn,DWORD PTR nWd,DWORD PTR nHg,DWORD PTR nLn,DWORD PTR nWd,DWORD PTR pHg,DWORD PTR nLn,DWORD PTR pWd,DWORD PTR pHg

invoke glVertex3f,DWORD PTR nLn,DWORD PTR nWd,DWORD PTR nHg
invoke glVertex3f,DWORD PTR nLn,DWORD PTR nWd,DWORD PTR pHg
invoke glVertex3f,DWORD PTR nLn,DWORD PTR pWd,DWORD PTR pHg
invoke glVertex3f,DWORD PTR nLn,DWORD PTR pWd,DWORD PTR nHg

invoke Normals,DWORD PTR nLn,DWORD PTR nWd,DWORD PTR nHg,DWORD PTR pLn,DWORD PTR nWd,DWORD PTR nHg,DWORD PTR pLn,DWORD PTR nWd,DWORD PTR pHg

invoke glVertex3f,DWORD PTR nLn,DWORD PTR nWd,DWORD PTR nHg
invoke glVertex3f,DWORD PTR pLn,DWORD PTR nWd,DWORD PTR nHg
invoke glVertex3f,DWORD PTR pLn,DWORD PTR nWd,DWORD PTR pHg
invoke glVertex3f,DWORD PTR nLn,DWORD PTR nWd,DWORD PTR pHg


invoke Normals,DWORD PTR nLn,DWORD PTR pWd,DWORD PTR nHg,DWORD PTR pLn,DWORD PTR pWd,DWORD PTR nHg,DWORD PTR pLn,DWORD PTR pWd,DWORD PTR pHg

invoke glVertex3f,DWORD PTR nLn,DWORD PTR pWd,DWORD PTR nHg
invoke glVertex3f,DWORD PTR pLn,DWORD PTR pWd,DWORD PTR nHg
invoke glVertex3f,DWORD PTR pLn,DWORD PTR pWd,DWORD PTR pHg
invoke glVertex3f,DWORD PTR nLn,DWORD PTR pWd,DWORD PTR pHg


invoke Normals,DWORD PTR pLn,DWORD PTR nWd,DWORD PTR nHg,DWORD PTR pLn,DWORD PTR nWd,DWORD PTR pHg,DWORD PTR pLn,DWORD PTR pWd,DWORD PTR pHg

invoke glVertex3f,DWORD PTR pLn,DWORD PTR nWd,DWORD PTR nHg
invoke glVertex3f,DWORD PTR pLn,DWORD PTR nWd,DWORD PTR pHg
invoke glVertex3f,DWORD PTR pLn,DWORD PTR pWd,DWORD PTR pHg
invoke glVertex3f,DWORD PTR pLn,DWORD PTR pWd,DWORD PTR nHg



invoke Normals,DWORD PTR pLn,DWORD PTR nWd,DWORD PTR pHg,DWORD PTR nLn,DWORD PTR nWd,DWORD PTR pHg,DWORD PTR nLn,DWORD PTR pWd,DWORD PTR pHg

invoke glVertex3f,DWORD PTR pLn,DWORD PTR nWd,DWORD PTR pHg
invoke glVertex3f,DWORD PTR nLn,DWORD PTR nWd,DWORD PTR pHg
invoke glVertex3f,DWORD PTR nLn,DWORD PTR pWd,DWORD PTR pHg
invoke glVertex3f,DWORD PTR pLn,DWORD PTR pWd,DWORD PTR pHg

invoke glEnd
invoke glEndList


ret
SolidBox ENDP

; #########################################################################

Прототип функции:

SolidBox PROTO :DWORD,:DWORD,:DWORD,:DWORD

Функция для нормалей (расчет векторного произведения), нормаль к вершине строится непосредственно в самой функции:

; #########################################################################
Normals PROC x0:DWORD,y0:DWORD,z0:DWORD,\
x1:DWORD,y1:DWORD,z1:DWORD,\
x2:DWORD,y2:DWORD,z2:DWORD

LOCAL xn:DWORD,yn:DWORD,zn:DWORD
LOCAL xi1:DWORD,yi1:DWORD,zi1:DWORD,xi2:DWORD,yi2:DWORD,zi2:DWORD

fld[x1]
fsub[x0]
fst[xi1]

finit
fld[y1]
fsub[y0]
fst[yi1]

finit
fld[z1]
fsub[z0]
fst[zi1]


finit
fld[x2]
fsub[x0]
fst[xi2]

finit
fld[y2]
fsub[y0]
fst[yi2]

finit
fld[z2]
fsub[z0]
fst[zi2]

finit

invoke Determinant,zi1,yi1,zi2,yi2,ADDR xn
invoke Determinant,xi1,zi1,xi2,zi2,ADDR yn
invoke Determinant,yi1,xi1,yi2,xi2,ADDR zn

invoke glNormal3f,DWORD PTR xn,DWORD PTR yn,DWORD PTR zn

ret
Normals ENDP

; #########################################################################

Прототип функции:

Normals PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD

Вспомогательная функция - вычисление определителя второго порядка:

; #########################################################################
Determinant PROC x1:DWORD,y1:DWORD,x2:DWORD,y2:DWORD,Number:DWORD
LOCAL tmpval:DWORD
finit
fld[x2]
fmul[y1]
fst[tmpval]
fld[x1]
fmul[y2]
fsub[tmpval]
mov eax,Number
fst DWORD PTR [eax]
ret
Determinant ENDP
; #########################################################################

Прототип функции:

Determinant PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD

Текстурные координаты, если необходимо, можно добавить в функцию SolidBox одновременно с определением координат вершин. Константа, необходимая для работы функций, объявлена в примере как глобальная (может быть и локальная) и типа float (но можно и integer, но тогда нужно немного изменить функции, заменив деление типа float на целочисленное):

dva dd 2.0

Пример программы, использующей эти функции:

Скачать исходники и ехе-файл.

©   Короленко М.В., 2011       
Перепечатка материалов возможна только после согласования с автором при условии обязательной ссылки на сайт