· Начало · Статистика · WASM.RU · Noir.Ru ·

 WASM Phorum (Оффлайн - 24.11.2003) —› WASM.DIRECTX.OPENGL —› OpenGL, DoubleBuffer & WM_TOPMOST

Посл.отвђт Сообщенiе


Дата: Ноя 1, 2003 00:49:16

Ниже приведенная программа создает окно на весь экран, инициализирует OpenGL, а затем, когда нет никаких сообщений, рисует в нем линию. Если переключится по Alt+Tab'у на какое нибудь другое окно, а затем обратно, то количество кадров значительно падает. Похоже это происходит из за того что отключается аппаратный двойной буфер. Я нашел способ это исправить - WS_EX_TOPMOST, но при этом окно нельзя свернуть. В обработчике нажатия левой кнопки окно перемещается поверх всех, чтобы аппаратный двойной буфер снова включился, а затем возвращается обратно, чтобы можно было его свернуть или переключится на другую программу.
Требуется поймать момент когда окно программы оказывается поверх всех окон видимых окон. Кто-нибудь знает какое сообщение при этом отправляется? Пробовал WM_ACTIVATE, WM_MOUSEACTIVATE,WM_SETFOCUS - не помогает.

И еще вопрос: почему wglMakeCurrent не хочет работать в обработчике WM_CREATE? В книге И.А.Тарасова "Основы OpenGL" выбор формата пикселей, создание и выбор контекста осуществлялись именно при обоработке WM_CREATE.
include '%include%\win32ax.inc'

.data

hdc dd 0
hglrc dd 0
hwnd dd 0
wndclass db 'WndClassOGLTest',0
lasttime dd 0
framecnt dd 0
slen dd 0
buf rb 256


.code

wndproc:;(hwnd +4, msg +8, wp +12, lp +16)
virtual at esp
	dd ?
	.hwnd dd ?
	.msg dd ?
	.wp dd ?
	.lp dd ?
end virtual
	mov eax,[.msg]
	cmp eax,WM_LBUTTONDOWN
	jz .lbdown
	cmp eax,WM_SIZE
	jz .size
	cmp eax,WM_DESTROY
	jz .destroy
	jmp [DefWindowProc]
    .lbdown:
	invoke SetWindowPos,[24+.hwnd],HWND_TOPMOST,0,0,0,0,\
		SWP_NOMOVE+SWP_NOSIZE
	invoke SetWindowPos,[24+.hwnd],HWND_NOTOPMOST,0,0,0,0,\
		SWP_NOMOVE+SWP_NOSIZE
	ret 16
    .size:
	sub esp,16
	invoke GetWindowRect,[4+16+.hwnd],esp
	invoke glViewport
	ret 16
    .destroy:
	invoke PostQuitMessage,0
	ret 16

_display:;(this +4)
	push ebx
	push edi
	invoke TextOut,[hdc],0,0,buf,[slen]
	invoke glClear,GL_COLOR_BUFFER_BIT
	invoke glBegin,GL_LINES
	invoke glVertex3i,1,1,1
	invoke glVertex3i,-1,-1,-1
	invoke glEnd

	inc [framecnt]
	invoke GetTickCount
	mov ebx,eax
	sub ebx,[lasttime]
	cmp ebx,1000
	jb .next
	mov [lasttime],eax
	xor eax,eax	
	xchg eax,[framecnt]
	mul [.c1000]
	div ebx
	mov edi,buf
	call eaxtostr
	sub edi,buf+1
	mov [slen],edi
    .next:
	invoke wglGetCurrentDC
	invoke SwapBuffers,eax

	pop edi
	pop ebx	
	ret 4
    .c1000 dd 1000

eaxtostr:;(eax - num, edi-str) in 21 byte
	push 10		;2
	pop ecx		;1
	push -'0'	;2
    .l0:
	xor edx,edx	;2
	div ecx		;2
	push edx	;1
	test eax,eax	;2
	jnz .l0		;2
    .l1:
	pop eax		;1
	add al,'0'	;2
	stosb		;1
	jnz .l1		;2
	ret		;1

start:
	xor ebx,ebx
	invoke RegisterClass,esp,\
		CS_OWNDC,wndproc,\
		ebx,ebx,ebx,ebx,ebx,ebx,ebx,wndclass
	invoke GetDesktopWindow,  ebx,ebx,ebx,ebx
	sub esp,16
	invoke GetWindowRect,eax,esp
	invoke CreateWindowEx,WS_EX_TOPMOST,wndclass,0,\
		WS_POPUP+WS_VISIBLE+WS_CLIPCHILDREN+WS_CLIPSIBLINGS
	mov [hwnd],eax

	invoke GetDC,[hwnd]
	mov [hdc],eax
	xor ecx,ecx
	invoke ChoosePixelFormat,eax,esp,sizeof.PIXELFORMATDESCRIPTOR+10000h,\
		PFD_DRAW_TO_WINDOW+PFD_SUPPORT_OPENGL+PFD_DOUBLEBUFFER,\
		PFD_TYPE_RGBA+2000h,ecx,ecx,ecx,\
		PFD_MAIN_PLANE shl 16,ecx,ecx,ecx
	invoke SetPixelFormat,[hdc],eax,esp
	add esp,sizeof.PIXELFORMATDESCRIPTOR
	test eax,eax
	jz .exit
	invoke wglCreateContext,[hdc]
	mov [hglrc],eax
	invoke wglMakeCurrent,[hdc],eax

	sub esp,sizeof.MSG-40
    .getmessage:
	mov eax,esp
	invoke GetMessage,eax,ebx,ebx,ebx
	test eax,eax
	jz .exit
	invoke TranslateMessage,esp
	invoke DispatchMessage,esp
    .peekmessage:
	mov eax,esp
	invoke PeekMessage,eax,ebx,ebx,ebx,PM_NOREMOVE
	test eax,eax
	jnz .getmessage
	stdcall _display,0
	jmp .peekmessage
    .exit:
	invoke wglMakeCurrent,0,0
	invoke wglDeleteContext,[hglrc]
	invoke ReleaseDC,[hwnd],[hdc]
	add esp,sizeof.MSG
	ret

.end start


Дата: Ноя 8, 2003 10:18:06

Кто-нибудь знает какое сообщение при этом отправляется? Пробовал WM_ACTIVATE, WM_MOUSEACTIVATE,WM_SETFOCUS - не помогает.

Попробуй WM_WINDOWPOSCHANGED.


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.075