概要
中古ノート買ってみた。
windows10でfasmをやってみた。
OpenGL見つけたので、やってみた。
写真
サンプルコード
format PE64 NX GUI 5.0
entry start
include 'win64a.inc'
WGL_CONTEXT_MAJOR_VERSION_ARB = 0x2091
WGL_CONTEXT_MINOR_VERSION_ARB = 0x2092
GL_COLOR_BUFFER_BIT = 0x00004000
GL_TRIANGLES = 0x0004
GL_TRIANGLE_STRIP = 0x0005
GL_FLOAT = 0x1406
GL_ARRAY_BUFFER = 0x8892
GL_STATIC_DRAW = 0x88E4
GL_VERTEX_SHADER = 0x8B31
GL_FRAGMENT_SHADER = 0x8B30
GL_COMPILE_STATUS = 0x8B81
GL_LINK_STATUS = 0x8B82
irp name,\
glCreateShader,\
glShaderSource,\
glCompileShader,\
glGetShaderiv,\
glCreateProgram,\
glAttachShader,\
glLinkProgram,\
glGetProgramiv,\
glDeleteShader,\
glGenVertexArrays,\
glBindVertexArray,\
glGenBuffers,\
glBindBuffer,\
glBufferData,\
glVertexAttribPointer,\
glEnableVertexAttribArray,\
glUseProgram,\
glGetUniformLocation,\
glUniform1f,\
glUniform3f { define CONTEXT_AWARE_FUNCTION name }
section '.data' data readable writeable
wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,NULL,NULL,_class
attribs:
dd WGL_CONTEXT_MAJOR_VERSION_ARB, 3
dd WGL_CONTEXT_MINOR_VERSION_ARB, 3
dd 0
vertices:
dd 0.6, 0.6, 0f, 0f, 1f
dd -0.6, 0.6, 1f, 0f, 1f
dd 0.6, -0.6, 0f, 0f, 0f
dd -0.6, -0.6, 1f, 0f, 0f
thousand dd 1000.0
align 8
p_vs_src dq vs_src
p_fs_src dq fs_src
hdc dq ?
hrc dq ?
clock dq ?
msg MSG
rc RECT
pfd PIXELFORMATDESCRIPTOR
wglCreateContextAttribsARB dq ?
irpv name, CONTEXT_AWARE_FUNCTION { name dq ? }
vs_id dd ?
fs_id dd ?
program dd ?
vao dd ?
vbo dd ?
uTimeLoc dd ?
uResolutionLoc dd ?
section '.text' code readable executable
start:
sub rsp,8
invoke GetModuleHandle,0
mov [wc.hInstance],rax
invoke LoadIcon,0,IDI_APPLICATION
mov [wc.hIcon],rax
invoke LoadCursor,0,IDC_ARROW
mov [wc.hCursor],rax
invoke RegisterClass,wc
invoke CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_OVERLAPPEDWINDOW+WS_CLIPCHILDREN+WS_CLIPSIBLINGS,16,16,432,432,NULL,NULL,[wc.hInstance],NULL
msg_loop:
invoke GetMessage,addr msg,NULL,0,0
cmp eax,1
jb end_loop
jne msg_loop
invoke TranslateMessage,addr msg
invoke DispatchMessage,addr msg
jmp msg_loop
end_loop:
invoke ExitProcess,[msg.wParam]
proc WindowProc uses rbx rsi rdi, hwnd,wmsg,wparam,lparam
frame
mov [hwnd],rcx
cmp edx,WM_CREATE
je wmcreate
cmp edx,WM_SIZE
je wmsize
cmp edx,WM_PAINT
je wmpaint
cmp edx,WM_KEYDOWN
je wmkeydown
cmp edx,WM_DESTROY
je wmdestroy
defwndproc:
invoke DefWindowProc,rcx,rdx,r8,r9
jmp finish
wmcreate:
invoke GetDC,rcx
mov [hdc],rax
lea rdi,[pfd]
mov rcx,sizeof.PIXELFORMATDESCRIPTOR shr 3
xor eax,eax
rep stosq
mov [pfd.nSize],sizeof.PIXELFORMATDESCRIPTOR
mov [pfd.nVersion],1
mov [pfd.dwFlags],PFD_SUPPORT_OPENGL+PFD_DOUBLEBUFFER+PFD_DRAW_TO_WINDOW
mov [pfd.iLayerType],PFD_MAIN_PLANE
mov [pfd.iPixelType],PFD_TYPE_RGBA
mov [pfd.cColorBits],32
mov [pfd.cAlphaBits],8
mov [pfd.cDepthBits],24
mov [pfd.cStencilBits],8
invoke ChoosePixelFormat,[hdc],addr pfd
invoke SetPixelFormat,[hdc],eax,addr pfd
invoke wglCreateContext,[hdc]
test rax,rax
jz context_not_created
mov [hrc],rax
invoke wglMakeCurrent,[hdc],[hrc]
lea rbx,[_wglCreateContextAttribsARB] ; name pointer in rbx for error handler
invoke wglGetProcAddress,rbx
test rax,rax
jz function_not_supported
mov [wglCreateContextAttribsARB],rax
invoke wglDeleteContext,[hrc]
invoke wglCreateContextAttribsARB,[hdc],0,attribs
test rax,rax
jz context_not_created
mov [hrc],rax
invoke wglMakeCurrent,[hdc],[hrc]
irpv name, CONTEXT_AWARE_FUNCTION {
lea rbx,[_#name] ; name pointer in rbx for error handler
invoke wglGetProcAddress,rbx
test rax,rax
jz function_not_supported
mov [name],rax
}
invoke glCreateShader,GL_VERTEX_SHADER
mov [vs_id],eax
invoke glShaderSource,[vs_id],1,addr p_vs_src,0
invoke glCompileShader,[vs_id]
invoke glCreateShader,GL_FRAGMENT_SHADER
mov [fs_id],eax
invoke glShaderSource,[fs_id],1,addr p_fs_src,0
invoke glCompileShader,[fs_id]
invoke glCreateProgram
mov [program],eax
invoke glAttachShader,[program],[vs_id]
invoke glAttachShader,[program],[fs_id]
invoke glLinkProgram,[program]
invoke glDeleteShader,[vs_id]
invoke glDeleteShader,[fs_id]
invoke glUseProgram,[program]
invoke glGetUniformLocation,[program],uTime
mov [uTimeLoc],eax
invoke glGetUniformLocation,[program],uResolution
mov [uResolutionLoc],eax
invoke glGenVertexArrays,1,addr vao
invoke glBindVertexArray,[vao]
invoke glGenBuffers,1,addr vbo
invoke glBindBuffer,GL_ARRAY_BUFFER,[vbo]
invoke glBufferData,GL_ARRAY_BUFFER,4*5*4,addr vertices,GL_STATIC_DRAW
invoke glVertexAttribPointer,\ ; position
0,\ ; index, layout(location=0)
2,\ ; size(vec2)
GL_FLOAT,\ ; type
0,\ ; normalized
20,\ ; stride(bytes)
0 ; offset(bytes)
invoke glEnableVertexAttribArray,0
invoke glVertexAttribPointer,\ ; color
1,\ ; index, layout(location=1)
3,\ ; size(vec3)
GL_FLOAT,\ ; type
0,\ ; normalized
20,\ ; stride(bytes)
8 ; offset(bytes), skip vec2
invoke glEnableVertexAttribArray,1
wmsize:
invoke GetClientRect,[hwnd],addr rc
invoke glViewport,0,0,[rc.right],[rc.bottom]
cvtsi2ss xmm1,[rc.right]
cvtsi2ss xmm2,[rc.bottom]
invoke glUniform3f,[uResolutionLoc],float xmm1,float xmm2,float 1f
xor eax,eax
jmp finish
wmpaint:
invoke GetTickCount
mov rcx,rax
sub rcx,[clock]
cmp rcx,10 ; wait at least 10ms before drawing again
jb finish
mov [clock],rax
and eax,0FFFFFh
cvtsi2ss xmm1,rax
divss xmm1,[thousand]
invoke glUniform1f,[uTimeLoc],float xmm1
invoke glClearColor,float dword 0.02,float dword 0.02,float dword 0.04,float dword 1.0
invoke glClear,GL_COLOR_BUFFER_BIT
invoke glDrawArrays,GL_TRIANGLE_STRIP,0,4
invoke SwapBuffers,[hdc]
xor eax,eax
jmp finish
wmkeydown:
cmp r8d,VK_ESCAPE
jne defwndproc
wmdestroy:
invoke wglMakeCurrent,0,0
invoke wglDeleteContext,[hrc]
exit:
invoke ReleaseDC,[hwnd],[hdc]
invoke PostQuitMessage,0
xor eax,eax
finish:
ret
function_not_supported:
invoke MessageBox,[hwnd],_function_not_supported,rbx,MB_ICONERROR+MB_OK
jmp exit
context_not_created:
invoke MessageBox,[hwnd],_context_not_created,NULL,MB_ICONERROR+MB_OK
jmp exit
endf
endp
section '.rdata' data readable
_title db 'OpenGL 3.3',0
_class db 'OPENGL3FASM2',0
_function_not_supported db 'Function not supported.',0
_context_not_created db 'Failed to create OpenGL context.',0
_wglCreateContextAttribsARB db 'wglCreateContextAttribsARB',0
irpv name, CONTEXT_AWARE_FUNCTION { _#name db `name,0 }
vs_src file 'vertex.gls'
db 0
fs_src file 'fragment.gls'
db 0
uTime db 'iTime',0
uResolution db 'iResolution',0
align 8
data import
library kernel,'KERNEL32.DLL',\
user,'USER32.DLL',\
gdi,'GDI32.DLL',\
opengl,'OPENGL32.DLL'
import kernel,\
GetModuleHandle,'GetModuleHandleA',\
GetTickCount,'GetTickCount',\
ExitProcess,'ExitProcess'
import user,\
MessageBox,'MessageBoxA',\
RegisterClass,'RegisterClassA',\
CreateWindowEx,'CreateWindowExA',\
DefWindowProc,'DefWindowProcA',\
GetMessage,'GetMessageA',\
TranslateMessage,'TranslateMessage',\
DispatchMessage,'DispatchMessageA',\
LoadCursor,'LoadCursorA',\
LoadIcon,'LoadIconA',\
GetClientRect,'GetClientRect',\
GetDC,'GetDC',\
ReleaseDC,'ReleaseDC',\
PostQuitMessage,'PostQuitMessage'
import gdi,\
ChoosePixelFormat,'ChoosePixelFormat',\
SetPixelFormat,'SetPixelFormat',\
SwapBuffers,'SwapBuffers'
import opengl,\
glClear,'glClear',\
glClearColor,'glClearColor',\
glViewport,'glViewport',\
glDrawArrays,'glDrawArrays',\
wglGetProcAddress,'wglGetProcAddress',\
wglCreateContext,'wglCreateContext',\
wglDeleteContext,'wglDeleteContext',\
wglMakeCurrent,'wglMakeCurrent'
end data
以上。
