I'm looking to create a glowing line effect in BlitzMax, something like a Star Wars lightsaber or laserbeam. Doesn't have to be realtime, but just to TImage objects and then maybe saved to PNG for later use in animation. I'm happy to use 3D features, but it will be for use in a 2D game.
Since it will be on black/space background, my strategy is to draw a series of white blurred lines with color and high transparency, then eventually central lines less blurred and more white. What I want to draw is actually bezier curved lines. Drawing curved lines is easy enough, but I can't use the technique above to create a good laser/neon effect because it comes out looking very segmented. So, I think it may be better to use a blur effect/shader on what does render well, which is a 1-pixel bezier curve.
The problems I've been having are:
Applying a shader to just a certain area of the screen where lines are drawn. If there's a way to do draw lines to a texture and then blur that texture and save the png, that would be great to hear about. There's got to be a way to do this, but I just haven't gotten the right elements working together yet. Any help from someone familiar with this stuff would be greatly appreciated.
Using just 2D calls could be advantageous, simpler to understand and re-use.
It would be very nice to know how to save a PNG that preserves the transparency/alpha stuff.
p.s. I've reviewed this post (and others), have the samples working, and even developed my own 5x5 shader. But, it's 3D and a scene-wide thing that doesn't seem to convert to 2D or just a certain area very well.
http://www.blitzbasic.com/Community/posts.php?topic=85263
Ok, well I don't know about BlitzMax, so I can't go into much detail regarding implementation, but to give you some pointers:
For applying shaders to specific parts of the image only, you will probably want to use multiple rendering passes to compose your scene.
If you have pixel access, doing the same things that fragment shaders do is, of course, possible "the oldskool way" in 2D, ie. something like getpixel/setpixel. However, you'll have much poorer performance this way.
If you have a texture with an alpha channel intact, saving in PNG with an alpha channel should Just Work (sorry, once again no idea how to do this in BlitzMax specifically). Just make sure you're using RGBA modes all along.
Related
I saw that D3DX9 is not recommended by Microsoft and not shipped with Windows SDK.
I would like to adopt.
I'm missing my line drawing utility.
How can I replace ID3DXLine and ID3DXFont in "new" DirectX9?
Generally, lines and fonts are sprites. ID3DXLine and ID3DXFont use ID3DXSprite interface under the hood. (Of course, there are other options too, but sprite approach is the most widely used)
Drawing sprites
So, firstly, you will need either 3rd party or your own sprite renderer. Typically, development of "bedroom" sprite engine, consists of stages:
drawing bunch of simple colored quads (two triangles forming rectangle). There are different techniques, but even simplest "all-in-one vertex buffer" approach is not so bad. More advanced techniques includes instancing, point sprites, geometry shader and tessellation tricks (last two are not applicable in DX9). But don't even try to draw million sprites with million draw calls ;)
Texturing those quads. You will need bitmap loader. If you don't want to use D3DX at all, you can pick open-source FreeImage library for example, of write your own loader.
optimizing rendering using batching. Sort your sprites, to minimize draw calls number and/or minimize context state changes.
optimizing texturing using texture atlases. You will need to solve rectangle packing algorithm (there are already plenty of implementations on web, or pick up you math book) and roll out some kind of texture atlas format.
You can choose on what stage you stop. Later, you can go back and continue.
Drawing lines
Then, for straight lines, you will simply draw a thin rectangular sprite. User will input values such as beginning, end and thickness of line, and you will need to do some simple math to calculate position and rotation of this sprite. Sprite can be just colored or have a texture: for dotted lines, stripped lines, lines with pink fluffy kittens etc. Then, you can implement curved lines as a set of straight lines. You can optionally add sprites to the ends of line, such as arrows.
Drawing text
For text, things can be very complicated (and I will tell only about sprite fonts here):
each character is a little sprite
you draw texture of a letter over it
you have a texture with those letters, and sample it using dictionary. Dictionary is a map of character (or character code) to texture coordinates where it's picture situated, along with additional info, such as spacing, kerning, etc.
you can have pre-baked (offline) texture atlas with all letters of all fonts of all font sizes you need, along with dictionary. Obviously you cannot have all letters of all languages on a planet in your resource cache.
you can bake each character as needed on runtime and add it to your cache (texture atlas + dictionary)
To get characters from font file such as .ttf to a bitmap (image) you can use library. FreeType is a best open-source I know. Parsing fonts yourself can be... complicated.
You can then mix all together and draw lines with text texture. Or draw text surrounded by frame of lines. Or sprite with a text above it. Or GUI. All those stuff will be the sprites.
...or just not bother
If you still using DirectX 9, do you really need to bother with Windows SDK, removing D3DX stuff? Maybe you can continue developing with Direct SDK and D3DX if it works for you? Note, that if, for some reason, you'll decide to move to DX11, there are DirectXTK, which partially replaces D3DX11 stuff. Still, your own, or 3rd party solution will probably be more flexible and suitable for you. There are many others applications of sprites in 3D graphics,, such as billboarding, GUI, particles, etc. And as always, reinventing the wheel is a much fun and positive experience ;)
Hope it helps. Happy coding!
Why not try and use DirectX 11?
Oterhwise OpenGL is supported on almost any platform.
I would recommend trying SDL it has helper methods for most 2D stuff you can imagine.
As written in the title, i would like to draw anti aliased rounded rectangles in c++ and in a linux context (ubuntu). I already tried SDL_gfx but anti aliasing is not available on roundedBox shapes. I also read about SDL_Draw but I think it does neither provide anti aliasing.
That's why I am asking if anybody knows a framework providing this kind of shapes or if anybody knows a (light) anti aliasing algorithm (I need this for real time video processing).
Thank you Vjo, but I don't really want to use openGL in my soft ... And by the way, I think I figured out another way to draw anti aliased rounded rectangles !
What I did not explain in the first post is that i am already using SDL and opencv in my program. So I had an idea :
draw a 1 channel rounded rectangle with SDL_gfx
smooth it with cvSmooth to get the antialiasing alpha
use the result as the alpha channel of a simple rectangle
What do you think about that ? I'll try it this evening !
The only parts of the shape that need to be antialiased are the corners. draw four antialiased quater circles, one at each corner (Xiaolin Wu's circle algrithm is your best bet here), and bridge the gaps with simple lines. If the shapes will not be rotated (that is, all straight lines will be either vertical or horizontal, use Bresenham's non-antialiased line algorithm, otherwise use Wu's line algorithm. Wu's antialiasing algorithms are typically the fastest and give very good results.
If you really want to optimize your result, and are familiar with x86 assembly programming, I suggest writing the drawing routines using inline assembly language. Properly tuned, wu's line algorithm can be written in as few as 15 instructions, and his circle algorithm around 40-50 instructions.
I'm trying to, in JOGL, pick from a large set of rendered quads (several thousands). Does anyone have any recommendations?
To give you more detail, I'm plotting a large set of data as billboards with procedurally created textures.
I've seen this post OpenGL GL_SELECT or manual collision detection? and have found it helpful. However it can take my program up to several minutes to complete a rendering of the full set, so I don't think drawing 2x (for color picking) is an option.
I'm currently drawing with calls to glBegin/glVertex.../glEnd. Given that I made the switch to batch rendering on the GPU with vao's and vbo's, do you think I would receive a speedup large enough to facilitate color picking?
If not, given all of the recommendations against using GL_SELECT, do you think it would be worth me using it?
I've investigated multithreaded CPU approaches to picking these quads that completely sidestep OpenGL all together. Do you think a OpenGL-less CPU solution is the way to go?
Sorry for all the questions. My main question remains to be, whats a good way that one can pick from a large set of quads using OpenGL (JOGL)?
The best way to pick from a large number of quad cannot be easily defined. I don't like color picking or similar techniques very much, because they seem to be to impractical for most situations. I never understood why there are so many tutorials that focus on people that are new to OpenGl or even programming focus on picking that is just useless for nearly everything. For exmaple: Try to get a pixel you clicked on in a heightmap: Not possible. Try to locate the exact mesh in a model you clicked on: Impractical.
If you have a large number of quads you will probably need a good spatial partitioning or at least (better also) a scene graph. Ok, you don't need this, but it helps A LOT. Look at some tutorials for scene graphs for further information's, it's a good thing to know if you start with 3D programming, because you get to know a lot of concepts and not only OpenGl code.
So what to do now to start with some picking? Take the inverse of your modelview matrix (iirc with glUnproject(...)) on the position where your mouse cursor is. With the orientation of your camera you can now cast a ray into your spatial structure (or your scene graph that holds a spatial structure). Now check for collisions with your quads. I currently have no link, but if you search for inverse modelview matrix you should find some pages that explain this better and in more detail than it would be practical to do here.
With this raycasting based technique you will be able to find your quad in O(log n), where n is the number of quads you have. With some heuristics based on the exact layout of your application (your question is too generic to be more specific) you can improve this a lot for most cases.
An easy spatial structure for this is for example a quadtree. However you should start with they raycasting first to fully understand this technique.
Never faced such problem, but in my opinion, I think the CPU based picking is the best way to try.
If you have a large set of quads, maybe you can group quads by space to avoid testing all quads. For example, you can group the quads in two boxes and firtly test which box you
I just implemented color picking but glReadPixels is slow here (I've read somehere that it might be bad for asynchron behaviour between GL and CPU).
Another possibility seems to me using transform feedback and a geometry shader that does the scissor test. The GS can then discard all faces that do not contain the mouse position. The transform feedback buffer contains then exactly the information about hovered meshes.
You probably want to write the depth to the transform feedback buffer too, so that you can find the topmost hovered mesh.
This approach works also nice with instancing (additionally write the instance id to the buffer)
I haven't tried it yet but I guess it will be a lot faster then using glReadPixels.
I only found this reference for this approach.
I'm using the solution that I've borrowed from DirectX SDK, there's a nice example how to detect the selected polygon in a vertext buffer object.
The same algorithm works nice with OpenGL.
I have a VB6 application (please don't laugh) which does a lot of drawing via BitBlt and the standard VB6 drawing functions. I am running up against performance issues (yes, I do the regular tricks like drawing to memory). So, I decided to investigate other ways of drawing, and have come upon OpenGL.
I've been doing some experimenting, and it seems straightforward to do most of what I want; the application mostly only uses very simple drawing -- relatively large 2D rectangles of solid colors and such -- but I haven't been able to find an equivalent to something like a HatchBrush or PatternBrush.
More specifically, I want to be able to specify a small monochrome pixel pattern, choose a color, and whenever I draw a polygon (or whatever), instead of it being solid, have it automatically tiled with that pattern, not translated or rotated or skewed or stretched, with the "on" bits of the pattern showing up in the specified color, and the "off" bits of the pattern left displaying whatever had been drawn under the area that I am now drawing on.
Obviously I could do all the calculations myself. That is, instead of drawing as a polygon which will somehow automatically be tiled for me, I could calculate all of the lines or pixels or whatever that actually need to be drawn, then draw them as lines or pixels or whatever. But is there an easier way? Like in GDI, where you just say "draw this polygon using this brush"?
I am guessing that "textures" might be able to accomplish what I want, but it's not clear to me (I'm totally new to this and the documentation I've found is not entirely obvious); it seems like textures might skew or translate or stretch the pattern, based upon the vertices of the polygon? Whereas I want the pattern tiled.
Is there a way to do this, or something like it, other than brute force calculation of exactly the pixels/lines/whatever that need to be drawn?
Thanks in advance for any help.
If I understood correctly, you're looking for glPolygonStipple() or glLineStipple().
PolygonStipple is very limited as it allows only 32x32 pattern but it should work like PatternBrush. I have no idea how to implement it in VB though.
First of all, are you sure it's the drawing operation itself that is the bottleneck here? Visual Basic is known for being very slow (Especially if your program is compiled to intermediary VM code - which is the default AFAIRC. Be sure you check the option to compile to native code!), and if it is your code that is the bottleneck, then OpenGL won't help you much - you'll need to rewrite your code in some other language - probably C or C++, but any .NET lang should also do.
OpenGL contains functions that allow you to draw stippled lines and polygons, but you shouldn't use them. They're deprecated for a long time, and got removed from OpenGL in version 3.1 of the spec. And that's for a reason - these functions don't map well to the modern rendering paradigm and are not supported by modern graphics hardware - meaning you will most likely get a slow software fallback if you use them.
The way to go is to use a small texture as a mask, and tile it over the drawn polygons. The texture will get stretched or compressed to match the texture coordinates you specify with the vertices. You have to set the wrapping mode to GL_REPEAT for both texture coordinates, and calculate the right coordinates for each vertex so that the texture appears at its original size, repeated the right amount of times.
You could also use the stencil buffer as you described, but... how would you fill that buffer with the pattern, and do it fast? You would need a texture anyway. Remember that you need to clear the stencil buffer every frame, before you start drawing. Not doing so could cost you a massive performance hit (the exact value of "massive" depending on the graphics hardware and driver version).
It's also possible to achieve the desired effect using a fragment shader, but learning shaders for that would be an overkill for an OpenGL beginner like yourself :-).
Ah, I think I've found it! I can make a stencil across the entire viewport in the shape of the pattern I want (or its mask, I guess), and then enable that stencil when I want to draw with that pattern.
You could just use a texture. Put the pattern in as in image and turn on texture repeating and you are good to go.
Figured this out a a year or two ago.
I guess I'll illustrate with an example:
In this game you are able to draw 2D shapes using the mouse and what you draw is rendered to the screen in real-time. I want to know what the best ways are to render this type of drawing using hardware acceleration (OpenGL). I had two ideas:
Create a screen-size texture when drawing is started, update this when drawing, and blit this to the screen
Create a series of line segments to represent the drawing, and render these using either lines or thin polygons
Are there any other ideas? Which of these methods is likely to be best/most efficient/easiest? Any suggestions are welcome.
I love crayon physics (music gets me every time). Great game!
But back to the point... He has created brush sprites that follow your mouse position. He's created a few brushes that account for a little variation. Once the mouse goes down, I imagine he is adding these sprites to a data structure and sending that structure through his drawing and collision functions to loop through. Thus popping out the real-time effect. He is using Simple DirectMedia Layer library, which I give two thumbs up.
I'm pretty sure the second idea is the way to go.
First option if the player draws pure freehand (rather than lines), and what they draw doesn't need to be animated.
Second option if it is animated or is primarily lines. If you do choose this, it seems like you'd need to draw thin polygons rather than regular lines to get any kind of interesting look (as in the crayon example).