Is there a simple complete code example using any gui toolkit (that will work in both Linux and Windows) of opening multiple opengl windows simultaneously? And how to handle their events and such separately of course. I tried it naively and it crashes.
I received a full working source code example from someone outside of stackoverflow. I'm pasting it here for all to benefit.
module Main where
import Graphics.UI.GLUT
import System.Exit (exitWith, ExitCode(ExitSuccess))
reshape :: ReshapeCallback
reshape size = do
viewport $= (Position 0 0, size)
matrixMode $= Projection
loadIdentity
frustum (-1) 1 (-1) 1 1.5 20
matrixMode $= Modelview 0
keyboard :: KeyboardMouseCallback
keyboard (Char '\27') Down _ _ = exitWith ExitSuccess
keyboard _ _ _ _ = return ()
renderCube :: Color3 GLfloat -> IO ()
renderCube c = do
clear [ ColorBuffer ]
let color3f = color :: Color3 GLfloat -> IO ()
scalef = scale :: GLfloat -> GLfloat -> GLfloat -> IO ()
color3f c
loadIdentity
lookAt (Vertex3 0 0 5) (Vertex3 0 0 0) (Vector3 0 1 0)
scalef 1 2 1
renderObject Wireframe (Cube 1)
flush
displayR :: DisplayCallback
displayR = renderCube (Color3 1 0 0)
displayB :: DisplayCallback
displayB = renderCube (Color3 0 0 1)
createWindowWithDisplayFunc :: String -> Position -> DisplayCallback -> IO Window
createWindowWithDisplayFunc name pos display = do
win <- createWindow name
windowPosition $= pos
clearColor $= Color4 0 0 0 0
shadeModel $= Flat
displayCallback $= display
reshapeCallback $= Just reshape
keyboardMouseCallback $= Just keyboard
return win
main = do
getArgsAndInitialize
initialDisplayMode $= [ SingleBuffered, RGBMode ]
initialWindowSize $= Size 100 100
initialWindowPosition $= Position 100 100
createWindowWithDisplayFunc "R" (Position 10 10) displayR
createWindowWithDisplayFunc "B" (Position 110 10) displayB
mainLoop
GLUT, of course.
The GLUT homepage states
The toolkit supports:
- Multiple windows for OpenGL rendering
- Callback driven event processing
- Sophisticated input devices
- An 'idle' routine and timers
- A simple, cascading pop-up menu facility
- Utility routines to generate various solid and wire frame objects
- Support for bitmap and stroke fonts
- Miscellaneous window management functions
Hence you can use GLUT for managing multiple windows (I had used once). Here is a tutorial for what you need.
I've also found this article which you may look a little, since it's Haskell specific.
OpenGL support in wxWidgets uses the WxGLCanvas class, which is in wxcore as GLCanvas. Unfortunately, it doesn't seem to exist in the wx package. You can probably implement your own control for GLCanvas without too much difficulty, using the other controls in the wx package and C++ usage examples as a reference.
Related
Constraints:
1. Have a pointer to an image with margins of size (ImHeight,ImWidth)
2. Filter size (FH,FW) ; FH,FW are odd
3. ActualImageHeight = ImHeight-2*(FH/2); ActualImageWidth = ImWidth-2*(FW/2);
How To:
Initialize image with the pointer such that image(0,0) is pixel(0,0) and not the margin pixel ?
Define a schedule without using boundary conditions / clamping - since the given image pointer memory already accounts for the margins
Modify the minimum coordinate of the image. You didn't state if you are using JIT or AOT, but here is a JIT implementation.
Halide::Image input( ImWidth + 2 * FW, ImHeight + 2 * FH ), output;
input.set_min( -FW, -FH );
Func f;
f(x,y) = ( input( x - FW, y - FH ) + input( x + FW - 1, y + FH - 1 ) ) / 2;
output = f.realize( ImWidth, ImHeight );
For AOT:
Use ImageParam for input.
Use Param<int> for ImWidth and ImHeight to have them be parameters to the AOT function.
Use int for ImWidth and ImHeight to have them be baked into the the AOT function.
Use set_bounds and set_stride for all dimensions of input and f.output_buffer(). These take Exprs so will accept ImWidth + 2 * FW if ImWidth is a Param<int>.
I have a little program in haskell, using wxhaskell. It displays a window with a panel inside, containing some drawings. The problem is that the window shrinks to a very tiny size, and I have to expand it with the mouse.
How can I define correctly the size?
here is my program:
module Main where
import Graphics.UI.WX
import Graphics.UI.WXCore
main :: IO ()
main
= start hello
hello :: IO ()
hello = do
f <- frame [text := "HELLO!"]
sw <- panel f [ on paint := onpaint]
set f [clientSize := sz 300 300,
layout := fill $ widget sw]
return()
where
onpaint dc pnel = do
circle dc (pt 200 200) 20 [penKind := PenDash DashDot]
drawPoint dc (pt 200 200) []
thank you.
Setting a minimum size instead of the client size
set f [ layout := minsize (sz 300 300) $ widget sw ]
works for me.
I have created a transition shader.
This is what is does:
On each update the color that should be alpha changes.
Then preform a check for each pixel.
If the color of the pixel is more that the 'alpha' value
Set this pixel to transparent.
Else If the color of the pixel is more that the 'alpha' value - 50
Set this pixel to partly transparent.
Else
Set the color to black.
EDIT (DELETED OLD PARTS):
I tried converting my GLSL into AGAL (using http://cmodule.org/glsl2agal):
Fragment shader:
const float alpha = 0.8;
varying vec2 TexCoord; //not used but required for converting
uniform sampler2D transition;//not used but required for converting
void main()
{
vec4 color = texture2D(transition, TexCoord.st);//not used but required for converting
color.a = float(color.r < alpha);
if(color.r >= (alpha - 0.1)){
color.a = 0.2 * (color.r - alpha - 0.1);
}
gl_FragColor = vec4(0, 0, 0, color.a);
}
And I've customized the output and added that to a (custom) Starling filter:
var fragmentShader:String =
"tex ft0, v0, fs0 <2d, clamp, linear, mipnone> \n" + // copy color to ft0
"slt ft0.w, ft0.x, fc0.x \n" + // alpha = red < inputAlpha
"mov ft0.xyz, fc1.xyzz \n" + // set color to black
"mov oc, ft0";
mShaderProgram = target.registerProgramFromSource(PROGRAM_NAME, vertexShader, fragmentShader);
It works and when I set the filters alpha, it will update the stuff. The only thing left is the partly transparent thing, but I have no idea how I can do that.
Swap the cycle on the Y and X coordinates. By using the X in the inner loop you optimize the L1 cache and the prefetcher of the CPU.
Some minor hints:
Remove the zeros for a cleaner code:
const c:uint = a << 24
Verify that 255/50 is collapsed into a single constant by the compiler.
Don't be crazy by doing it with BitmapData once you're using Starling.
I didn't get if you're grayscaling it by yourself or not. In not, just create a Starling filter for grayscale (pixel shader below will do the trick)
tex ft0, v0, fs0 <2d,linear,clamp>
add ft1.x, ft0.x, ft0.y
add ft1.x, ft1.x, ft0.z
div ft1.x, ft1.x, fc0.x
mov ft0.xyz, ft1.xxx
mov oc ft0
And for the alpha transition just extend the Image Class, implement IAnimatable add it to the Juggler. in the advanceTime just do a this.alpha -= VALUE;
Simple like that :)
Just going to elaborate a bit on #Paxel's answer. I discussed with another developer Jackson Dunstan about the L1 caching, where the speed improvement comes from, and what other improvements can be made to code like this to see performance gain.
After which Jackson posted a blog entry which can be read at here: Take Advantage of CPU caching
I'll post some the relative items. First the bitmap data is stored in memory by rows. The rows memory addresses might look something like this:
row 1: 0 1 2 3 4 5
row 2: 6 7 8 9 10 11
row 3: 12 13 14 15 16 17
Now running your inner loop through the rows will allow you leverage the L1 cache advantage since you can read the memory in order. So inner looping X first you'll read the first row as:
0 1 2 3 4 5
But if you were to do it Y first you'd read it as:
0 6 12 1 7 13
As you can see you are bouncing around memory addresses making it a slower process.
As for optimizations that could be made, the suggestion is to cache your width and height getters, storing the properties into local variables. Also using the Math.round() is pretty slow, replacing that would see a speed increase.
I'm attempting to use the SetLayeredWindowAttributes function to change the windows transparency color. I made a structure using the ctypes module. I'm pretty sure I have to use the COLORREF RGB macro to get this to work properly.
How do I use macros on a structure made using ctypes?
What I have going.
import Tkinter as tk
import win32gui
import win32con
class ColorRef (ctypes.Structure) :
_fields_ = [("byRed", ctypes.c_byte),
("byGreen", ctypes.c_byte),
("byBlue", ctypes.c_byte)]
# makes a Tkinter window
root = tk.Tk()
# a handle to that window
handle = int(root.wm_frame(), 0)
# a COLORRED struct
colorref = ColorRef(1, 1, 1)
# attempting to change the transparency color
win32gui.SetLayeredWindowAttributes(handle, colorref, 0, win32con.LWA_COLORKEY)
root.mainloop()
Three things:
C preprocessor macros don't exist outside C code. They are textually expanded before the actual compilation takes place.
COLORREF is a typedef to DWORD, not a structure.
All RGB macro does is some bitshifting to get 0x00bbggrr value.
So the code would look like this:
def RGB(r, g, b):
r = r & 0xFF
g = g & 0xFF
b = b & 0xFF
return (b << 16) | (g << 8) | r
colour = RGB(1, 1, 1)
win32gui.SetLayeredWindowAttributes(handle, colour, 0, win32con.LWA_COLORKEY)
I'm stuck with generating debug output for my game objects using Haskell/Yampa (=Arrows) (with HOOD).
My engine basically runs a list of game objects which produce Output states (line, circle) which are then rendered.
data Output = Circle Position2 Double | Line Vector2
output :: [Output] -> IO ()
output oos = mapM render oos
render :: Output -> IO ()
render (Circle p r) = drawCircle p r
render (Line vec) = drawLine (Point2 0 0) vec
The player object just moves to the right and is represented as a (positioned) circle.
playerObject :: SF () Output -- SF is an Arrow run by time
p <- mover (Point2 0 0) -< (Vector2 10 0)
returnA -< (Circle p 2.0)
mover is just a simple integrator (acceleration->velocity->position) where I want to observe the velocity and render it as debug output as an (unpositioned) Line.
mover :: Position2 -> SF Vector2 Position2
mover position0 = proc acceleration -> do
velocity <- integral -< acceleration -- !! I want to observe velocity
position <- (position0 .+^) ^<< integral -< velocity
returnA -< position
How can I create additional graphical debug output for internal values of my game object functions?
What actually should happen is in output, first render the actual object (circle) but also render additional debug output (movement vector as line). Probably I can achieve this with HOOD but I'm still not fluent in Haskell and don't know how do adopt the HOOD tutorial for my case.
I don't know HOOD but Debug.Trace is easy:
> import Debug.Trace
> mover position0 = proc acceleration -> do
> > velocity <- integral -< acceleration
> > position <- trace ("vel:" ++ show velocity ++ "\n") $
> > > > > > > > > > > (position0 .+^) ^<< integral -< velocity
> > returnA -< position
Note that it shouldn't be put on the line defining velocity.
What you probably want to do is make mover more flexible, to support adding out-of-band debug information (the value of velocity) to be rendered. I don't think HOOD is relevant for your problem, since you already have the FRP framework for handling continuously changing values. Just arrange for velocity to be output.
Something like:
mover :: Position2 -> SF Vector2 (Position2, Vector2)
mover position0 = proc acceleration -> do
velocity <- integral -< acceleration -- !! I want to observe velocity
position <- (position0 .+^) ^<< integral -< velocity
returnA -< (position, velocity)
playerObject :: SF () [Output]
(p, v) <- mover (Point2 0 0) -< (Vector2 10 0)
returnA -< [Circle p 2.0, Line v]