Post by xenovacivus on Aug 21, 2006 15:32:37 GMT -5
Here's a little demo simulating multiple OpenGL windows. It actually only uses one window but by clipping rectangles out and resetting the viewport, the effect is pretty much the same as having a bunch of openGL windows. I just figured out how to do this (late night coding yesterday), and thought it was pretty cool. I'm planning on using this type of thing to make a modeling program for the animated model format, but there's loads of other stuff it can be used for. One idea in particular was modifying a window into a simple text editor with saving capabilities, then load the file using the compilefile command and run it in another window. A mini Basic4GL IDE!!! I haven't played with the compilefile stuff yet, so not sure if it's possible... I'll look into it. Anyway, enjoy!
oh, and I'm still a little unsure of exactly how the text behaves... Apparently, if the text is clipped and scaled to fit into whatever the current viewport is, but DrawText () and Cls have to be called in each viewport while Swapbuffers () is only called once...
Please post any questions or comments!
' Lighting
dim LightAmbient#(3): LightAmbient# = vec4 (.5, 1, .5, 1)
dim LightDiffuse#(3): LightDiffuse# = vec4 (.5, 1, .5, 1)
dim LightPosition#(3):LightPosition# = vec4 (0, 10, 20, 1)
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient#) ' light thats always there.
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse#) ' light coming from a source.
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition#) ' where the light source is.
glEnable(GL_LIGHT1) ' enable the light source that was just created.
dim i
' Structure to hold information about the window-
struc swindow
dim frames ' how many times the window has been drawn
dim minimized ' state of the window
dim size#(1) ' x and y size (in pixels)
dim pos# (1) ' x and y position (in pixels, starting at lower left hand corner)
dim normalSize# (1) ' used to store size when minimized
dim mouse# (1) ' position of the mouse cursor on the window
endstruc
dim mouse# (1) ' mouse position
dim lastMouse# (1) ' mouse position previous frame
dim mouseDown (2) ' true if mouse is down
dim mouseClick(2) ' true if mouse is clicked
dim swindow window (10) ' array of windows
dim drawArray (10) ' array used to draw windows in order- recently used are drawn last (over the top of previous ones).
dim swindow &win ' pointer to a window structure- for simplifying code.
dim windowCount ' how many windows there are
dim activeWindow ' which window is currently active
dim ClosestClickedWindow' used to determine if another window was clicked on other than the active window.
goto Start
' Shortcut to the OpenGL Stuff For The Windows.
Draw3DWindow:
ResizeText (20, 15)
printr "3D OpenGL Windows!!!"
glTranslatef (0, 0, -10)
glRotatef (win.frames, 0, 1, 0)
glRotatef (win.frames*.1, 1, 0, 0)
' Draw a lighted cube
glEnable (GL_LIGHTING)
glBegin (GL_QUADS)
glNormal3f (0, 0, 1) : glVertex3f (-1, -1, 1)
glNormal3f (0, 0, 1) : glVertex3f (1, -1, 1)
glNormal3f (0, 0, 1) : glVertex3f (1, 1, 1)
glNormal3f (0, 0, 1) : glVertex3f (-1, 1, 1)
glNormal3f (0, 0, -1) : glVertex3f (1, 1, -1)
glNormal3f (0, 0, -1) : glVertex3f (1, -1, -1)
glNormal3f (0, 0, -1) : glVertex3f (-1, -1, -1)
glNormal3f (0, 0, -1) : glVertex3f (-1, 1, -1)
glNormal3f (1, 0, 0) : glVertex3f (1, 1, 1)
glNormal3f (1, 0, 0) : glVertex3f (1, -1, 1)
glNormal3f (1, 0, 0) : glVertex3f (1, -1, -1)
glNormal3f (1, 0, 0) : glVertex3f (1, 1, -1)
glNormal3f (-1, 0, 0) : glVertex3f (-1, 1, 1)
glNormal3f (-1, 0, 0) : glVertex3f (-1, -1, 1)
glNormal3f (-1, 0, 0) : glVertex3f (-1, -1, -1)
glNormal3f (-1, 0, 0) : glVertex3f (-1, 1, -1)
glNormal3f (0, 1, 0) : glVertex3f (-1, 1, -1)
glNormal3f (0, 1, 0) : glVertex3f (1, 1, -1)
glNormal3f (0, 1, 0) : glVertex3f (1, 1, 1)
glNormal3f (0, 1, 0) : glVertex3f (-1, 1, 1)
glNormal3f (0, -1, 0) : glVertex3f (-1, -1, -1)
glNormal3f (0, -1, 0) : glVertex3f (1, -1, -1)
glNormal3f (0, -1, 0) : glVertex3f (1, -1, 1)
glNormal3f (0, -1, 0) : glVertex3f (-1, -1, 1)
glEnd ()
glDisable (GL_LIGHTING)
return
start:
for i = 0 to 10
window (i).pos# = vec2 (i*20, i*20)
window (i).size# = vec2 (100 + i*20, 150)
drawArray (i) = i
next
windowCount = 11
TextMode (TEXT_OVERLAID)
while true
lastMouse# = mouse#
mouse#(0) = Mouse_X () * WindowWidth ()
mouse#(1) =(1-Mouse_Y())*WindowHeight()
if Mouse_Button (MOUSE_LBUTTON) then
if not mouseDown (MOUSE_LBUTTON) then
mouseDown (MOUSE_LBUTTON) = true
mouseClick(MOUSE_LBUTTON) = true
else
mouseClick(MOUSE_LBUTTON) = false
endif
else mouseDown (MOUSE_LBUTTON) = false
endif
if mouseDown (MOUSE_LBUTTON) then
&win = &window (activeWindow)
if mouseClick(MOUSE_LBUTTON) then
win.mouse# = mouse# - win.pos#
endif
if win.mouse#(0)>=0 and win.mouse#(1)>=0 and win.mouse#(0)<=win.size#(0) and win.mouse#(1)<=win.size#(1) then
if win.Mouse#(1) > win.size#(1)-20 then
if win.Mouse#(0) <= win.size#(0)-20 then
win.pos# = win.pos# + mouse#-lastMouse#
else
if mouseClick (MOUSE_LBUTTON) then
if not win.minimized then
win.normalSize# = win.size#
win.size#(0) = 150
win.size#(1) = 20
win.pos# = win.pos# - win.size# + win.normalsize#
win.minimized = true
else
win.pos# = win.pos# + win.size# - win.normalSize#
win.size# = win.normalSize#
win.minimized = false
endif
endif
endif
endif
else
closestClickedWindow = -1
for i = 0 to windowCount-1
&win = &window (drawArray (i))
win.mouse# = mouse# - win.pos#
if win.mouse#(0)>=0 and win.mouse#(1)>=0 and win.mouse#(0)<=win.size#(0) and win.mouse#(1)<=win.size#(1) then
closestClickedWindow = i
endif
next
if not closestClickedWindow = -1 then
ActiveWindow = DrawArray (closestClickedWindow)
for i = closestClickedWindow to WindowCount-2
DrawArray (i) = DrawArray (i+1)
next : DrawArray (WindowCount-1) = ActiveWindow
mouseClick (MOUSE_LBUTTON) = false
endif
endif
win.mouse# = mouse# - win.pos#
endif
glClearColor (0, 0, 0, 0)
glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
glEnable (GL_SCISSOR_TEST)
for i = 0 to windowCount-1
&win = &window (drawArray (i))
glLoadIdentity ()
gosub DrawWindow
next
glDisable (GL_SCISSOR_TEST)
SwapBuffers ()
wend
end
DrawWindow:
win.frames = win.frames + 1
' Only draw a rectangle the size of the window. This is done
' by using glScissor, which makes it so only the scissored
' part of the screen is drawn to. Also reset the viewport so
' the coordinates behave the same way they would if they were
' drawn in a normal opengl window.
glScissor (win.pos#(0), win.pos#(1), win.size#(0), win.size#(1))
glViewport (win.pos#(0), win.pos#(1), win.size#(0), win.size#(1))
' Clear out all previous information from the scissor rectangle.
glClearColor (.5, .5, .5, 1)
glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
' Set 2D mode and draw all 2D stuff (menu, borders, etc).
glMatrixMode (GL_PROJECTION)
glLoadIdentity ()
glOrtho (0, win.size#(0), 0, win.size#(1), -1, 1)
glMatrixMode (GL_MODELVIEW)
' Menu bar
if drawArray (i) = ActiveWindow then
glBegin (GL_QUADS)
glColor3f (0, 0, .5) : glVertex2f (0, win.size#(1)-20)
glColor3f (0, .1, .5) : glVertex2f (win.size#(0), win.size#(1)-20)
glColor3f (0, .5, .2) : glVertex2f (win.size#(0), win.size#(1))
glColor3f (0, .2, .2) : glVertex2f (0, win.size#(1))
glEnd ()
else
glBegin (GL_QUADS)
glColor3f (.1, 0, .1) : glVertex2f (0, win.size#(1)-20)
glColor3f (.1, .1, .1) : glVertex2f (win.size#(0), win.size#(1)-20)
glColor3f (.1, .1, .2) : glVertex2f (win.size#(0), win.size#(1))
glColor3f (.1, .2, .2) : glVertex2f (0, win.size#(1))
glEnd ()
endif
' Minimize button
glBegin (GL_QUADS)
glColor3f (.5, .5, .5): glVertex2f (win.size#(0) -18, win.size#(1) - 18)
glColor3f (.3, .3, .3): glvertex2f (win.size#(0) - 2, win.size#(1) - 18)
glColor3f (.5, .5, .5): glVertex2f (win.size#(0) - 2, win.size#(1) - 2)
glColor3f (.3, .3, .3): glVertex2f (win.size#(0) -18, win.size#(1) - 2)
glEnd ()
' Border
glBegin (GL_QUADS)
glColor3f (0, 0, .5)
glVertex2f (0, 0)
glVertex2f (2, 0)
glVertex2f (2, win.size#(1) - 20)
glVertex2f (0, win.size#(1) - 20)
glVertex2f (2, 0)
glVertex2f (win.size#(0)-2, 0)
glVertex2f (win.size#(0)-2, 2)
glVertex2f (2, 2)
glVertex2f (win.size#(0) -2, 0)
glVertex2f (win.size#(0) -2, win.size#(1) - 20)
glVertex2f (win.size#(0), win.size#(1) - 20)
glVertex2f (win.size#(0), 0)
glEnd ()
' Draw what's inside the window if it's not minimized.
if not win.minimized then
' Clip the draw area to within the window border- two units on each
' side, 2 units on the bottom and 20 units for the top.
glScissor (win.pos#(0)+2, win.pos#(1)+2, win.size#(0)-4, win.size#(1)-22)
glViewPort (win.pos#(0)+2, win.pos#(1)+2, win.size#(0)-4, win.size#(1)-22)
' Set the background color to dark grey and clear the scissored area.
glclearColor (.1, .1, .1, .1)
glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
' Set 3D mode-
glMatrixMode (GL_PROJECTION)
glLoadIdentity ()
gluPerspective (60, (1.0*win.size#(0))/win.size#(1), 1, 1000)
glMatrixMode (GL_MODELVIEW)
' Draw all the 3D stuff-
gosub Draw3DWindow
DrawText (): cls
endif
return
oh, and I'm still a little unsure of exactly how the text behaves... Apparently, if the text is clipped and scaled to fit into whatever the current viewport is, but DrawText () and Cls have to be called in each viewport while Swapbuffers () is only called once...
Please post any questions or comments!