Passing options to the draw function declaration in quil and clojure. - clojure

I am a beginner in using Quil and Clojure and am attempting to draw some rectangles from some existing data structures. If I define the draw function to take a structure of some kind how do I pass the structure to draw using defsketch?
(defn draw [x]
(stroke 80)
(stroke-weight 3)
(fill 23 181 100)
(rect x x x x))
(defn create-sketch []
"Automatically uses the given setup and draw functions. Magic."
(defsketch example
:setup setup
:draw draw
:size [2000 2000]))
In the code above (taken from one of Quil's examples) I could define draw to take a random parameter x which it would then use. I can't figure out how to pass in a parameter when defining the sketch. The :draw draw declaration as it is now works for a function with an empty parameter-list. I have tried every way I can think of to pass it in some x value. I'm not knowledgeable enough on what the problem actually is to be able to fix it.

quil draw takes no arguments. The partial trick shown in the comments works if you always draw the same list of rectangles.
If you want to have an animation draw must access a mutable state (eg an atom).

Related

Unable to get textures to work in OpenGL in Common Lisp

I am building a simple Solar system model and trying to set textures on some spheres.
The geometry is properly generated, and I tried a couple different ways to generate the texture coordinates. At present I am relying on glu:quadric-texture for generating the coordinates when glu:sphere is called.
However, the textures never appear - objects are rendered in flat colors.
I went through several OpenGL guides and I do not think I am missing a step, but who knows.
Here is what is roughly happening:
call gl:enable :texture-2d to turn on textures
load images using cl-jpeg
call gl:bind-texture
copy data from image using gl:tex-image-2d
generate texture ids with gl:gen-textures. Also tried generating ids one by one instead of all at once, which had no effect.
during drawing create new quadric, enable texture coordinates generation and bind the texture before generating the quadric points:
(let ((q (glu:new-quadric)))
(if (planet-state-texture-id ps)
(progn (gl:enable :texture-gen-s)
(gl:enable :texture-gen-t)
(glu:quadric-texture q :true)
(gl:bind-texture :texture-2d planet-texture-id)))
(glu:quadric-texture q :false))
(glu:sphere q
planet-diameter
*sphere-resolution*
*sphere-resolution*)
I also tried a more manual method of texture coordinates generation, which had no effect.
Out of ideas hereā€¦
make-texture function
texture id generation
quadric drawing
When the program runs, I can see the textures are loaded and texture ids are reserved, it prints
loading texture from textures/2k_neptune.jpg with id 1919249769
Loaded data. Image dimensions: 1024x2048
I don't know if you've discovered a solution to your problem, but after creating a test image, and modifying some of your code, I was able to get the texture to be applied to the sphere.
The problem comes into play with the fact that you are attempting to upload textures to the GPU before you've enabled them. (gl:enable :texture-2d) has to be called before you start handling texture/image data.
I'd recommend putting the let* block with the planets-init that is in the main function after 'setup-gl', and also moving the 'format' function with the planets data to work correctly without an error coming up.
My recommendation is something like:
(let ((camera ...
...
(setup-gl ...)
(let* ((planets...
...
(format ... planet-state)
In your draw-planet function, you'll want to add (gl:bind-texture :texture-2d 0) at the end of it so that the texture isn't used for another object, like the orbital path.
As is, the (gl:color 1.0 ...) before the (gl:quadratic-texture ...) will modify the color of the rendered object, so it may not look like what you're expecting it to look like.
Edit: I should've clarified this, but as your code stands it goes
initialize-planets > make-textures > enable-textures > render
When it should be
enable-textures > init-planets > make-textures > render
You're correct about not missing a step, the steps in your code are just misordered.

Cannot locate gimp.xxx() or pdb.gimp_xxx() function for >applying< a gradient fill

Can not find python function (either gimp.xxxx() or pdb.gimp_xxxxx() ) that will actually APPLY the gradient selected as current with either
gimp.gradients_set_active(<gradientName>) (which seems to have disappeared) or
pdb.gimp_context_set_gradient(<gradientName>)
I have seemingly spent an eternity browsing the web, s.o., and the gimp procedural database to find something that will actually FILL a LAYER/drawable/selection with a GRADIENT along a PATH with no success.
the pdb fill functions have an option for pattern fill, but no gradient and no stroke path.
the pdb stroke functions only apply the current foreground along a path.
everything on the web is about >creating< a gradient -- but I have the gradients - just no way to apply/fill/stroke them from a script.
code: SEE above
It appears that gimp_edit_blend() is the pdb function to actually fill a drawable with a gradient.
The context gradient must be set before-hand (as in the question).
And, it appears that the blend_mode parameter (the second parameter) must be 3, (ie CUSTOM-MODE) ->
pdb.gimp_edit_blend(drawable, blend_mode, ...)
To fill a layer with a gradient, the proper function is pdb.gimp_drawable_edit_gradient_fill().
To use a gradient along path, use pdb.gimp_paintbrush() where the last argument is the "fade" length. Of course this call takes a sequence of straight segments and not a path, but you can transform a path stroke into a sequence of segments using pdb.gimp_vectors_stroke_interpolate().

Python 3 Graphics Programming: how can I get a mouse click within a polygon shape?

So I'm working on a project for a class and I'm still trying to figure out how to go about doing something.
I am making a game where there is a board of squares or hexagons, they are either black or white, each being a state of being "Flipped", and when you click one square/hexagon, it flips all the adjacent shapes too.
Here is an image of what I am aiming to create.
Assignment images
I have gotten it running with squares, but now I need to do it with Hexagons. With the squares I registered a mouseclick as being within a square parameters of the x and y location of the click, and the state changes are assigned to a list of values assigned similarly to how the shapes were assigned within a list.
I will include a quick recording of the square program running in a folder I'm going to link.
Now, I believe I can't apply this kind of system to hexagons since they don't really line up like the squares did.
So how would I go about making a click register within a single hexagon on a grid? I have already drawn out the grid, but I am stuck on what to do to register a click to allow a hexagon to change it's state from un-flipped to flipped. I'm pretty sure I know what to do for the state change itself, but I don't know how to go about this, would it involve something with making a separate Class or something? I would appreciate any help with this.
I'll put a dropbox link here for the progress I made so far, and a pdf manual for graphics.py.
Dropbox: Python files
You can view the python code in your web-browser with dropbox too, I don't really want to fill this page pull of an entire thing of code..
Any help and feedback would be wonderful, thank you c:
so, TL;DR: How do you register a click within a polygon shape in python that allows it to change a value (within a list?) and change its visual appearance.
Just for the general side of your question, you can use a test to check if a point (x, y) is inside a polygon (formed by a list of x, y pairs).
Here's one such solution: http://www.ariel.com.au/a/python-point-int-poly.html
# determine if a point is inside a given polygon or not
# Polygon is a list of (x,y) pairs.
def point_inside_polygon(x,y,poly):
n = len(poly)
inside =False
p1x,p1y = poly[0]
for i in range(n+1):
p2x,p2y = poly[i % n]
if y > min(p1y,p2y):
if y <= max(p1y,p2y):
if x <= max(p1x,p2x):
if p1y != p2y:
xinters = (y-p1y)*(p2x-p1x)/(p2y-p1y)+p1x
if p1x == p2x or x <= xinters:
inside = not inside
p1x,p1y = p2x,p2y
return inside
This can be used in a way that is quite symmetrical to your drawing code, as you also form polygons in the same way for drawing as you would to test to see if the cursor is inside a hex.
You can modify the above implementation also to work with this Point type you are using to draw the polygons.
The rest you should be able to figure out, especially considering that you managed the input handling and drawing for the square grid.

Draw Ring with shapeRenderer in LibGDX

I want to draw a ring (circle with big border) with the shaperenderer.
I tried two different solutions:
Solution: draw n-circles, each with 1 pixel width and 1 pixel bigger than the one before. Problem with that: it produces a graphic glitch. (also with different Multisample Anti-Aliasing values)
Solution: draw one big filled circle and then draw a smaller one with the backgroundcolor. Problem: I can't realize overlapping ring shapes. Everything else works fine.
I can't use a ring texture, because I have to increase/decrease the ring radius dynamic. The border-width should always have the same value.
How can I draw smooth rings with the shaperenderer?
EDIT:
Increasing the line-width doesn't help:
MeshBuilder has the option to create a ring using the ellipse method. It allows you to specify the inner and outer size of the ring. Normally this would result in a Mesh, which you would need to render yourself. But because of a recent change it is also possible to use in conjunction with PolygonSpriteBatch (an implementation of Batch that allows more flexible shapes, while SpriteBatch only allows quads). You can use PolygonSpriteBatch instead of where you normally would use a SpriteBatch (e.g. for your Stage or Sprite class).
Here is an example how to use it: https://gist.github.com/xoppa/2978633678fa1c19cc47, but keep in mind that you do need the latest nightly (or at least release 1.6.4) for this.
Maybe you can try making a ring some other way, such as using triangles. I'm not familiar with LibGDX, so here's some
pseudocode.
// number of sectors in the ring, you may need
// to adapt this value based on the desired size of
// the ring
int sectors=32;
float outer=0.8; // distance to outer edge
float inner=1.2; // distance to inner edge
glBegin(GL_TRIANGLES)
glNormal3f(0,0,1)
for(int i=0;i<sectors;i++){
// define each section of the ring
float angle=(i/sectors)*Math.PI*2
float nextangle=((i+1)/sectors)*Math.PI*2
float s=Math.sin(angle)
float c=Math.cos(angle)
float sn=Math.sin(nextangle)
float cn=Math.cos(nextangle)
glVertex3f(inner*c,inner*s,0)
glVertex3f(outer*cn,outer*sn,0)
glVertex3f(outer*c,outer*s,0)
glVertex3f(inner*c,inner*s,0)
glVertex3f(inner*cn,inner*sn,0)
glVertex3f(outer*cn,outer*sn,0)
}
glEnd()
Alternatively, divide the ring into four polygons, each of which consists of one quarter of the whole ring. Then use ShapeRenderer to fill each of these polygons.
Here's an illustration of how you would divide the ring:
if I understand your question,
maybe, using glLineWidth(); help you.
example pseudo code:
size = 5;
Gdx.gl.glLineWidth(size);
mShapeRenderer.begin(....);
..//
mShapeRenderer.end();

Getting the inverse projection matrix for mouse picking

I'm trying to implement mouse picking in a small application written in haskell. I want to retrieve the projection matrix that has been set with this code found in the resize function that gets called when the window resizes itself:
resize w h = do
GL.viewport $= (GL.Position 0 0, GL.Size (fromIntegral w) (fromIntegral h))
GL.matrixMode $= GL.Projection
GL.loadIdentity
GL.perspective 45 (fromIntegral w / fromIntegral h) 1 100
The best I've achieved so far is to set the current matrix to GL.Projection and then trying to read the GL.currentMatrix statevar like this:
GL.matrixMode $= GL.Projection
pm <- GL.get GL.currentMatrix
-- inverse the matrix, somehow, and multiply this with the clip plane position of
-- of the mouse
This doesn't work and produces this error:
Ambiguous type variable `m0' in the constraint:
(GL.Matrix m0) arising from a use of `GL.currentMatrix'
Probable fix: add a type signature that fixes these type variable(s)
In the first argument of `GL.get', namely `GL.currentMatrix'
In a stmt of a 'do' expression: pm <- GL.get GL.currentMatrix
I think I should be using some sort of type constraint when trying to get the matrix out of the StateVar, but changing the GL.get call to pm <- GL.get (GL.currentMatrix :: GL.GLfloat) just produces a different and equally puzzling message.
I know this is using the old deprecated OpenGL matrix stack and modern code should be using shaders and such to perform their own matrix handling, but I'm not quite comfortable enough in haskell to attempt to really do anything beyond the most basic of projects. If it's easy enough I would certainly try to convert what little rendering code I have to a more modern style, but I find it difficult to find suitable tutorials to help me along.
First thing is first: currentMatrix is deprecated and is removed in the most recent OpenGL package (2.9.2.0). In order to use the most recent version, you can upgrade the dependency in your .cabal file. If you look at the source, GL.currentMatrix is identical to calling GL.matrix Nothing.
Second: The error you're receiving is because Haskell doesn't know the type of matrix component (float or double) that you're trying to read from the GL state. You're on the right track about adding a type signature to the function call, but GL.currentMatrix has type
GL.Matrix m, GL.MatrixComponent c => GL.StateVar (m c)
Hence, you need to fully specify the type if you plan on using it in order to disambiguate it to haskell. If you're set on using the old fixed function pipeline, then the type signature should look something like this:
pm <- GL.get (GL.currentMatrix :: GL.StateVar (GL.GLmatrix GL.GLfloat))
That being said, your mouse picking code may still have problems because there're a couple of other factors that you need to account for:
You need both the modelview and projection matrices to get the proper world-space position of the ray into your scene. The call to GL.currentMatrix just gets the current matrix for whatever the current matrix mode is.
Inverting a 4x4 matrix isn't part of the OpenGL package, IIRC and you'll need your own inverting code.
Once you get the proper matrices, the OpenGL.GLU package has an unproject function that might do what you need