CHDIR "programs\samples\open_gl" DIM SHARED AllowSubGL 'we'll set this after we finish our setup immediately below, just in case 'there is anything here (there isn't currently though) that SUB _GL will depend on TYPE DONT_USE_GLH_Handle_TYPE in_use AS _BYTE handle AS LONG END TYPE REDIM SHARED DONT_USE_GLH_Handle(1000) AS DONT_USE_GLH_Handle_TYPE SCREEN _NEWIMAGE(1024, 768, 32) backdrop = _LOADIMAGE("xcom_backdrop.jpg") _PUTIMAGE , backdrop _FREEIMAGE backdrop _DONTBLEND LINE (200, 200)-(500, 500), _RGBA(0, 255, 255, 0), BF 'create a see-through window (press 1) _BLEND AllowSubGL = 1 DO 'This is our program's main loop _LIMIT 100 LOCATE 1, 1 c = c + 1: PRINT "Mainloop has done nothing"; c; "times" PRINT "Press 1[GL behind], 2[GL on top] or 3[GL only, good for speed] to switch rendering order." k$ = INKEY$ IF k$ = "1" THEN _GLRENDER _BEHIND IF k$ = "2" THEN _GLRENDER _ONTOP IF k$ = "3" THEN _GLRENDER _ONLY LOOP UNTIL k$ = CHR$(27) END 'this specially named sub "_GL" is detected by QB64 and adds support for OpenGL commands 'it is called automatically whenever the underlying software deems an update is possible 'usually/ideally, this is in sync with your monitor's refresh rate SUB _GL STATIC 'STATIC was used above to make all variables in this sub maintain their values between calls to this sub IF AllowSubGL = 0 THEN EXIT SUB 'we aren't ready yet! 'timing is everything, we don't know how fast the 3D renderer will call this sub to we use timers to smooth things out T# = TIMER(0.001) IF ETT# = 0 THEN ETT# = T# ET# = T# - ETT# ETT# = T# IF sub_gl_called = 0 THEN sub_gl_called = 1 'we only need to perform the following code once i = _LOADIMAGE("xcom256.png", 32) mytex = GLH_Image_to_Texture(i) 'this helper function converts the image to a texture _FREEIMAGE i END IF 'These settings affect how OpenGL will render our content '!!! THESE SETTINGS ARE TO SHOW HOW ALPHA CAN WORK, BUT IT IS 10x FASTER WHEN ALPHA OPTIONS ARE DISABLED !!! '*** every setting must be reset because SUB _GL cannot guarantee settings have not changed since last time *** _glMatrixMode _GL_PROJECTION 'Select The Projection Matrix _glLoadIdentity 'Reset The Projection Matrix _gluPerspective 45, _WIDTH(0) / _HEIGHT(0), 1, 100 'QB64 internally supports this GLU command for convenience sake, but does not support GLU _glEnable _GL_TEXTURE_2D _glEnable _GL_BLEND _glBlendFunc _GL_SRC_ALPHA, _GL_ONE_MINUS_SRC_ALPHA 'how alpha values are interpretted _glEnable _GL_DEPTH_TEST 'use the zbuffer _glDepthMask _GL_TRUE _glAlphaFunc _GL_GREATER, 0.5 'dont do anything if alpha isn't greater than 0.5 (or 128) _glEnable _GL_ALPHA_TEST _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MAG_FILTER, _GL_LINEAR _glTexParameteri _GL_TEXTURE_2D, _GL_TEXTURE_MIN_FILTER, _GL_LINEAR '************************************************************************************************************** GLH_Select_Texture mytex _glMatrixMode _GL_MODELVIEW 'Select The Modelview Matrix _glLoadIdentity 'Reset The Modelview Matrix _glTranslatef 0, 0, -10 'Translate Into The Screen _glRotatef rotation1, 0, 1, 0 'spin, spin, spin... _glRotatef rotation2, 1, 0, 0 _glBegin _GL_QUADS 'we will be drawing rectangles aka. QUADs _glTexCoord2f 0, 0: _glVertex3f 0, 0, 4 'the texture position and the position in 3D space of a vertex _glTexCoord2f 1, 0: _glVertex3f 5, 0, 4 _glTexCoord2f 1, 1: _glVertex3f 5, -5, 4 _glTexCoord2f 0, 1: _glVertex3f 0, -5, 4 _glEnd RANDOMIZE USING 1 'generate the same set of random numbers each time _glBegin _GL_TRIANGLES 'the png (almost) only consumes a triangular region of its rectangle FOR t = 1 TO 10 _glTexCoord2f 0, 0: _glVertex3f RND * 6 - 3, RND * 6 - 3, RND * 6 - 3 _glTexCoord2f 1, 0: _glVertex3f RND * 6 - 3, RND * 6 - 3, RND * 6 - 3 _glTexCoord2f 0.5, 1: _glVertex3f RND * 6 - 3, RND * 6 - 3, RND * 6 - 3 NEXT _glEnd rotation1 = rotation1 + 100 * ET# rotation2 = rotation2 + 200 * ET# END SUB 'QB64 OPEN-GL HELPER MACROS (aka. GLH macros) SUB GLH_Select_Texture (texture_handle AS LONG) 'turn an image handle into a texture handle IF texture_handle < 1 OR texture_handle > UBOUND(DONT_USE_GLH_HANDLE) THEN ERROR 258: EXIT FUNCTION IF DONT_USE_GLH_Handle(texture_handle).in_use = 0 THEN ERROR 258: EXIT FUNCTION _glBindTexture _GL_TEXTURE_2D, DONT_USE_GLH_Handle(texture_handle).handle END SUB FUNCTION GLH_Image_to_Texture (image_handle AS LONG) 'turn an image handle into a texture handle IF image_handle >= 0 THEN ERROR 258: EXIT FUNCTION 'don't allow screen pages DIM m AS _MEM m = _MEMIMAGE(image_handle) DIM h AS LONG h = DONT_USE_GLH_New_Texture_Handle GLH_Image_to_Texture = h _glBindTexture _GL_TEXTURE_2D, DONT_USE_GLH_Handle(h).handle _glTexImage2D _GL_TEXTURE_2D, 0, _GL_RGBA, _WIDTH(image_handle), _HEIGHT(image_handle), 0, &H80E1&&, _GL_UNSIGNED_BYTE, m.OFFSET _MEMFREE m END FUNCTION FUNCTION DONT_USE_GLH_New_Texture_Handle handle&& = 0 _glGenTextures 1, _OFFSET(handle&&) DONT_USE_GLH_New_Texture_Handle = handle&& FOR h = 1 TO UBOUND(DONT_USE_GLH_Handle) IF DONT_USE_GLH_Handle(h).in_use = 0 THEN DONT_USE_GLH_Handle(h).in_use = 1 DONT_USE_GLH_Handle(h).handle = handle&& DONT_USE_GLH_New_Texture_Handle = h EXIT FUNCTION END IF NEXT REDIM _PRESERVE DONT_USE_GLH_Handle(UBOUND(DONT_USE_GLH_HANDLE) * 2) AS DONT_USE_GLH_Handle_TYPE DONT_USE_GLH_Handle(h).in_use = 1 DONT_USE_GLH_Handle(h).handle = handle&& DONT_USE_GLH_New_Texture_Handle = h END FUNCTION