Simple quad program?
BlitzMax Forums/OpenGL Module/Simple quad program?
| ||
Can you draw a quad with GL_QUADS without using openGL stuff to set a context (i.e. just draw it on a screen open with the graphics command)? If so, anyone got some example code; I can't get it to work. |
| ||
Yes, but if you want to use textures you might have problems. Graphics sets the viewport to the current screen co-ordinates, remember. The default OpenGL viewport with bglCreateContext is -1,-1 to 1,1. |
| ||
tea - why may there be a problem texturing? I tried drawing a quad using screen coords and couldn't see it. Any ideas? |
| ||
Drawing in Max2D and drawing in 'pure GL' using screen coordinates:' Mode1 is pretty much the same as Mode2, except in Mode1 ' the states are set up for you and transformations are ' performed in DrawRect, no transformations are performed ' in Mode2 for the sake of simplicity Goto Mode1 ' Pure Max2D #Mode1 Graphics 800,600,0,0 While Not KeyDown(KEY_ESCAPE) Cls() SetColor(255,255,255) DrawRect(GraphicsWidth()*.5-64,GraphicsHeight()*.5-64,128,128) Flip() FlushMem Wend End ' Pure GL #Mode2 bglCreateContext(800,600,0,0,BGL_BACKBUFFER | BGL_DEPTHBUFFER) glOrtho(0,800,0,600,-10,10) While Not KeyDown(KEY_ESCAPE) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glBegin(GL_QUADS) glVertex2f(400-64,300-64) glVertex2f(400+64,300-64) glVertex2f(400+64,300+64) glVertex2f(400-64,300+64) glEnd() bglSwapBuffers() FlushMem Wend End The problem you might run into with textures is that Max2D stores its own texture state variables and has its own functions for binding GL textures, but these functions aren't exposed, so basically, if you want to use GL and Max2D, you're screwed. |
| ||
Noel, as was explained to you before, it is simple a case of making sure you preserve the state of the OpenGL machine, if you want to use GLBindTexture in your own code then you need to restore it's previous state at the end of your code if you want to play nicely with Max2D, just like transformation and everything else. |
| ||
skid: Or the functions that would make that much easier could be exposed. What do you think sounds easier? Edit: Let's look at your options.. 1. Tell users to write code to save the GL state and then restore it afterwards. 2. Remove the line that says 'Private' in the GlMax2D code. 3. Don't respond. What do you think sounds best in the long run? If you picked 1 or 3, you should seek help immediately. If you picked 2, you win a cookie the instant you make the change. |
| ||
i agree with the one called cower, your not meant to fight the users, your meant to help the users |
| ||
Adding GL specific interfaces would simply pollute GLMax2D in the same way as adding DX specific public functions to DXMax2D. IMHO it is just as simple, more optimal and allows more flexibility for people banging GL directly to learn to restore it's state when sharing with GLMax2D. |
| ||
I think skidracer has a point. If there is going to be a DX 2d lib (dear god say its true!!) compatability would be good to keep |
| ||
Then how about, instead of making a 2D and 3D modules seperate, you build a base device class that the engine and 2D modules expand upon? I'm doing this for my engine, and it's not hard. |
| ||
You mean the driver class which actually exists? |
| ||
skidracer: I do agree with you there (however many times I tried to twist it around as a 'bad thing' in my book, it doesn't work), and thus if (probably worth it to continue reading, 'cause that's a big 'if' there) I decide to continue using Max2D I'll just modify it and expose the functions. Or not use Max2D. Which would probably be easier in the long run as then I wouldn't have to deal with its peculiar nuances. Dreamora: It's not intended for anything beyond simple 2D application. Look at the source, it's obvious that they weren't thinking ahead when designing Max2D and Max3D as Max3D is going to have -another- device class which will then make the Max2D driver utterly useless to have. So what I think is neccessary is that if Blitz Research are going to use hardware acceleration primarily in their 2D system is to write a device class that has 2D and 3D functionality (general functionality, not full blown engine type but rather like the Direct3D Device class, it has DrawPrimitives, states, and such that can be modified via methods) and then Max2D and Max3D should be written to use this device class instead of depending on their own seperate device (or drivers as Mark calls them) classes. The aforementioned device class proposed would obviously require writing new math classes which -- assuming Mark wouldn't go insane -- would be there for users to use and abuse the device class(es) with. On another note (I say that way too much), I've been thinking about deleting Brl's Max2D and GLMax2D modules (and any others that depend on them) just because they aren't worth the trouble and then rewriting it in my own way that isn't as ack basswards and instead mimics a full 2D and 3D device class (similar to the Managed DirectX Direct3D Device class, in a sense). Actually, I've already done the device class, it's still a work in progress though.. Type CDevice Abstract Field Indices:Int[] Field Vertices:CVertex[] Field Material:CMaterial Field Width:Int,Height:Int Method ClearColor(R#,G#,B#,A#) Abstract Method SetViewport(X%,Y%,Width%,Height%) Abstract Method GetViewport(X:Int Ptr, Y:Int Ptr, _Width:Int Ptr, _Height:Int Ptr) Abstract Method DrawPrimitives(PrimitiveType:Int) Abstract Method SetVertexData(Indices:Int[],Vertices:CVertex[]) Abstract Method Clear(Enum:Int = CBuffers.Color | CBuffers.Depth) Abstract Method Present() Abstract Method SetWorldMatrix(mat:CMatrix) Abstract Method SetViewMatrix(mat:CMatrix) Abstract Method SetProjectionMatrix(mat:CMatrix) Abstract Method GetWorldMatrix:CMatrix() Abstract Method GetViewMatrix:CMatrix() Abstract Method GetProjectionMatrix:CMatrix() Abstract Method FreeObjectResources(i:Object) Abstract Method LoadObjectResources(i:Object) Abstract Method LoadVertexShader:CVertexShader(path$) Abstract Method LoadPixelShader:CPixelShader(path$) Abstract Method BindShader(i:CShader) Abstract Method BindTexture(i:CTexture) Abstract ' Get this.. CEngine_Global_Device is.. PUBLIC! Oh, my god, Becky. Method SetActiveDevice() CEngine_Global_Device = Self End Method Function GetActiveDevice:CDevice() Return CEngine_Global_Device End Function End Type At the moment, I have that working with OpenGL and I'm working on a software renderer for it now (wrapped SDL's 2D functions and such into a nice neat package so no hardware acceleration is required -- yes folks, I added 'real 2D', it's actually faster than normal Blitz2D/Plus stuff too). |
| ||
Noel : Thanx for the OGL/Max example. Skid: Could you give an example or point me in the drection of a thread on restoring the OGL machine state? |
| ||
I'm not exactly experienced with OpenGL but from what I have seen in BlitzMax so far, if you are going to mess with glBindtexture GL_TEXTURE_2D then you need to save and restore the current state like this:glGetIntegerv GL_TEXTURE_BINDING_2D,VarPtr old_name .. your code here glBindTexture GL_TEXTURE_2D,old_name and to save and restore the matrix transformation I beleive you need to use the glPushMatrix and glPopMatrix commands. |
| ||
I don't agree that Max2D is 'ass-backwards' (because it's clearly not) but it does make it difficult for third parties to make modules that extend it or are based on it. Essentially you have to rewrite the entire driver if you want to do something simple but different. This is a problem when: * The official Max2D and glMax2D modules are updated * You want to distribute the modified driver (based on the original driver code) with your module - the BlitzMax licence isn't clear whether you're legally allowed to do that. Including a state lock/state restore function in Max2D would be wonderful for third-party developers. It doesn't solve all the problems, but it solves a lot of them. Something like this (not thoroughly tested): Strict Import pub.opengl Import brl.glmax2d Private Global lock_gl_texture_2d:Int Global lock_gl_texture_binding_2d:Int Global lock_blendstate:Int Global lock_rgba:Byte[4] Public Rem bbdoc: Locks the gl state so you can use OpenGL functions with glMax2D. You can use native OpenGL functions between LockGL() and UnlockGL(). All Max2D commands <u>must</u> be called outside of those functions. Be nice with your OpenGL and clean up after yourself before calling UnlockGL(). These functions rely on Max2D working in a specific way - if the Max2D internals break, these functions will need to be updated. Note that Graphics() does not initialise the depth buffer. End Rem Function LockGL() lock_blendstate = GetBlend() Local r:Int, g:Int, b:Int, a:Int a = GetAlpha()*255# If(a>255) Then a=255 If(a<0) Then a=0 GetColor(r, g, b) lock_rgba[0] = Byte(r) lock_rgba[1] = Byte(g) lock_rgba[2] = Byte(b) lock_rgba[3] = Byte(a) glPushMatrix() glGetBooleanv(GL_TEXTURE_2D, Varptr lock_gl_texture_2d) glGetIntegerv(GL_TEXTURE_BINDING_2D, Varptr lock_gl_texture_binding_2d) End Function Rem bbdoc: Unlock the OpenGL state so Max2D can use it again End Rem Function UnlockGL() glBindTexture(GL_TEXTURE_2D,lock_gl_texture_binding_2d) If(lock_gl_texture_2d) glEnable(GL_TEXTURE_2D) Else glDisable(GL_TEXTURE_2D) EndIf glPopMatrix() SetBlend(lock_blendstate) glColor4ubv(lock_rgba) End Function That only stores some of the texture functions and the colour/alpha settings though - there's many other state variables that you can store, but many of them are very slow. |
| ||
Nice one TMonkey - I'll have a play with that later. |