News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Can't get a rendering context, wglCreateContext fails

Started by hamper, November 11, 2013, 10:30:52 PM

Previous topic - Next topic

qWord

When applying drizz's and jj's hints, the latest code does work. However, I strongly suggest to use a timer for drawing  :t
MREAL macros - when you need floating point arithmetic while assembling!

jj2007

Quote from: qWord on November 13, 2013, 09:12:42 AMI strongly suggest to use a timer for drawing  :t

Yes, the PeekMessage hack blocks normal message processing. On the other hand, a timer will slow it down. Perhaps a GetMessage (and WM_TIMER) per every 100 PeekMessage?

Quote from: drizz on November 12, 2013, 09:04:55 AM
You need to use functions from gdi32.dll ChoosePixelformat() SetPixelformat() instead of wgl prefixed ones.

The wql versions work, see attachment to my previous post.

qWord

I would simply use WM_TIMER and use a common message loop.

EDIT:
Quote from: jj2007 on November 13, 2013, 09:15:48 AMThe wql versions work, see attachment to my previous post.
It doesn't work on Win7, x64. (probably depends on the GC driver) EDIT2: it does work
MREAL macros - when you need floating point arithmetic while assembling!

jj2007

OK, if the plain GDI versions work on 7-64, then I stand corrected :icon14:

qWord

Quote from: jj2007 on November 13, 2013, 09:24:23 AM
OK, if the plain GDI versions work on 7-64, then I stand corrected :icon14:
sorry, I've execute it in the AV's Sandbox - wgl version also runs here.

A version with timer:
;--------------------------------------------------------------------------------------
; An OpenGL example                                                      opengltest.asm
;--------------------------------------------------------------------------------------

.686
.model flat,stdcall
option casemap:none

includelib user32
includelib kernel32
includelib opengl32
includelib gdi32
includelib winmm

;--------------------------------------------------------------------------------------

CreateWindowExA      proto :dword,:dword,:dword,:dword,:dword,:dword,
                           :dword,:dword,:dword,:dword,:dword,:dword
DefWindowProcA       proto :dword,:dword,:dword,:dword
DispatchMessageA     proto :dword
ExitProcess          proto :dword
GetModuleHandleA     proto :dword
LoadCursorA          proto :dword,:dword
LoadIconA            proto :dword,:dword
PeekMessageA         proto :dword,:dword,:dword,:dword,:dword
PostQuitMessage      proto :dword
RegisterClassExA     proto :dword
windowproc           proto :dword,:dword,:dword,:dword
GetDC                proto :dword
ChoosePixelFormat    proto :dword,:dword
SetPixelFormat       proto :dword,:sdword,:dword
wglCreateContext     proto :dword
wglMakeCurrent       proto :dword,:dword
wglDeleteContext     proto :dword
ReleaseDC            proto :dword,:dword
glViewport           proto :sdword,:sdword,:sdword,:sdword
glMatrixMode         proto :dword
glOrtho              proto :real8,:real8,:real8,:real8,:real8,:real8
glClearColor         proto :real4,:real4,:real4,:real4
glClear              proto :dword
glPushMatrix         proto
glPopMatrix          proto
glRotatef            proto :real4,:real4,:real4,:real4
glBegin              proto :dword
glEnd                proto
glColor3fv           proto :dword
glVertex3fv          proto :dword
glFlush              proto
wglSwapBuffers       proto :dword
rendernextframe      proto
SetTimer proto :DWORD,:DWORD,:DWORD,:DWORD
timeBeginPeriod proto :DWORD
GetMessageA proto :DWORD,:DWORD,:DWORD,:DWORD
timeEndPeriod proto :DWORD

point struct
   x dword ?
   y dword ?
point ends

msgst struct
   hwnd    dword ?
   message dword ?
   wparam  dword ?
   lparam  dword ?
   time    dword ?
   pt      point <>
msgst ends

windowclasstype struct
   wcsize        dword ?
   style         dword ?
   addrwp        dword ?
   classeb       dword ?
   windoweb      dword ?
   proghandle    dword ?
   liconhandle   dword ?
   cursorhandle  dword ?
   colour        dword ?
   menuhandle    dword ?
   addrclassname dword ?
   siconhandle   dword ?
windowclasstype ends

pfdtype struct
   nsize           word  40
   nversion        word  1
   dwflags         dword 4133
   ipixeltype      byte  0
   ccolorbits      byte  32
   credbits        byte  0
   credshift       byte  0
   cgreenbits      byte  0
   cgreenshift     byte  0
   cbluebits       byte  0
   cblueshift      byte  0
   calphabits      byte  0
   calphashift     byte  0
   caccumbits      byte  0
   caccumredbits   byte  0
   caccumgreenbits byte  0
   caccumbluebits  byte  0
   caccumalphabits byte  0
   cdepthbits      byte  32
   cstencilbits    byte  0
   cauxbuffers     byte  0
   ilayertype      byte  0
   breserved       byte  0
   dwlayermask     dword 0
   dwvisiblemask   dword 0
   dwdamagemask    dword 0
pfdtype ends

;--------------------------------------------------------------------------------------

.const
classname   byte "SimpleWinClass",0
windowtitle byte "The window title",0

.data?
msg        msgst <>
mywc       windowclasstype <>
winhandle  dword ?
dchandle   dword ?
rchandle   dword ?

.data
pfd        pfdtype <>
myortho    real8 1.0,1.0,-1.0,1.3,0.5,1.5
mybgcolour real4 0.0,0.0,0.0,1.0
myrot      real4 0.0,0.0,0.0,1.0
myrotsdw   sdword 0
myvertices real4 0.0,1.0,1.0,0.87,-0.5,1.0,-0.87,-0.5,1.0
mycolours  real4 1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0

.code
start:

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

;---------- fill up the window class structure variable and get the program handle etc.

mov mywc.wcsize,48
mov mywc.style,35
mov mywc.addrwp,offset windowproc
mov mywc.classeb,0
mov mywc.windoweb,0
push 0
call GetModuleHandleA
mov mywc.proghandle,eax
push 32515
push 0
call LoadIconA
mov mywc.liconhandle,eax
mov mywc.siconhandle,eax
push 32515
push 0
call LoadCursorA
mov mywc.cursorhandle,eax
mov mywc.colour,2
mov mywc.menuhandle,0
mov mywc.addrclassname,offset classname

;---------- register the window class

push offset mywc
call RegisterClassExA

;---------- create and display the window

push 0
push mywc.proghandle
push 0
push 0
push 340         ; window height
push 320         ; window width
push 230         ; window top position
push 480         ; window left position
push 269418496
push offset windowtitle
push mywc.addrclassname
push 0
call CreateWindowExA
mov winhandle,eax

;---------- the message loop

msgloopstart:
   invoke GetMessageA,OFFSET msg,0,0,0
   test eax,eax
   jz msgloopend
   push offset msg
   call DispatchMessageA
   jmp msgloopstart
msgloopend:
   push rchandle
   call wglDeleteContext
   push dchandle
   push winhandle
   call ReleaseDC
   push 0
   call ExitProcess

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

;---------- the window procedure

windowproc proc hwnd:dword,message:dword,wparam:dword,lparam:dword

      cmp message,1           ; WM_CREATE
      je initialiseopengl
      cmp message,16          ; WM_CLOSE
      je closeprogram
      cmp message,113h ; WM_TIMER
      je WM_TIMER
     
   ; default processing
      push lparam
      push wparam
      push message
      push hwnd
      call DefWindowProcA
      ret
   initialiseopengl:
      push hwnd
      call GetDC
      mov dchandle,eax
      push offset pfd
      push dchandle
      call ChoosePixelFormat
      push offset pfd
      push eax
      push dchandle
      call SetPixelFormat
      push dchandle
      call wglCreateContext
      mov rchandle,eax
      push rchandle
      push dchandle
      call wglMakeCurrent
      push 5889
      call glMatrixMode     ; projection matrix stack
      push 300              ; height
      push 300              ; width
      push 10               ; y
      push 10               ; x
      call glViewport
      push dword ptr myortho[44]   ; myortho real8 1.0,1.0,-1.0,1.3,0.5,1.5
      push dword ptr myortho[40]
      push dword ptr myortho[36]
      push dword ptr myortho[32]
      push dword ptr myortho[28]
      push dword ptr myortho[24]
      push dword ptr myortho[20]
      push dword ptr myortho[16]
      push dword ptr myortho[12]
      push dword ptr myortho[8]
      push dword ptr myortho[4]
      push dword ptr myortho
      call glOrtho
      push 5888
      call glMatrixMode     ; modelview matrix stack
      push mybgcolour[12]   ; mybgcolour real4 0.0,0.0,0.0,1.0   ; black
      push mybgcolour[8]
      push mybgcolour[4]
      push mybgcolour
      call glClearColor
      invoke timeBeginPeriod,1
      invoke SetTimer,hwnd,100,10,0
      ret
   closeprogram:
     
      invoke timeEndPeriod,1
      push 0
      call PostQuitMessage
      ret
WM_TIMER:
call rendernextframe
  ret

windowproc endp

;---------- the rendering procedure

rendernextframe proc

      push 16384
      call glClear                 ; clear window to background colour
      call glPushMatrix            ; push the matrix stack
      inc myrotsdw                 ; perform any translations, scales, rotations etc.
      cmp myrotsdw,360
      jne carryon
      mov myrotsdw,0
   carryon:
      finit
      fild myrotsdw
      fst myrot
      push myrot[12]
      push myrot[8]
      push myrot[4]
      push myrot
      call glRotatef
      push 4
      call glBegin                 ; draw objects anew
      push offset mycolours
      call glColor3fv
      push offset myvertices
      call glVertex3fv
      push offset mycolours[12]
      call glColor3fv
      push offset myvertices[12]
      call glVertex3fv
      push offset mycolours[24]
      call glColor3fv
      push offset myvertices[24]
      call glVertex3fv
      call glEnd
      call glFlush
      call glPopMatrix             ; pop the matrix stack
      push dchandle
      call wglSwapBuffers          ; swap buffers
      ret

rendernextframe endp

;--------------------------------------------------------------------------------------

end start
MREAL macros - when you need floating point arithmetic while assembling!

jj2007

Quote from: qWord on November 13, 2013, 09:38:25 AM
A version with timer

Looks fine but seems ca. 20..50 times slower. If you choose 1ms instead of 10, does it become as fast as the PeekMessage version?

qWord

Quote from: jj2007 on November 13, 2013, 09:52:42 AM
Quote from: qWord on November 13, 2013, 09:38:25 AM
A version with timer

Looks fine but seems ca. 20..50 times slower. If you choose 1ms instead of 10, does it become as fast as the PeekMessage version?
for what does we need so much FPS?
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

the system timer resolution is typically 10 to 16 ms
but, that should be fast enough

when i try hitchhikr's example in the masm32 package, it runs like a kitten on crack - lol

dedndave

Quote from: hamper on November 13, 2013, 07:59:30 AM
....But here is my latest version, just in case anyone is actually interested in trying to help me find out where the problem is, as opposed to just berating my programming style, trying to be slick and funny, or promoting software that's nothing to do with the subject of this thread. But I'm not holding my breath. I'll give it a couple of days to see if this forum is actually capable of helping solve my problem. If not, then my assembly notes, C notes, API notes and OpenGL notes are all going on the fire, condemned to the "what a complete waste of time all that was" tray.

if you don't want to proceed at the pace we are moving, don't let the door hit you in the ass
you talk as though we are on your payroll or something
if you don't like assembly language, it's not our problem

on the other hand, we all like to "learn as we go"
have some patience, and you'll probably be pleased with the results

qWord

Quote from: dedndave on November 13, 2013, 10:04:12 AM
the system timer resolution is typically 10 to 16 ms
but, that should be fast enough
if someone is not happy with that, timeBegin/EndPeriod() allows resolution up to 1ms (as used above).
Quote from: dedndave on November 13, 2013, 10:04:12 AMwhen i try hitchhikr's example in the masm32 package, it runs like a kitten on crack - lol
that is a misconstruction you can fined in many 3D examples. The animation speed should be bound with the time and not the CPU/GPU speed.
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

well - as i browsed through that code, i saw the call in the message loop
and - i wasn't pleased with that - something i would do differently, if i were to use that code

but, the program does function - so Franck has that much going on   :P
something else i didn't care for.....
he uses GetDC in WM_CREATE, then in WM_CLOSE he finally releases it
i doubt that's a requirement for OpenGL
the wglCreateContext likely uses that DC as a reference to create a compatible DC
after that, the original DC can be released
also - it could just as well be the desktop DC

dedndave

qWord's "foo" version works nicely, here   :t

at least, it works with my current build:


jj2007

#57
I'm also not happy with the PeekMessage approach, but if the OP wants hi speed, it's so far the only one that does the job. The way to go is probably WM_TIMER with a proc as last para, where the proc performs 100 or so renderings. Up to hamper to decide.

One remark regarding the code attached in reply 44: wglChoosePixelFormat throws error "can't find the specified procedure"; that must be an internal error, because the returned value (4) works perfectly.

P.S.: Just noticed that on Win7-32, it runs much, much slower than on WinXP. It's a factor 20...50, and the Win7 machine is faster than my XP machine, so it must be something OS-related ::)

Besides, the wglChoosePixelFormat internal error is no longer present on Win7; it returns 7 (instead of 4; ChoosePixelFormat returns 1), and GetLastError returns zero.
However, if you use
      push offset pfd
      push 4   ; eax
      push dchandle
      call SetPixelFormat

i.e. the value that ChoosePixelFormat returns on XP, then suddenly the rendering becomes as fast as on XP. So it seems that the "internal" error is responsible for the difference in speed. I'd call that a bug in OpenGL, unless somebody else spots a feature in this, of course :icon_mrgreen:

Quote from: dedndave on November 13, 2013, 10:22:25 AM
the wglCreateContext likely uses that DC as a reference to create a compatible DC
after that, the original DC can be released

You would pass a released handle to wglMakeCurrent. It works, but still, better to place the release after wglMakeCurrent (tested OK).

dedndave

well - that's essentially what i meant - you caught me mis-speaking - lol
if you look at my first posted code...
the ReleaseDC is at the end of the WM_CREATE handler code, after wglMakeCurrent
in some of the example code i have looked at, it's released in WM_CLOSE   :P
hamper's code releases it after the message loop, before ExitProcess - a bit strange
but, the init code was originally before the message loop in the main proc

i prefer to do creation in WM_CREATE, and clean-up in WM_DESTROY
in the case of that DC, though, it need not be retained for the life of the process

a while back, drizz pointed us to:
http://www.opengl.org/archives/resources/faq/technical/mswindows.htm
sections 5.190 to 5.210

it explains the difference between the wgl and GDI versions of these 5 functions:
ChoosePixelformat, DescribePixelformat, GetPixelformat, SetPixelformat, SwapBuffers
however, the document is a bit old - so things may have changed, over time
still, it's interesting to note the history
i am going to do as drizz and the document suggest, and use the GDI versions   :P
at least, until i see a reason for doing otherwise

it's a bit odd that qWord sets the timer resolution to 1 mS, then uses a 10 mS elapse time
but, he's pretty sharp - let's see how it goes without altering the resolution
i try to avoid changing the resolution unless i have to, because it affects other things

GoneFishing

I've found glGetError function , it takes no parameter and returns one of these:
from gl.h
Quote
/* ErrorCode */
#define GL_NO_ERROR                        0
#define GL_INVALID_ENUM                  0x0500
#define GL_INVALID_VALUE                 0x0501
#define GL_INVALID_OPERATION         0x0502
#define GL_STACK_OVERFLOW            0x0503
#define GL_STACK_UNDERFLOW          0x0504
#define GL_OUT_OF_MEMORY              0x0505