Lights Fantastic (Source Included)

BlitzMax Forums/BlitzMax Programming/Lights Fantastic (Source Included)

dw817(Posted 2016) [#1]
Back in the day, as my friend, Braydell calls it, vectors were king. Before Id and 3D Castle Wolfenstein hit the scene, people were content to draw vectors, today considered simple lines from point to point.

While images drawn today can also be rotated, it is with the advent of ALPHA that you now have the ability to have images appear translucent, like glass, to what is behind it.



As I delve into archives of old Q-Basic code, I came across this program I wrote years ago so I did a modern conversion with comments. I hope you like it !






Brucey(Posted 2016) [#2]
Cls, Flip, Cls, Draw stuff, Flip?

And you wonder why it flickers?

For anything I've ever done, Cls, Draw stuff, Flip, was all that was necessary.


Endive(Posted 2016) [#3]
I came across this program I wrote years ago


By "years ago" do you mean when Ronald Reagan was president? Or was it before that?

I saw a very similar kaleidoscope literally in 1979 running on what I presume was... I don't even know what computer it might have been. It was at a very very early computer store my mom took me to after a math tutoring class on the Plato touch-screen computers. It might have been some kind of very early atari?


dw817(Posted 2016) [#4]
Glad you guys like it. What I thought was especially intriguing was where you have curves in the vectors and they become bright at the nexus. I couldn't get that without ALPHA, marvel what you can do with it.

And Brucey, in truth, it shouldn't flicker. Not really. All you are doing is plotting to a screen. I could point out the limitation of BlitzMAX's inability to flicker when the screen is covered with complex images, as I can think of many programming languages that do not do it, perhaps a close Freeware competitor language called B4GL ? But I think you already know this. :)

In any case, that's fine. I program to relax - and this was a relaxing program to write. Going back to working on Tilemaster. May be a few more days before I release it.


Endive(Posted 2016) [#5]
I could point out the limitation of BlitzMAX's inability to flicker when the screen is covered with complex images, as I can think of many programming languages that do not do it, perhaps a close Freeware competitor language called B4GL ? But I think you already know this. :)


He does know the answer and he already explained it to you.

As we discussed a month ago, flip takes more time than any other reasonable graphical operation.

When you flip, you display what you've just drawn.

When you do cls; flip; cls; drawstuff; flip

You are first quite literally drawing a blank. Then you're displaying that blank frame.

That's why it appears to flicker.

Once again, this is not a problem with Blitzmax. It's a very simple and obvious problem in your code.

Who knows Blitzmax better, you or Brucey? If you think you know it better than he does you're a damn fool. I had your measure very early on.


LT(Posted 2016) [#6]
Pretty sure that you're just unaware of double-buffering and what flip does.

You're clearing the (unseen) back buffer, then showing it.
>>Result = black screen.
Then you're clearing the (again unseen) back buffer, drawing stuff to it, then showing it.
>>Result = drawn stuff.

Do this really fast and it'll flicker.

EDIT: Looks like Endive beat me to it. :)


Endive(Posted 2016) [#7]
EDIT: Looks like Endive beat me to it. :)

You've really got to be fast on the keyboard to keep up with this guy.


dw817(Posted 2016) [#8]
Endive, if you're not going to be polite, please don't speak at all. I've been =REALLY= meaning to withhold telling you this many messages over, but you're earning it now.

Brucey, LT, you are welcome to fudge the code if you can think of a more efficient way of flipping the screen. As I =KNOW= it is clear to all of you, I don't learn something by discussing the history of computer monitors and or the hardware involved in graphics but by working examples of what you speak.


Endive(Posted 2016) [#9]
Endive, if you're not going to be polite, please don't speak at all. I've been =REALLY= meaning to withhold telling you this many messages over, but you're earning it now.

Who is really impolite, me or you? You've repeatedly bitten the hand that feeds and at least three times now you've blamed the tool that this forum is about when the problem lay not with the tool but with your own faulty understanding of the tool. You've done this while arguing with past-master super-experts in the tool, who may very well have more to do with the language now than the guy who wrote it, and who have been programming in this tool and its previous iterations since the Amiga days.

[Personally I've only been using it since 2010. There is a lot I don't know.]

When called on your frankly abominably rude behavior you've gotten angry with the people who might otherwise have helped you. For some inexplicable reason (boredom? amusement?) they continue to attempt to answer your absurd questions. If their goal is to amuse *me* it's certainly working.

If you're not going to be polite, please don't speak at all.


dw817(Posted 2016) [#10]
Brucey, please tell me there is an option of IGNORE in the forum. And guess what Endive, you are OFF TOPIC AGAIN ! Did you JUST come here to insult me ??


By "years ago" do you mean when Ronald Reagan was president? Or was it before that?


Yep, sure looks like it. Keep it up and you'll drive me away from here completely which I suspect is what you want.

Especially with your words of, "goal is to amuse *me*" yes. That is what I am here for solely, to amuse you. God just listen to yourself.

My concern is you others - IS THAT what you want as well ? I'll leave and never return and keep my code to myself if that is REALLY what this forum is all about - to insult new arrivals ?

I can certainly find what I want with Google, I had HOPED I would not be criticized for the way I program or personal remarks made about me or the way I write messages. Apparently not.

And I suspect I'm not the only person who has been driven from this board in the past for the exact same reason.


Endive(Posted 2016) [#11]
Did you JUST come here to insult me ??

Actually I didn't insult you.

But I did explain to you why your program was flickering, and that was because you were displaying a black rectangle every other frame.

Don't blame the tool for your own failings. Don't blame others who have expended effort to help you for not spoonfeeding you sufficiently. Don't blame the books for being hard to understand-- it's the subject that is difficult and the books are the best there is.

If you do behave thus, don't blame others for losing patience.


dw817(Posted 2016) [#12]
Endive, I'm going to be clear here. If I am the author of the post, I do not want to see you in it, I do not want to see your replies, and I certainly don't want to see your 'humorous' anecdotes - I find your personal remarks about my age, the way I write, and the way I code to be offensive and cutting.

AM I CRYSTAL ?


Endive(Posted 2016) [#13]
Look at your posts and your attitude, your asterisks, your anime spamming, all the other attention-seeking weirdness, and ask yourself what is really offensive. It's a free country and if you don't want comments on your behavior, don't be rude and abrasive to people who are trying to help you.

I explained in detail where your error was here, as did others. As you did in other threads, you blamed the people helping you, then you blamed the tool. Now, yet again, you are getting stroppy when called on your egregious behaviour. If you like that other basic better, go use that and see how you do on their forum. If I know programmers your welcome will be much colder than what you've experienced here. This is a good bunch of guys and very knowledgeable but insulting the tool for your own poor use is just gauche.


dw817(Posted 2016) [#14]
Endive, you're still talking. Did you not understand what I said ? I am speaking only to you and no-one else. I don't want or need your help, not now, not ever - not with the price you attach to it. I can't be any more plain.

If you have any respect for others, please, stop writing in this thread. I will honor your own threads and not post in them additionally - and you can berate me THEN if I do, and not until. I think that is more than fair.


Endive(Posted 2016) [#15]
I don't think you understand. You have no power whatsoever over me and I care for your offense no more than you care for the offense of others. I'll be as polite to you as you are to others, and I will not shut up or stop.

AM I CRYSTAL?


dw817(Posted 2016) [#16]
Yes, very crystal. You are telling me that you have no respect for others, either their personal area or privacy. You are saying then that any posts I write in the future, you will come in to deliberately berate and insult me ? Crackers.


Endive(Posted 2016) [#17]
This forum is neither your personal area nor your private safe space. If you are rude and unpleasant to others you can expect others to respond in kind. You have complete control over how you are treated. This is true in the wider world as well as here. If you wish to maintain your rude and belligerent stance, good luck with all that-- but people like you rarely learn or change because that's part of the condition that makes you behave the way you do.

Best of luck here and in life.


dw817(Posted 2016) [#18]
Why am I even talking to you ? As there seems to be no option to add a flag for ignored members, the best way to show you despise me is to ignore me - I will try and do the same.

Can we at least agree to disagree ?


Endive(Posted 2016) [#19]
No.

Go read your books. Also get on YouTube and look up Inigo Quilez.


dw817(Posted 2016) [#20]
You agree then. :)


Brucey(Posted 2016) [#21]
If everyone would leave their egos at home, topics would probably have more chance of staying on topic...

Endive, if you don't have anything useful to contribute to the topic, it's probably better not to waste your time, and others.

Although you are both pretty much to blame.

Anyway, as LT notes, since your screen is double buffered, clearing the backbuffer (the page your are drawing onto) then flipping (showing it) is going to result in your seeing a blank screen every other time. Which will flicker.


Bobysait(Posted 2016) [#22]
<< The double-buffering analogy by BobySait >>

Just imagine a sheet of paper an artist is drawing on (or a baby, it doesn't change anything ... but, there is much to think that the baby will do what you did and flip several times his unfinished drawing before the end of the frame)

So, he is drawing, probably you on the beach, it's a sunny day ... ok, now the scenario is enough.

the "flip" is to the double-buffering what the "Tadaaaa !" is to the artist :
The moment when he flip his paper to show it to you.
The drawing is finished, and you didn't see him drawing it, you just see the final frame.

Working with double-buffering is the same :
You draw anything on the backbuffer (your sheet of paper) and when the frame is ready, you flip it to the screen (in opengl this function is called SwapBuffer > I just mention it because it 's maybe a bit more explicit name for the function)

Then, you don't want to show a blank screen between two frames, it will just make a stroboscope to the user "Whyte-frame-whyte-frame-whyte-frame" ... hope there is no epileptic here :)


col(Posted 2016) [#23]
Hey dw817

I remember this effect from when I was a kid walking around the computer stores, usually it was a bbc micro.

Just curious, whats the spec of the pc that you're developing on? cpu, memory, gpu, type of monitor etc.


Bobysait(Posted 2016) [#24]
BTW, it can "flicker" (as you mention) with GL drivers if you never clear anything or only once every X flip.

You can :
- use D3D9Max2DDriver instead of GLMax2D (for windows)
- use a quick and dirty "CoFlip" to clear both front and back buffers when you go for a new round.

Cls()
Flip true
Cls()
Flip true



and as long as you flip after each 8 lines (4 colored and 4 whytes) you should flip after the 8 drawlines and draw the lines once more to have the two buffers identical.
Because, now you're alternating drawing 8 lines on a buffer then the next 8 lines on the second buffer. you don't see it because it goes too fast to be noticed, but you actually have two buffers with different lines on it.
It's like a stroboscope effect that goes so fast that you don't see it flickering, due to your eyes "framerate" that is only around 24 Hz while the screen can render at a much higher rate so the 2 buffers blend in your eyes and you see all the lines at once.


TomToad(Posted 2016) [#25]
@Bobysait: That wont work properly on all systems.
First, depending on the video card, drivers and os, There may be more than 2 buffers being used. Some systems use triple buffering, or even more.

Second, you don't know what happens to the screen buffer after it has been "flipped" out of view. Some systems simply place it back on the buffer queue leaving the contents unchanged, some clear it first before placing onto the queue, and some will destroy the buffer and create a brand new one.

That is why, as mentioned before, you should never rely on the contents of the back buffer.


Bobysait(Posted 2016) [#26]
Well, you know, I'm cartesian.
so ... as an anonymous said, at worst, I'm wrong only by a bit ^_^


dw817(Posted 2016) [#27]
If everyone would leave their egos at home, topics would probably have more chance of staying on topic

Thanks, if someone can keep his leash on, I'll be happy to produce more code. Failing that if I get more personal insults I'll just post EXEs - if my source code is that amusing to look at.

Hi Dave. Ah, but did it use ALPHA to give an interesting glass effect ? :) I'm running a quad-core 64-bit Window 8.1 pentium. It's certainly a lot faster than my computer upstairs. :)

I'm just barely getting around to understanding a new command right now, "CreateList." I'm going to spend the day learning it and I think it will help my code for moving objects.

Bobysait & TomToad, what would be a written solution in the code above to prevent against this ?

Now when I was using Flip() without a number, the program ran REALLY fast, but right as it got to about 5000 iterations the screen started to flicker terribly. Now I'm using Flip 1 and clear the screen after 3000, that seems to work, no flicker here.

NOW, if I don't clear the screen at all, then yes, it starts to flicker. And - I'm not really sure why. I'm reading the answers you guys are giving.

One serious advantage would be to have a hidden screen to work on. Just plot only to it and then every machine cycle copy that hidden screen to your true display. If I could that, I would never need flip(). I know I did that for Turbo Pascal years ago.

But that hidden screen would also need to be able to handle your basic line(), rect(), oval(), plot(), grabimage(), grabpixmap(), drawimage(), drawpixmap(), readpixel(), writepixel(), and drawtext().

With that in place, it would be impossible to have flicker no matter what the contents were and no matter how long you ran them for.


Derron(Posted 2016) [#28]

One serious advantage would be to have a hidden screen to work on. Just plot only to it and then every machine cycle copy that hidden screen to your true display. If I could that, I would never need flip(). I know I did that for Turbo Pascal years ago.

But that hidden screen would also need to be able to handle your basic line(), rect(), oval(), plot(), grabimage(), grabpixmap(), readpixel(), writepixel(), and drawtext().



Ohh... If there only was something which allows to redirect the draw commands to an image ...
(though, even this needs a "flip()"...)


But let's wait with what others come up.


dw817(Posted 2016) [#29]
I appreciate the sarcasm, Derron. No, it doesn't use Flip(). Remember GFA ? They never had the command flip(). Instead I had to use BITBLT NewDC,H,V,X,Y,_dc(),H2,V2,Typ

Where _DC() was the main screen.

Now correct if I'm wrong. What FLIP does in Blitzmax is place you to WRITE on a 2ndary page that is not seen. And what is seen (READ) is the first page.

If you use FLIP, then all they do is swap visual and writing pages - no copying involved, and it's rather quick.

The technique I am talking about does not FLIP anything. You draw to one and only one hidden page all the time. Then you use a command like UPDATE and it will raw copy all pixels from the hidden page to the main - there is no flipping involved.

If it is fast, and I suspect it would be, I would much rather have this in all cases rather then the command flip().


kfprimm(Posted 2016) [#30]
What you want is single buffer rendering.

Try this.

SetGraphicsDriver GLMax2DDriver(), 0 ' 0 is important. No GRAPHICS_BACKBUFFER.
Graphics 320,240
glDrawBuffer(GL_FRONT) ' Throw that in for good measure.


Remove your calls to Flip and see what happens. You may need to invoke glFlush to force the drawing operations to happen.

No warranty on the code. Complete speculation!


Bobysait(Posted 2016) [#31]
I posted long time ago a kind of RenderToTexture method for openGL drivers.
It supported all the max2d stuff, so you'll be able to use it for your purpose.
Just search "FrameBuffer" with user "bobysait", you should find it.
it was relative to a "virtual canvas" as far as I remember.


dw817(Posted 2016) [#32]
Hi Kfprimm:

I appreciate your enthusiasm, but I can't seem to get it to work. Here is the code I have:
SetGraphicsDriver GLMax2DDriver(), 0 ' 0 is important. No GRAPHICS_BACKBUFFER.
Graphics 640,480
glDrawBuffer(GL_FRONT)
glflush
DrawOval 50,50,50,50
Flip ' this command or what is used to transfer the graphics ?
WaitKey


Bobysait, here is what came up, which article did you write that lists the code you are suggesting ?




Bobysait(Posted 2016) [#33]
-> test of virtual canvas for max2d


kfprimm(Posted 2016) [#34]
dw817, you need to pay attention to what people write.

To quote myself,

Remove your calls to Flip and see what happens. You may need to invoke glFlush to force the drawing operations to happen.


Interestingly enough, your sample worked on my system. Goes to show how the driver behavior can vary from system to system.

This sample has been tested.

SetGraphicsDriver GLMax2DDriver(), 0 ' 0 is important. No GRAPHICS_BACKBUFFER.
Graphics 640,480
DrawOval 50,50,50,50
glFlush
WaitKey



dw817(Posted 2016) [#35]
Okay, Bobysait. Checking ... your code here is 366-lines to create and access a single hidden screen. Wow. (Hoping Kfprimm fixes the smaller example above).

Bobysait, back to your code and functions. Two things.

[1] How do you initialize the hidden screen
[2] How do you transfer all hidden contents back to the main display


Bobysait(Posted 2016) [#36]
ok, this is your sample using the virtual canvas sdk

The sdk is not 366 lines, it includes a sample at the bottom.
For sure it's bigger than working on front buffer, but it doesn't deserve the same purpose.
using the virtual canvas allows you to render on a kind of texture
it works like a blitzmax image in the end.
SetCanvas (the_canvas) -> All you draw is drawn on the canvas (the offscreen frame)
SetCanvas (Null) -> return to the backbuffer.

DrawCanvas (The_Canvas, x,y) -> Draw the canvas the same as it would draw an image. (you can also use blend modes, alpha etc ...)





dw817(Posted 2016) [#37]
Hmm ... This sounds suspiciously like that Virtual Page method I tried earlier only to find grabimage() and grabpixmap() did not work on it. Let's try here though.

Oh, you used my Kaleidoscope program, okay. Running, looks good, can you do full-screen (no taskbar is seen) with your canvas ?

Checking CPU, a little more than 1.5% in use, nice job !!

Awright, now lemme really pick through this thing proper and see what you are doing here - AND test it with grabimage() and grabpixmap(). Hope it works this time ...

Pause, I see Kfprimm wrote back. His 5-line sample works fine. Wow ! Small code, Neat ! I needed this weeks ago.

Here is an animation test:
SetGraphicsDriver GLMax2DDriver(), 0 ' 0 is important. No GRAPHICS_BACKBUFFER.
Graphics 640,480
Repeat
  Cls
  DrawOval i,50,50,50
  i:+1
  glFlush
  Delay 1
Until KeyDown(27)
ZING ! There it goes ! :D I've never really used the delay command before today - looks like I'll need it now !

But now there's another question, if FLIP() is out, how do you make for maintaining the program at the same speed no matter the CPU power ?

And yes, my hand is raised, Bobysait - your program works very well too. What does your program do, however, that Kfprimm's does not ?

Why would I use your code over Kfprimm's smaller ?

I'm not trying to be rude, I'm honestly and truly (being as nice as I can be) and really wanting to know what is going on in your code that made you write it to such lengths ? How does this differ from Kfprimm's ?

Now I need to test both your entries with grabimage() and grabpixmap(), however, I think they're going to work just fine.


Bobysait(Posted 2016) [#38]

Didn't need it, but now there's another question, if FLIP() is out, how do you make for maintaining the program at the same speed no matter the CPU ?



the delay can do this. just surround your loop with two variable that stores millisecs()
set the delay value according to the time elapsed and you'll get a fully control framerate (that will get consistent until your framerate goes above 1000 fps ...).

--------------------------------------------------------

can you do full-screen (no taskbar is seen) with your canvas ?


Sure, just modify the "Graphics" parameter like a normal use.


What does your program do, however, that Kfprimm's does not ?


Actually, a lot of things probably, all what RenderToTexture can do.
It was not coded for rendering like on the frontbuffer (what the Kfprimm does).

All I can say, it's that you probably will have a use for it one day, when you won't remember you had it.
So, it's the kind of code you put in a module and save it for later use.

Imagine that you need to work in backbuffer (like it's really mostly always the case) and you have this kind of effect that require to not clear the effect ... but if you don't the rest of the screen don't get cleared and it's dirty ...
with the virtual canvas, you have no problem to do it
-> To simplify, it's the same usage as drawing on a pixmap within the loop. You can write to it, clear it, draw it on screen, and nothing you do on it affect the screen, so as nothing that affects the screen affects the canvas.


I won't explain in detail what is RenderToTexture, it covers a large panel of usages so, google it, maybe you'll find something interesting to do with it.
Else I won't blame you, I just suggest it because it could do what you want.

and BTW, working in frontbuffer on nowadays, it's a bit like making wine with the feet ... it's possible, but it's not how we work anymore.


Kryzon(Posted 2016) [#39]
how do you make for maintaining the program at the same speed no matter the CPU power ?

That's related to the main loop of your game.
There's some science behind this subject. The two main articles on this I remember are these:

- http://www.koonsolo.com/news/dewitters-gameloop/
- http://gafferongames.com/game-physics/fix-your-timestep/


dw817(Posted 2016) [#40]
Bobysait, I've got big feet if that's what it takes. :) No, seriously, won't using frontbuffer fix the flicker problem completely (topic at hand) ?

And - if so, why isn't anyone else using it ?

Kryzon, looking at the articles. Ohh ,,, that's knocking around a few pendulums in my head. Ok, yes - I had to do this in QBasic years ago. What I did was write code to calculate how many iterations could be done in exactly one-second of time - and build a routine to give proper snips of time.

It actually took 2-seconds cause I looped until the time changed, then I started calculating. Hmm ... I may have that be an option that appears if the code is being run in final mode (?Not debug).

Still experimenting with yours, Kfprimm.


dw817(Posted 2016) [#41]
Here it is, Kfprimm, and the test for your method:



Your code gives correct results all the way around, congrats ! :D

Bobysait, I am going to be using Kfprimm's method for all my future work (till it breaks, hopefully not) but I WILL back up your code, as you say, if I need it later. Thanks for all the help and contributions !

I'll go to update the top Lights Fantastic with the new method and see if that takes flicker out of it completely. I'll even let it run until you hit a key which clears the screen - that will be a real test of no flicker !

Updated ! You should totally try it out now (code on top !) It runs really fast and really sweet !

CPU usage ? <0.5 % !


Casaber(Posted 2016) [#42]
I find dw817 amazing Ppl like him is what makes places like this worth going to.

In most of these kind of forums often you find only trashing, ignorance and petrinizing, you find ppl bullying eachother and sort ppl by what they know or not, and talk to them differently. Helping gets to be redirecting as best. Not him. He offers hands down some help. Right here and now.

So ya.. I wanted to help out with the screen buffer problem, I know you wanted to have a buffer as in GFA.

Use the link not the box. Because the it uses long lines I couldnīt post all of it. So go for the link.

http://www.megafileupload.com/a7cu/retro.bmx

'
' 60hz Smooth screen pixel access on 2010+ Mac's and PC's
'
' It does not use pixelshader nor PBO, but a simple memory-to-GPU transfer every frame. This practically saturates at about 4GB for an old 2010+ Mac' or PC.
' Meaning a full 1920 x 1080 are perfectly possible at 120hz (or two frames at 60hz if you want that for some reason) on most old machines. It only goes up from there. 
'
' You get 60 fps pixelaccess of your full screen (1920 x 1080 or similiar is very realistic).
' Full pixel access reading writing, and it's perfectly possible at 60hz without stuttering.

' This use no GPU whatsoever, it relies on the CPU, BUS and MEM to be fast. Luckily today it's not a major problem.
' The problem using this technique is instead the speed of the language itself and how it compiles. 
' Becuase the array that are manipulated is huge this means that instructions gets too expansive to neglect in these huge quantities (even by todays standard). So despite popular beliefs - we need do optimize here.
'
' You need optimization every bit you can and you'll notice that when you start doing more and more complex things, e.g. try some trigonometry or even standard random functions and see it quickly die off.
' With BlitzMax this goes with simple IF THEN aswell, so try to use simple primitive such as + shl or even explore things like Sgn And Abs (which seem strangely fast in BlitzMAX if thet are they makes them into good optization tools).
' But you do need To think about code speed when manipulating the array. The array behaves just a classic screenbuffer.
'
' Here's a reminder of what sizes we're playing with and why careful coding and optimization needs to be done in the inner loops;
' - A 320 x 240 resolution is about 70 KB (32 bit graphics).
' - A 1920 x 1080 is 2GB (32 bit graphics).'

' This kind of slowdowns means oldschool & general knowledge about assemblers and compilers applies very much what we need to think about iside the loops e.g. 
' use minimum of IF THEN, converting multiplications into shifts etc everything is valuable. 
' It also means that you may want to use your knowledge about memory alignments and common practice how to transverse BlitzMax arrays quickest possible.
 
' Load some suiting retro graphics
Global buffer:Int[128*128] ; Local myhex$ = "0123456789ABCDEF", w:Int, h:Int, line$
RestoreData tiles ; ReadData w ; ReadData h
For Local y:Int = 0 To h - 1
	ReadData line$
	For Local x:Int = 0 To w - 1
		Local word$ = Mid$( line$, x * 8 + 1, 8 ), pixel:Int = 0, shift:Int = 28
		For Local i:Int = 1 To 8 ; pixel :+ (Instr( myhex$, Mid$(word$, i, 1) ) - 1) Shl shift ; shift :- 4 ; Next
		buffer[x+y*w] = pixel
	Next
Next

' Graphics mode
Global xres:Int = 1920 ; yres:Int = 1080 ; Global pixels:Int[xres*yres]
GLGraphics(xres,yres,32,60,GRAPHICS_BACKBUFFER + GRAPHICS_DEPTHBUFFER) ; HideMouse ' Fullscreen, for windowed use instead GLGraphics(xres,yres,0,60,GRAPHICS_BACKBUFFER + GRAPHICS_DEPTHBUFFER)
glViewport(0,0,xres,yres) ;  glLoadIdentity() ; glMatrixMode(GL_PROJECTION) ; glPixelZoom(1,-1) ; glOrtho(0,xres,yres,0,0,1) ; glRasterPos2i(0,0)

' Main loop
Repeat

	' Demo a CLS, example how to clear the array (non-optimized yet)
	For y=0 To yres-1 Step 1 ; For x=0 To xres-1 Step 1 ; pixels[(y*xres+x)] = 0 ; Next ; Next ' stepping is not needed if you only use 1
	
	' Demo 128 sprites
	' The only reason that we do this is to show that the fullscreen buffer is very much alive and up and working, ready to be used.
	' Itīs there so you should be able to decide that there's a smooth 60hz movement happening or not. Remember itīs not about the sprites or few pixels that they are made of. 
	' We shuffle the whole buffer each frame either way if we use all the pixels or not. If it is smooth. You can go wild with your new pixelaccess fullscreen.
	
	xsprite=xsprite+2 ; ysprite=ysprite+2 ; xsprite = xsprite Mod (1920-512) ; ysprite = ysprite Mod (1080-512) ; temp2=temp2+1
	For temp=1 To 128
		ysprite = temp*2
		' Draw one sprite (coordinates are xprite & ysprite) (same goes here, partly un-optimized code)
		base = ysprite*xres+xsprite+(temp*32) ' Sprite coordinates are xsprite And ysprite
		tempy=0 ; For y=0 To 127 Step 1 ; For x=0 To 127 Step 1 ; pixels[base+x+x+X+X+tempy] = buffer[x+(y Shl 7)] ;	Next ;	tempy=tempy+xres+xres+XRES+XRES ; Next
	Next
	
	' This writes the array to the GPU, amazingly this is not the major bottleneck even on weak machines.
	glDrawPixels(xres,yres,GL_BGRA,GL_UNSIGNED_BYTE,Varptr(Pixels[0]))
	Delay 1 ; Flip 1

Until MouseDown(2)
End





dw817(Posted 2016) [#43]
I - very much appreciate the sentiment Casaber. I try to help when I can, it's usually returned tenfold, such as today.

While Front Buffer may not seem like much, it is going to make my work =SO= much easier - and execution time is a LOT faster than with flip() even after a delay(1) statement.

I really and honestly thought flip() was running as fast as it could to keep flicker-free graphics. No, not at all. GLFlush() and Delay(1) return very smooth and VERY fast graphics. Can't be beat.

I had to go into my keyboard code for Tilemaster and increase the timer delays multiplying by 10 as everything was a blur !

That's extra CPU power I can run in the background with other things. BlitzMAX with that little bit of Front Buffer code to me is now a slice of heaven. *Grin*

I'm trying out your program, Casaber, really curious to see it. I run and get a hardware shift on my monitor and the resolution does not work (images flicker and are drawn incorrectly).

I stopped it, closed the output, then tried to change the resolution to 1024x768, the one my monitor handles:
Global xres:Int = 1024 ; yres:Int = 768 ; Global pixels:Int[xres*yres]
and it crashes HERE:
tempy=0 ; For y=0 To 127 Step 1 ; For x=0 To 127 Step 1 ; pixels[base+x+x+X+X+tempy] = buffer[x+(y Shl 7)] ;	Next ;	tempy=tempy+xres+xres+XRES+XRES ; Next
Unhandled Exception:Attempt to index array element beyond array length

That's an awful lot of ";" too. I admit I may use one or two per line with the exception of variable definitions, however ... :)

Also, you might use [ codebox ] and [ /codebox ] (minus spaces) between your code to keep it in a neat box where to copy, all you have to do is click inside, and press CTRL-A, and CTRL-C, instead of highlight copying with the mouse.


Casaber(Posted 2016) [#44]
I want to correct some numbers in the remarks while I'm here and all. It should say

' - 320 x 240 x 4bytes = 0.5 MB per frame (18MB per second at 60hz)
' - 1920 x 1080 x 4bytes = 8 MB per frame (480MB per second at 60hz)

Iīve found that the weakest machines tolerate 1GB-2GB / second in practice, at least, thatīs the worst case Iīve ever found. Well above the needed 0.5GB.

I think I did a bad demo lemme improve it, and to be sure I made it windowed this time (and when windowed works, just try the commented fullscreen line instead)
Windowed mode gives less errors, thatīs why I prefer that when I heard you had problems.

Just replace the actual code and leave the data below END intact. This code should be a correct working demo.




therevills(Posted 2016) [#45]
Just wondering why you are using glFlush?


BlitzMan(Posted 2016) [#46]
.


dw817(Posted 2016) [#47]
Hi Therevills, are you just catching up to our convo ? :)

With it you can copy a hidden page to the main page, which is a programming method I'm quite familiar with. FLIP can give problems like so:



Flipping pages was a real nightmare back on the Apple ][, unfortunately, that was the only way to get really fast graphics.

When I wrote my game packages back then though, I would NOT do that. Instead I made a machine-language routine to copy HIRES page 2 to HIRES page 1 anytime I wanted to update the screen.

I never had to worry about flipping in the wrong places, it was flicker-free always, and perfect - aside from being a bit slower than just flipping viewing pages.

The method of using glflush in BlitzMAX is a godsend to me and VERY fast. The screen does not FLIP at all and I can add all the elements I want, viewing them in-between with no problems and never EVER have to worry about flicker or wrong pages.

When I started BlitzMAX years ago I realized FLIP() was going to be a problem, so - I wrote routines to redraw the screen from CLS to all elements every single machine-cycle before I would do a FLIP(). Now I don't have to ! :)


BlitzMan(Posted 2016) [#48]
.


dw817(Posted 2016) [#49]
Casaber, this time it ran ! it got halfway across the screen and then crashed ...

Nonetheless I like what I'm seeing. Those are some great game characters, :D did you draw them ?

You might be interested in a program I wrote that lets you attach images or really anything you want to BlitzMAX source-code - AND you can upload it straight as a message in the forum.

Lemme find it ... Here ya go. You won't have to use data numbers anymore and you are welcome to use my data converter (Carryall) in your projects. :)

http://www.blitzbasic.com/Community/post.php?topic=105555&post=1288492

I call it the "BOXCAR" edition as with dice, 12 is considered boxcars. And you are converting 8-bit data to 6-bit and back again.

Hope This Helps !


dw817(Posted 2016) [#50]
Nice 3D Robot, BlitzMAN - and you didn't even use a 3D library like SideSign.

... I'm keenly looking at your DrawCube function. Do you have a way of putting 6-different images appearing on each face of the cube - and can add some arguments so you can specify the scale and other goodies ? I.E.:
Function DrawCube(xScrnPos:Float,yScrnPos:Float,xWidth:Float,yHeight:Float,xPos:Float,yPos:Float,zPos:Float)
I am correct in thinking the xPos, yPos, and zPos you have currently is for the rotation of the cube ?


Casaber(Posted 2016) [#51]
Thanks, I drew some most are from the Commodore though. I extracted every character available in the ROM and I threw away the inverted and rotated ones to make room for my other graphics.

Perhaps the best example is the simplest one a simple plot actually. Trust me Iīve already build amazing things with this simple code as base I wish I had some code here with me now. But I think you got the idea. It's amazingly powerful.




Casaber(Posted 2016) [#52]
I've build half an C64 emulator with this. It runs perfectly smooth. with that exact plot even. Not even optimized it yet.


dw817(Posted 2016) [#53]
That last example just gives me a dot on the screen, Casaber ?

I see you're trying to clear an array. That's an interesting point, am I correct in thinking that BlitzMAX does not have a command like other basics such as:
ClearArray Cards()
or
FillArray Flags(),1



BlitzMan(Posted 2016) [#54]
.


dw817(Posted 2016) [#55]
Blitzman, hardware wise I have done a little investigation. If I am understanding it correctly, DX does not have as many 'effects' available as GL but DX is more compatible with computers.

As you have a choice for videogame emulators, I have chosen GL if and whenever possible - and have better results and accurate graphics - at least on my computer.


Casaber(Posted 2016) [#56]
Here, try an Amiga variation.



Full HD fullscreen version




dw817(Posted 2016) [#57]
Hmm ... I may be able to reproduce that, Casaber. Is this the effect you wanted ?



I was adding "#" in front of all the variables. I sometimes forget that once you define a variable in BlitzMAX, it is OPTIONAL if you use "#" for real or "$" for string. Old habits die hard - I'll be working on that this month. :)


Casaber(Posted 2016) [#58]
Yup, how the hell did you reproduce that with that code it does look like nothing like mine haha. Impressive.


dw817(Posted 2016) [#59]
*Grin* When I started working for businesses, Casaber, they would show me commercial software they didn't want to use and ask me to rewrite it completely with changes they wanted in it. As it is I got pretty good at being able to look at data handling methods or even graphics and being able to reproduce them pretty easily, provided they weren't 3D. (Although that may change this month).

The main problem critics have with my code (and there were some guys from Germany working in GFA - and they told me this). "Yes, your code works, but it's not portable in the least."

And by that they meant I used such unconventional methods of programming to just - git R done - and generate what I wanted that in many cases my code was language specific - that is, my code would only run on that particular programming language, possibly hardware specific as well, and precious few other platforms or hardware would run my code.

Whereas your code above is likely the more 'accepted' standard today and I suspect can be easily ported to many different programming languages, including C++


dw817(Posted 2016) [#60]
BTW, I'm still thinking of that character set you had, Casaber. I don't know if you had seen this - I was going to build a BBS called Anonymouse years ago where a mouse was the host and - well, these were the graphics you could do in it, 2400 baud at the time.

[image]

Today ? All for naught it seems. But, who knows. Maybe you could get some use out of them with your interest in classic and retro graphics ? :)


Casaber(Posted 2016) [#61]
I like the retro and naive look on those graphics, really nice.

I discovered this technique beats Blitz3D with being exactly twice the speed on my machines. I'm not sure why, I guess DX7/OS uses one buffer "too much" that's really not needed and it's somewhere in the chain inbetween WIN/DX/B3D and uses exactly this or a similiar method, this would explain the half capping of the speed at 1 Million pixels.

Writing pixels this way using OpenGL has been bashed alot as being slow, I guess it once probably where because opengl implementations simply was no good.
But in the last years OpenGL implementations seem to have improved exponentially. I don't even see the need for DX any longer and this shift seemed to start happen just around about 4-6 years ago, it should be okay to start to embrace it..

With this you may plot at least 2 million pixels each 60 hz on even weak machines and you get amazingly quick read/write pixel access (as it's an array / bank).
You have never had a quicker pixelbuffer in your life ;)

If I could get my hands dirty and just put SOME assembler in the inner loops and have all the control what's happening, that would be the sweetest thing.


AdamStrange(Posted 2016) [#62]
MMM, did a quick test on the two different but visually the same. but with very interesting CPU results:

Casaber: 18.3
dw817: 27.4

so just by going by those results. Casabers version wins and has less CPU use than the other.

I really like the quick detailed look at the GL code to deal with pixel drawing - very cool :)


Casaber(Posted 2016) [#63]
@ AdamStrange

Actually I think Itīs because things like MOD and RAND are used alot in his loops, and those are awfully CPU eating instructions in Bmax.
He uses GPU for everything and I intentionally use CPU so his code has definitly the better potential to be cheap on CPU. Try replace those with something cheap and I think things will change.

But donīt take me wrong, if you need pixelaccess then what I trying to do works amazingy nice, one just has to separate the slowdowns.
Heīs code is only more CPU demanding becuase of BMax's slow logic in some instructions

My approach to only use the GPU for getting an array over to the screen in a decently effecient way still need manipulating that array and that will cost you some CPU time,
so itīs not very CPU friendly.

With my i3 3Ghz with i manage one 1920x1080 screens (almost two, but not quiet) It handles about almost 3 million pixels perfectly.
While my i5 1.9Ghz manages more than double, and both machines uses same or similiar speeds on memory and buses overall, so ya it's tricky to know what to expect.

But 1 full HD screen is easly plotted on any machine and you still have lots of CPU time left to do lots of stuff. Which is nice.


Endive(Posted 2016) [#64]
Casaber this is amazing, thank you so much.


dw817(Posted 2016) [#65]
Morning gang. I just tossed that code together looking at Casaber's - no big. Mine may run slower with the delay 1 I have listed in my code, but I'm good with that. *Grin*

In any case it uses .25% (not even 1%) of my CPU. Casaber's if you're curious (checking last code w Process Explorer) pegs my CPU at 23.4%. If it's a race (which I was not aware of), he can have the prize. :)



Casaber, what is GPU and how is it different from CPU ? Not familiar with the term.


Casaber(Posted 2016) [#66]
GPU?

I guess just as the CPU and itīs memory makes up a world of their own, the graphicscard makes up another world with itīs CPU and memory.
And itīs called GPU. (Graphics Processing Unit instead of Central Processing Unit).

The important thing is that there's no way for the CPU and the GPU to glance over eachothers shoulders and access things, they may only talk using API like Opengl And DX.
Everything that happens in the GPU world are called "hardware accelerated", while things happening in the CPU world are called "software rendering".

These GPU's are very flexibly in how they could be used,

The standard way doing hardware accelerated rendering. Here you use upload static images from the CPU once into the GPU world and then you splash those images onto the canvas (backbuffer),
you could also use any primitives that the GPU happens knows how to draw. It's not very flexibly and thereīs not much useful pixelmanipulation, just splatting premade images on the canvas.

Then there are two main appoaches that adds flexibility inside this GPU world:
- The first improvement is VBO which adds the flexibility to draw images not only the canvas but also onto other images (which in turn may be painted anywhere not only backbuffer), much more flexible but still no pixelaccess though.
- The second improvement is when we have pixelshaders which gives pixelaccess (and it happens inside the GPU world). You transfer your actual pixelaccess-code to the GPU,
that in turn does what you want with the pixels as a helper CPU that happens to live where it needs to have quick access all the pixels.

The last approach (this one) adds flexibility in that it opens up the gate between the worlds, by sacrificing some power to get the added flexibility of pixelaccess
We use the CPU world exclusively to build up our single screen that we want To display and then transfer it to the GPU.
We're basically just streaming a piece of memory at e.g. 60hz.

The only hardware acceleration happening about this is the actual transfer though, I know you could add multiple whatīs called "PBO's" To speed up the transfering.
But there's alot of things happening with OpenGL right now and Iīm not keen in learnining those details when they might go old within a year.


dw817(Posted 2016) [#67]
Yes, I think you are getting a little extra kick in your program by going to a hardware resolution. Still ... really looking over your code - you have xres and yres at fixed values.

To be more compatible with users who have different resolutions on their computers and laptops, you could use:
xres=DesktopWidth() ; yres=DesktopHeight()
You will see you don't have to initialize graphics before this - so you can know someone's resolution every time.

And yes, :) there are indeed a lot of things happening in your code. Really a marvel how fast you throw those pixels out with your array.

You may like this too as a way of stuffing fast pixels:




Casaber(Posted 2016) [#68]
Iīm not sure why PIXMAPs never seem stable for me, itīs not stable on Mac's, not even smaller buffers, neither on the PC's Iīve tried.
Otherwise I would have used that. But I really needed smooth graphics. Iīm really pleased with Bmax now.

But I was abit dissapointed on Monkey 1 it's not smooth nor powerful in that aspect, itīs very jittery even with Mojo2. I haven't had the time to explore that fully yet but I feel it's beyond my hands in Monkey 1.
I do see a very nice language though, so I thought I would support either way.
I'm hoping for Monkey2 will offer smooth graphics and able to have things like quick integer arrays and able to do lots of pixel manipulation when you need it.

Actually I bought Monkey mainly just to support Monkey 2, bc I knew Monkey 1 wouldn't probably work for me as I wanted.


dw817(Posted 2016) [#69]
You've bought Monkey-X ? Could you please post a FLASH of a program you've written, Casaber ? Anything will do. I'm just curious to know if the graphics are not smooth in that format as well.

As far as pixmaps go, when you DO create one using the CreatePixmap() command, if you don't plan to write to every single pixel yourself, you need to use the command ClearPixels() as trash bytes can appear on it without this.

Other than that, I've never had any problems with pixmaps ! They work quite well for what I need. Just wish when I used drawpixmap() that you could rotate, scale, and alpha plot, that's why I'm using the code loadimage(pixmap) in-between so I can scale it.


Casaber(Posted 2016) [#70]
You have to install each platform you want to compile to I've never used FLASH, I tried though but it failed. I hate this kind of crap. I need a break or I will explode.

About pixmap no, never never *ever* it was smooth for me, I tried all kinds of tricks but no..

You got me an idea though with when you mentioned rotation and alpha.

PBO seem actually not that old, its more an extension to VBO. Meaning VBO is painting images on images.
And what we're doing above s painting CPU Memory to the screen. What if we paint the CPU memory into another buffer?

Which is what PIXMAPS tries to do of course but will all that cost when converting between PIXMAP and TIMAGE makes it useless for realtime.

I would like to try to change the code to do that. I'm not sure how to approach it though but I know it wouldnīt take much code. I need to think for abit.

This would bring together ALL of the individual advantages of above.
Painting images on screen, Painting images on images, painting CPUmemory onto images (and not only fullscreen as the destination).


Casaber(Posted 2016) [#71]
I tried again FLASH but no luck, if you REALLY really need it I could try again before the weekend but
It's not much I can do really that I know of Iīve set the path right I did download the SDK. Im starting to have horror dreams Monkey might need a certain version of the flash SDK, Iīve been in that ditch too many times with JAVA and whatnot, Flash seem even less documented.

I was quickly looking around, and you better donīt have high hopes even then..
http://www.monkey-x.com/Community/posts.php?topic=731

You need that for a client? HTML5 is really the way to go if not.
In Win10 which comes with IE11 Monkey 1 HTML5 is as smooth as Bmax. Chrome and other browsers they all are having a hickup party. But Win10 + IE11 *thumbs up*.


dw817(Posted 2016) [#72]
It's no big. Get some sleep. I have to admit, I've even been burning a little too much midnight oil myself. :)

After thorough testing, there is no doubt now that your pixels are faster than anything I can come up with (tested and retested), but you can't use any of these commands with it:
SetColor Red,Green,Blue
SetAlpha Solid#
SetRotation Rot#
SetScale X#,Y#
That can only be done with DrawImage(). Here is my code using your plotter.



Now, I was reading this night some people were saying drawing QUAD is even faster than glDrawPixels(). Might be worth investigating as I don't know really know what that is.

Nonetheless, get a good rest, you've earned it. Definitely the fastest pixel and bang for the buck. :)


Casaber(Posted 2016) [#73]
I'm just about to get to sleep here, it has been such a long night, full of extra strong coffee and learning, not so much any practical code yet. I'm trying to grasp this
http://graphics.snu.ac.kr/class/graphics2011/materials/ch12_pbo&fbo.pdf ) to be able write quickly into a texture which would actually solve your problem and give alpha and rotation.

Im not sure about Quad, I remember I started in that end and I donīt think that's the best solution but I could be wrong.
About the current glDrawPixels my thoughts are that despite itīs actually an old way doing things, it has never been as good as now simply bc of developments in hardware that has happened.
When it was brand new computers lacked the cpu speed the memory speed, the bus speed, and it wouldntīt even have made a difference if you went out and got the best Graphiccard in the world,
you still had the same busspeed. I think that started the rumour about it. This is not true anymore.

Unfortuently they're forcing the it away (https://www.opengl.org/wiki/Common_Mistakes) but API-developers usually do their part of the deal of both keeping and optimizing general things for awhile and only improve if anything.
Glwritepixels is having its hayday.

But there must be a change to get those features mentioned above; including rotation, scale and alpha.
It looks like itīs time to dive into OpenGL. I donīt have much time and this is not something you do within a week. I never stop to amaze myself how I keep hoping to solve every problem in the world overnight, but not this one.


dw817(Posted 2016) [#74]
Starting some coffee here, Casaber. Despite how fast your pixels go I am going to experiment with double-size using loadimage(). Essentially it'll be your code running on a 512x384 screen but with double-pixels that's 1024x768, and that's fine.

Because of the lesser # of pixels needed to plot, I should be able to make some interesting libraries and routines done solely at the touch of a single pixel.

If the rotation, scale, and alpha are to be met by your code, I suspect strongly you will not be using the common commands but the GL equivalent - and they may be out there. I'm not seeing an easy way of bring up GL commands in BlitzMAX.

In fact, if you click on HELP in BlitzMax on OpenGL you don't get very much.





Good hunting sir !


Casaber(Posted 2016) [#75]
Ya I do that too alot, that's why you see STEP all over the place, I skip or double them in the rendering routine. Becuase 1920x1080 is waaaay too much for most things. Itīs just a waste really.

Not even for realistic 3d games that kind of resolutions are needed (quality is about other things), same goes even more for retro stuff (even if you want smooth glowing ontop).


Several million dots to tell a good story - Itīs just not needed.


For anyone interested here's a few good links
http://www.slideshare.net/CassEveritt/approaching-zero-driver-overhead
http://www.openglsuperbible.com/2013/10/16/the-road-to-one-million-draws/


dw817(Posted 2016) [#76]
Don't rebuild the PS3, Casaber !

*Grin* Yeah, I learned long ago while I may eventually be able to handle and understand writing 3D games, in truth, I would always want to do topview map & sprite graphics like I grew up with on the Nintendo and Super Nintendo.

BlitzMAX's primary function was not 3D, that's why there is a language called Blitz3D, however - I would like it if you stayed with BlitzMAX as I am definitely learning from you.

And I see your work invaluable for anyone who wants to write their own from-scratch pixel libraries with your very fast renders.


Casaber(Posted 2016) [#77]
Hah no worries, no PS3 and no 3D neither Iīm all 2D at the moment, I think we share alot there. Nintendo, NeoGEO, older Arcades, and ya all that good stuff, I think even if I hadnīt experienced those things as a kid it still has something special that speaks to people. I love those kind of things.

The first thing I would use any pixelshader for would be create the best CRT style looking graphic ever and make that into a small project on its own;)


dw817(Posted 2016) [#78]
I've heard of pixelshaders. In your own words, can you tell me what they are and how they might be useful in a fast-pixel quest ?

I'm still looking at that robot demo that BlitzMAX posted out of the blue and wondered if there was a way to create a 3D cube with the same or 6-different pixmap or images on the facets. I could do something with that.


Casaber(Posted 2016) [#79]
The nice thing is that GPU's are designed to be extremely parallal and powerful, even with low Mhz/Ghz.

Graphics cards are becoming very general machines, Itīs sort of a factory setup (called the "pipeline"). They used to have alot of steps, and very specific tasks at each step.

I see nowadays graphics cards have simplified these steps, they are fewer and have become very general what they are able to do.
So general that chances are that the "G"in GPU soon will stand for General Processor my guess is.

Here' where shaders comes in, it's the most general part on the GPU's and they come in two flavors; Vertexes and Pixels.
Shaders allow you to simply upload some code into the GPU and run that it to do some manipulation on your Vertexes or Pixels.
So shaders becomes *the way* to use all the raw power of a GPU and have at your fingertips and do whatever you like.

You use GLSL, which is a standard and part of Open GL, itīs a weird mix of the language C (look-alike) together with shader instructions
(which I guess you could call shader assembler) Iīm not sure what to call it. Personally I just use the term Shader instructions.

So you use GLSL and write your small snippets of code and upload to the GPU at runtime and decide what it should affect.
It could be recoloring a sprite for example in realtime. It could do stuff like render the fullscreen in wavelike motion or create a CRT look, or even render an photo realistic ocean live (this needs high end still but it's moving, but rarely 60hz for these kind of things, there's a limit even with GPU's) .

That's the basics anyway. The only caveat is that you have to think very differently you're programming these shaders, because itīs parallal
meaning you have to access pixels in a kind of a different way than you usually do.

But I guess, that's part of the fun. Itīs a new challenge to do parallal coding.


TomToad(Posted 2016) [#80]
Ok, thought I'd have a go at my own version. Doesn't glow or use alpha at all, shouldn't be too hard to modify code to add it. I do like the way I have the colors cycling through the life of the line. I think in fullscreen, it could make a decent screensaver. :-)



TomToad(Posted 2016) [#81]
A little playing around and I came up with something really cool :-)



dw817(Posted 2016) [#82]
Tiger Stripes indeed, really very impressive, Tom !

I see you are using a rotating 'plank' to draw with. I did that in my earlier, "Kaleidoscope." When I was working on an earlier version of S3, I did that. But the "Lights Fantastic" was a different method, and I liked it better. So I made it part of my current engine. Just hit CTRL-K anywhere at all and it pops up over the map editor or item editor or wherever you are.


This is the original Kaleidoscope, hearkens back from Commodore Amiga, 320x200 pixels with 8-bits per pixel.

http://www.blitzbasic.com/Community/posts.php?topic=105560

Colors were made in a PALETTE. Because you could change the palette at any time, you could have interesting animation effects without plotting any new pixels.

I've got some QBasic DOS stuff that does that. You can try it in DOS BOX if you like.



It probably got lost in the shuffle. :)



This would be a difficult program to convert as it animates the hardware palette.

. . .

Casaber, I guess what I'm hoping for is to find a routine that let me build a polygon and have any 2D image on it. So if I put it on a triangle for instance, X1 and X2 would meet at the center, but X1 And X2 below would be apart, to make a triangle, so it would warp the image you put in it.

Doing this it should be possible to build 3D cubes with images on them. Then it's just a matter of stuffing them in a 3D array so you can build dungeon walls, corridors, and rooms.


Casaber(Posted 2016) [#83]
Ah then you want Quads, I guess triangles are non-intuitive, and so are polygons, but Quads are prett intuitive to use.

Pushing the buffer into one of those allow more than rotation, scaling, it allows you to move each corner and the content to be warped along with it. I have that on my list just for that reason actually. I donīt know of any better way to allow easy warping. We'll see if it could become a reality. I want to forge these feature nicely and I might have to re-arrange things to get it that way, even throw away something and do it differently.

For example why have CPU pixxeling if you have Pixelshader aswell but I feel that want both for different reasons, also pixelshaders are not that much powerful if you donīt need floatingpoint, it's about x8 - x 16 more power than this CPU above (comparing with a common medium GPU).

Same goes with that I would like to have not only stream software rendering onto a Quad but also stream a playing movie, at least one, prefferable multiple.


TomToad(Posted 2016) [#84]
Now I'm having fun. Here is Lines - Running Tiger Edition. Making use of alpha and a rotating texture to create a dance of colors. Best in fullscreen.

Will have to check out your kaleidoscope code, but first need to install DosBox and QBasic :)



Casaber(Posted 2016) [#85]
I'm not very used to play movies using acceleration but with Blitz3d I could play movies using Writepixelfast. Which was pretty fun.

I wrote an app to catch the playing movie into an array (very small of course as I saved it non-compressed, I wasnt THAT ambigtios).
And then wrote another app for playing that same saved array at its original fps (much much smaller in size of course but it had nice quality.

So I had several intros from a few TV shows saved as arrays of pixels, that I could play perfectly.
Just a fun thing to do, it might inspire ppl what could be done without acceleration.


Casaber(Posted 2016) [#86]
@TomToad nice, I like that last one it feels very polished.


TomToad(Posted 2016) [#87]
Ok, installed DosBox and QBasic. Ran the code above. Color me impressed :) There is a bug though. On line 22 you have WHILE A <> 14735: WEND which is basically just an endless loop. Once that line was removed, everything ran fine.


BlitzSupport(Posted 2016) [#88]
Started reading thread, decided to lock thread... turns out no need. Phew!


dw817(Posted 2016) [#89]
That's my silly (very silly) way of ensuring no-one changed my 'copyright' info by binary patching the EXE (the only thing I released years ago). I just nulled out the address without even looking. So it ran fine huh ? That's neat, that must be like - gosh - 25 years since I shared any of my QBasic stuff with someone. :D

Glad you like it ! Shoot ! I forgot all about QBasic, glad you could find it Online. I have 4.5 here. They ACTUALLY made a QBasic 7.1, but I never used it.

In DOS BOX, you can hit CTRL-F12 to make any DOS program run faster, or CTRL-F11 to make it run SLOWER.

If you don't mind SNAPPING your monitor, you can press ALT-ENTER and it runs full-screen.

Trying out your new Tiger Stripes, yeah, you got the palette to cycle, awesome ! :)
. . .
Casaber, back in the day when I was working on Turbo Pascal, I wrote routines that kept track of every single pixel on the screen and if I wanted to do an effect, I could have them explode - go all over the place, or even have every pixel on the screen do the explode effect.

On the line of controlling pixels, however, I was thinking of writing an example in a fresh post based on Bob Bishop's Bomber game, a tribute to his excellence and coding.



http://apple2history.org/spotlight/bobbishop/

He made this game called Bomber. It was a technical marvel for it's time as every pixel for the jet and tank were painstakingly drawn from a machine-language array and executable. You drop a bomb that follows a neat curve and if you could HIT the tank, every pixel on the target tank exploded in a shower of pixels. Can't find a video for it in Youtube.

Anyways, I will definitely do a tribute for the guy using TYPE variables, also as a test to ensure I know LINKED LISTS at this point.

Hmm ... Looks like I'm overdue for making a good vector-maker. I'll build that first and post it.


TomToad(Posted 2016) [#90]
After viewing your QBasic program, I thought I'd see if I could get some kind of pallet rotation going in BlitzMax. Palette Rotation


dw817(Posted 2016) [#91]
Yep, I can see that, Tom. I wrote you there. I needed a good font to display for the vector maker I'm working on so I made some code for that too - you can find it HERE:

http://www.blitzbasic.com/Community/posts.php?topic=105678

This vector generator is going to be a bit different than my original. The first one I wrote would only let you make polygons, not where you could have a line intersect inside an area to give it definition. This one will. I want this so the JET and TANK will look good and hollow like Bob had them.

BTW, I was running your Chasing Tiger in 800x600 full-screen and of course it looks great. My question is, does that seem to be the correct way to go to distribute full-screen games ?

Do all OS's (and Macintosh) have a hardwired 800x600x32 resolution ?


Endive(Posted 2016) [#92]
Why would you give this away for free? Write it in Monkey so you can release it on all kinds of devices and sell it!


Casaber(Posted 2016) [#93]
I could fill you in about the Apple Computers / OSX.
From all what I know all Apple's computers manages at least 800x600 and 1024x768. My iMac for example (2010 mid model) stretches the screen vertically and centres it horisontally, on its widescreen (this one uses 1920 x 1080). So you still get square pixels and the antialising method used looks great.


dw817(Posted 2016) [#94]
Endive ? Who are you talking to ?

Thanks, Casaber. Actually my computer uses a resolution of 1920x1080, but I don't do that. I keep it at 1024x768, old school 4x3 the way I like it.

I know many of the Windows games I've purchased in the past will run windows at 800x600 (which to me is kinna small) or you can hardware snap to 800x600, which I also don't like as I can't see my task icons below.

In fact, I think I'm about the only person that writes games that use the full-screen resolution of the monitor while maintaining the buttons below - outside of game emulators which will work with any resolution you choose.

When I saw BlitzMAX years ago able to do this, that was one of the main reasons I chose it for graphics. Today, I'm not disappointed. Finally figured out how to make borderless frames that span the user's screen and keep the taskbar below. Good enough for me. :)


Casaber(Posted 2016) [#95]
I'm wondering why that Pallet example is going crazy in any fullscreen mode that I try to run it with?
It gets about (I guess 16?) vertical tearings constantly moving and flickering. It works amazingy good as as windowed.

It must use some special technique. I really feel the urge to look into this why this is messing with fullscreens and what it does.

haha I love this part. 1st time ever Iīve seen remarks being remarked out. Actually I like that trick.

'Rem	
	'Here we rotate the pallet entries by one. :-)
	Local Temp:Int = Pallet[0]
	For Local i:Int = 0 To 14 ; Pallet[i] = Pallet[i+1] ; Next
	Pallet[15] = temp	
'End Rem



dw817(Posted 2016) [#96]
Are you talking about TomToad's Running Tiger ? It works great here. And - perhaps that's a good point I was referring to. Running hardware resolutions (snap) I never thought it was a good idea with modern computers. You could get different results.

Now in BlitzMAX you =DO= you have the ability of running in virtual resolutions, this is not a problem.
Strict
Local i,j
Graphics 1024,768
SetVirtualResolution 800,620 ' note it's 20+ compensates for taskbar
DrawRect 0,0,800,600 ' yet we can draw to full 800x600 with no problem
SetColor 0,0,0
DrawRect 1,1,798,598 ' hollow out rectangle to show it really fits
SetColor 0,0,255
DrawLine 50,50,200,200 ' simple line
SetColor 255,0,0
DrawOval 400,200,50,50 ' simple circle
Flip
WaitKey
So, yeah, there's no reason to hardware snap, not really. You can use SetVirtualResolution and put it anywhere you want.


Casaber(Posted 2016) [#97]
No this one, it acts up when you try it in fullscreen (at any resolution).
http://www.blitzbasic.com/codearcs/codearcs.php?code=3248

EDIT SOLVED IT, it needed FLIP to become FLIP 1


TomToad(Posted 2016) [#98]
Re: hardware snap: Why would you want to use hardware fullscreen? When you create a window, your program must play nice with any other program wanting to use the screen. This can slow rendering down. Using fullscreen gives the program total control of the screen, speeding things up, and also allowing games to adjust resolution as some games might work better at a different resolution than what your desktop is set to.

There are some caveats using fullscreen, though. As you can see, Windows components such as the taskbar cannot be used. Also ever have a buggy game crash and throw an error, but you can't see it because it crashed before releasing the screen back to windows?

Re:Flip 1: Yeah, I keep thinking that 1 is default with Flip. But actually it is -1. 1 will sync up the graphics to the vertical blank cycle, which will prevent tearing. -1 is a software sync which should reduce tearing, but might not eliminate it, usable in cases where the user has vertical blanking turned off in the graphics driver and you are relying on it for game timing. I din't notice it as my LCD monitor does't tear as badly as CRT monitors do.

Of course, a good commercial game will give the user control over Window settings, game settings, what kind of vertical blanking they want, etc... So that it can run according to their preference.


dw817(Posted 2016) [#99]
Agreed, Tom. In s3 you have massive configuration, not just resolution but is it full-screen, not, speed of program, SKIP of program (if it skips frames), and a whole bunch of other stuff.

Rather be Safe Than Sore. :)

As for your rainbow circle animation, it works fine here at full-screen 800x600, but as Casaber pointed out, it did NOT on his. And that's not your fault, Tom. That's BlitzMAX not being 100% compatible with all monitors when accessed at a hardware level.

You may be able to fix it with a special FLIP(), like 1 (one) as you mentioned above.


Casaber(Posted 2016) [#100]
dw817 here I did an example for you to see how shaders could be done in Bmax.
Iīm still learning myself how to connect the two but I thought it could be fun to see something?

Pixelshader sorts of works like those old lightpens on crts.
The pen I think used the timing or something to tell where it was and was actually an optical sensor, and got x and y position from looking at the moving raster.
Same goes here, pixels only know where they are by reading a special coordinate variable and, hmm damn I lost my idea how to explain this well.. Did that make sense at all?


Mind you that the while loop is just for looks, I should try a more complex example such as a starfield next.


'        50 SHADES of Red
'
' A simple introduction To shaders
'
'

' SET GRAPHICS MODE
Local xres:Int = 1920, yres:Int = 1080 ; GLGraphics xres,yres,32,60,GRAPHICS_BACKBUFFER + GRAPHICS_DEPTHBUFFER ; glewInit ; HideMouse
glMatrixMode GL_PROJECTION ; glLoadIdentity ; glOrtho 0,xres,yres,0,-1,1 ; glMatrixMode GL_MODELVIEW ; glLoadIdentity ; glViewport 0,0,xres,yres ; glPixelZoom 1,-1 ; glRasterPos2i 0,0

' CREATE SHADER
Local VC:String = VERTEX ; PC:String = PIXEL ; PO = glCreateProgramObjectARB() ; VS = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB) ; PS = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB)
Local SC:Byte Ptr = VC.ToCString(),SL = VC.Length ; glShaderSourceARB VS,1,Varptr SC,Varptr SL ; MemFree SC ; glCompileShaderARB VS
SC = PC.ToCString() ; SL = PC.Length ; glShaderSourceARB PS,1,Varptr SC,Varptr SL ; MemFree SC
glCompileShaderARB PS ; glAttachObjectARB PO,VS ; glAttachObjectARB PO,PS ; glDeleteObjectARB VS ; glDeleteObjectARB PS ; glLinkProgramARB PO

' PROGRAM BEGINS
Repeat
	glClear GL_COLOR_BUFFER_BIT ; glUseProgramObjectARB PO ; glBegin GL_QUADS ' Custom attributes instead, glVertexAttrib2f or VA/VBO glEnableVertexAttribArray/glVertexAttribPointer.
    glTexCoord2f(0,0) ; glVertex2f(0,0) ; glTexCoord2f(1,0) ; glVertex2f(xres,0) ; glTexCoord2f(1,1) ; glVertex2f(xres,yres) ; glTexCoord2f(0,1) ; glVertex2f(0,yres) 
	glEnd ; glUseProgramObjectARB 0
	Delay 1 ; Flip 1
Until KeyHit(KEY_ESCAPE)
End

' SHADERS
Const VERTEX:String = "void main(void) { gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex ; gl_TexCoord[0] = gl_MultiTexCoord0 ; }"

Const PIXEL:String = ..
"void main(void) { vec4 coord = gl_TexCoord[0] ; vec4 coord2 = coord ;                                  ~n" + ..
"int temp = 0 ; while (temp++ < 512) { coord2.w = coord.w + coord.y ; coord2.y = coord.y + coord.x ; } ~n" + ..
"float p = coord2.x ; gl_FragColor = vec4(p,0.0,0.0,1.0) ; }"

Rem VERTEX SHADER
void main(void) {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex
gl_TexCoord[0] = gl_MultiTexCoord0 
}
EndRem

Rem PIXEL SHADER
void main(void) {
vec4 coord = gl_TexCoord[0]
vec4 coord2 = coord
int temp = 0
while (temp++ < 512) {
coord2.w = coord.w + coord.y
coord2.y = coord.y + coord.x
}
float p = coord2.x
gl_FragColor = vec4(p,0.0,0.0,1.0)
}
EndRem



AdamStrange(Posted 2016) [#101]
very simple code - congrats :)


dw817(Posted 2016) [#102]
Indeed very simple code, except it's beyond what I understand. :)

Casaber, is the red part of a 3D rectangle ? How does it look when you feed random pixels into it ? And of course, the speed ? Is this faster than your previous glDrawPixels() ?


TomToad(Posted 2016) [#103]
@casaber: trying to follow along with your example. Don't understand this line
"int temp = 0 ; while (temp++ < 512) { coord2.w = coord.w + coord.y ; coord2.y = coord.y + coord.x ; } ~n" + ..

Seems to do nothing. Removed it from the code and the screen renders the same. Is there a reason for that loop to be there?


Casaber(Posted 2016) [#104]
That's right. It does nothing, I mentioned that in the post and If I took that out you would't notice it was C even. So I kept it because of that reason.


Casaber(Posted 2016) [#105]
Hereīs just another general Vertex shader, and a pixelshader with as many instructions as I could fit to see how things looks like inside a shader.

Mostly for my own eyes, Not much time for perfect presentation yet.

It's tough business to debug shaders, so itīs nice to have something to look at though to what is correct syntax.
I skip unfolding this time it's just a bunch of random code I use this while Iīm testing this week It has absolutely no sensible layout. The Vertex shade though, its very sensible. Itīs a general vertex to allow a pixel shader to exist. I use a somewhat different one here.

But the pixelshader i just an emmensive amount of code to show off syntax, it does nothing. (Except it shows bars) nothing moving yet though.
You get things moving by relaying on variables that are not position, but time. This example does not either show time.




Derron(Posted 2016) [#106]
The code above just segfaults on my computer.
The code in #100 segfaults here too.

Both segfault - in release and in debugmode, so it segfaults somewhere, where blitzmax cannot catch it.


bye
Ron


Casaber(Posted 2016) [#107]
Ya it's not stable at all, it could be something else than what I think.
But my thought is; as shaders are limited what they may do and how they do it in what sequence., and this pixelshader does alot of nonsense as a untouched whole.

If it's truly the shade that brings the computer to a segfault, it would not segfault if you exchange it with a simple pixelshader the first post should work.


Derron(Posted 2016) [#108]
It crashes because my screens do not allow fullhd :-)


bye
Ron


Casaber(Posted 2016) [#109]
Ah nice, good that's a relief, I made resolution change easy to do at the top.


Casaber(Posted 2016) [#110]
I edited the last post to sense screensize now. It assumed 1920x1080 before.


TomToad(Posted 2016) [#111]
I think I'm starting to get a hang of this. Little messy, but works. :)



Casaber(Posted 2016) [#112]
Nice I like that, very Amiga like demo. Really nice !!


TomToad(Posted 2016) [#113]
Ok, now I figured out how to get it to work with Max2D commands.



Casaber(Posted 2016) [#114]
Some nice patterns, abstract-red-bloodcells-whirlpools from hell.


'        50 SHADES of Red
'
' A simple introduction To shaders
'

' SET GRAPHICS MODE
Local xres:Int = DesktopWidth(), yres:Int = DesktopHeight() ; GLGraphics xres,yres,32,60,GRAPHICS_BACKBUFFER + GRAPHICS_DEPTHBUFFER ; glewInit ; HideMouse
glMatrixMode GL_PROJECTION ; glLoadIdentity ; glOrtho 0,xres,yres,0,-1,1 ; glMatrixMode GL_MODELVIEW ; glLoadIdentity ; glViewport 0,0,xres,yres ; glPixelZoom 1,-1 ; glRasterPos2i 0,0

' CREATE SHADER
Local VC:String = VERTEX ; PC:String = PIXEL ; PO = glCreateProgramObjectARB() ; VS = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB) ; PS = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB)
Local SC:Byte Ptr = VC.ToCString(),SL = VC.Length ; glShaderSourceARB VS,1,Varptr SC,Varptr SL ; MemFree SC ; glCompileShaderARB VS
SC = PC.ToCString() ; SL = PC.Length ; glShaderSourceARB PS,1,Varptr SC,Varptr SL ; MemFree SC
glCompileShaderARB PS ; glAttachObjectARB PO,VS ; glAttachObjectARB PO,PS ; glDeleteObjectARB VS ; glDeleteObjectARB PS ; glLinkProgramARB PO

' INIT VARIABLES
Local CString:Byte Ptr = "timer".ToCSTring(), TimerObject:Int = glGetUniformLocationARB(PO,CString), timer:Float = 0 ' TIMER
 
' PROGRAM BEGINS
Repeat
glClear GL_COLOR_BUFFER_BIT ; glUseProgramObjectARB PO

' FUN
If MouseDown(1) Then timer = MouseX()/1024.0 ' allow interactivity when mousdown

glUniform1fARB(TimerObject,timer) ; timer :+ 0.05 ; timer = timer Mod 360 ' TIMER
glBegin GL_QUADS ; glTexCoord2f(0,0) ; glVertex2f(0,0) ; glTexCoord2f(1,0) ; glVertex2f(xres/2,0) ; glTexCoord2f(1,1) ; glVertex2f(xres/2,yres) ; glTexCoord2f(0,1) ; glVertex2f(0,yres)
glTexCoord2f(1,0) ; glVertex2f(xres/2,0) ; glTexCoord2f(0,0) ; glVertex2f(xres,0) ; glTexCoord2f(0,1) ; glVertex2f(xres,yres) ; glTexCoord2f(1,1) ; glVertex2f(xres/2,yres) 
glEnd ; glUseProgramObjectARB 0 ' Custom attributes instead, glVertexAttrib2f or VA/VBO glEnableVertexAttribArray/glVertexAttribPointer.
Delay 1 ; Flip 1
Until KeyHit(KEY_ESCAPE)
End

' ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

' SHADERS
Const VERTEX:String = "void main() { gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex ; gl_TexCoord[0] = gl_MultiTexCoord0 ; }"

Const PIXEL:String = ..
"vec2 O = vec2(0.0,1.0) ;        ~n" + ..
"float wrap(float x) {return abs(mod(x,2.0)-1.0) ; }                                                                                    ~n" + ..
"float wave(vec2 p,float angle) {vec2 direction = vec2(cos(angle),sin(angle)) ; return cos(dot(p,direction)) ; }                        ~n" + ..
"float rand (in vec2 uv) {return fract(sin(dot(uv,vec2(12.4124,48.4124)))*48512.41241) ; }                                              ~n" + ..
"float noise (in vec2 uv) {vec2 b = floor(uv) ; return mix(mix(rand(b),rand(b+O.yx),0.5),mix(rand(b+O),rand(b+O.yy),0.5),0.5) ; }       ~n" + ..
"varying vec2 position ; uniform sampler2D tex0 ; uniform vec2 resolution ; uniform float timer ;                                       ~n" + ..
"void main() { vec4 coord = gl_TexCoord[0] ; vec2 uv = coord.xy / resolution.xy ;                                                       ~n" + ..
"vec2 p = (coord.xy - 0.5) * 50.0 ; float brightness = 0.0 ; for (float i = 1.0 ; i <= 11.0 ; i++) {brightness += wave(p,timer/i) ; }   ~n" + ..
"brightness = wrap(brightness) ;  gl_FragColor = vec4(brightness,0.0,0.0,1.0) ; gl_FragColor.a = 1.0 ; }                                ~n"

' ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Rem Unrolled Pixelshader
vec2 O = vec2(0.0,1.0)
float wrap(float x) {return abs(mod(x,2.0)-1.0) ; }
float wave(vec2 p,float angle) {vec2 direction = vec2(cos(angle),sin(angle)) ; return cos(dot(p,direction)) ; }
float rand (in vec2 uv) {return fract(sin(dot(uv,vec2(12.4124,48.4124)))*48512.41241) ; }
float noise (in vec2 uv) {vec2 b = floor(uv) ; return mix(mix(rand(b),rand(b+O.yx),0.5),mix(rand(b+O),rand(b+O.yy),0.5),0.5) ; }

varying vec2 position ; uniform sampler2D tex0 ; uniform vec2 resolution ; uniform float timer 

void main() {
	vec4 coord = gl_TexCoord[0]
	vec2 uv = coord.xy / resolution.xy
	vec2 p = (coord.xy - 0.5) * 50.0
	float brightness = 0.0
	for (float i = 1.0 ; i <= 11.0 ; i++) {
		brightness += wave(p,timer/i)
	}
brightness = wrap(brightness)
gl_FragColor = vec4(brightness,0.0,0.0,1.0)
gl_FragColor.a = 1.0 
}
EndRem



Casaber(Posted 2016) [#115]
TomToad's I Like it !

I couldnīt get the circleshader working it said something about some error I donīt know what that was about.

Got the sudden urge for images now.
Click and hold the mouse to interact with the shaders for some nice effect.




TomToad(Posted 2016) [#116]
@Casaber, what error are you getting? If you run it in debug mode, it should print some error messages in the BlitzMax output tab.

It may be there is an error in the shader code. Apparently, some graphics cards are a little more slack on the GLSL standards and will accept code that others will flag as an error.


Casaber(Posted 2016) [#117]
I got this error, I mostly got a black shader2 but a few times I got noisey pixels, and one rare time I could see the wallpaper of circles (OS garbled with noise). (Same error always though).

PixelShaderObject
ERROR: 0:2: '*' does not operate on 'float' and 'int'
ERROR: 0:2: '*' does not operate on 'float' and 'int'
ERROR: 0:2: '*' does not operate on 'float' and 'int'
ERROR: 0:2: Use of undeclared identifier 'red'
ERROR: 0:2: Use of undeclared identifier 'green'
ERROR: 0:2: Use of undeclared identifier 'blue'


steve_ancell(Posted 2016) [#118]
Rewinding back to post #2:

I just tried this, no flicker whatsoever.


TomToad(Posted 2016) [#119]
Thanks, found the problem. GLSL specs don't allow for operations on different types. So 360.0 * 3 is not allowed on many cards. This version should work.



Derron(Posted 2016) [#120]
@TomToad

Try to follow your mouse cursor while your code is running - I assume you should avoid this when not being sober :-)


bye
Ron


Casaber(Posted 2016) [#121]
Great ! Me too, found it just the minute ago i just couldnīt let it go.
Shaders really want floats everywhere . Missing a . could kill it instantly. Glad that's sorted!


dw817(Posted 2016) [#122]
Morning ! Yes it's coffee time ...

Casaber, that's an astounding bit of code you have there. Question, can you write a routine so you can stuff in a display of any size (512x384 zoomed) or (1024x768 unzoomed) and place pure random pixels in the field ? R G B (0-255) ?


Casaber(Posted 2016) [#123]
Zooming is no problem it handles that, but the pixelaccess I need to try out.
I found a way to even READ pixels under 5ms on a mobile now (normally taking 100ms for a 720 picture). So Iīm encourage by that.

Writing should be possible with good speed later most likely !


Casaber(Posted 2016) [#124]
I forgot to mention what it means

12ms becomes 60hz
24ms is 30hz
100ms is way slow
5msec is really fast


dw817(Posted 2016) [#125]
Casaber, is using this new method, is it the fastest way of putting pixels on the screen ? Benchmark ?


Casaber(Posted 2016) [#126]
Iīm counting on 5 msec as the worst case scenario, which is the same as my PIXELWRITERBUFFER. Itīs a (nice) standard bus constrain today.
Pixelshaders constrain are the GPU bus and memory, the design of all. I have only some rough ideas what to expect. If I keep under 2-5msec it would be great.

GPU's biggest trick up its sleave is to avoid pixel overdraws. When you use GPU's for splatting images this is very accessible but with shaders it's not as easly.
Some of these feataures are hidden in the hardware and some are very visible to the programmer as things like DEPTHBUFFER, STENCIL, those kind of things.
The GPU uses those buffers but they are not filled with rgba values for each pixel in those buffers but a number which gives the idea of "depth".

And you could of course do alot things with this.

This is great for handling 2D overdraws. You know when you draw more than "you really have to", to get a scene going with layers, those kind of thigns.
The GPU accesses those buffers much more quicker than it may access rgba buffers, also you may program many things how the GPU should react on those.

Shaders are not good at using these overdrawing features. That makes it worse than "normal GPU of just splatting images".
This is why VBO works so good. It allows pixeloverawing.

You want a VBO with PBO's I think would be the best soution.
This way you could draw pixles using normal techniques (GAINING THE SPEED PIXELOVERDRAW), and then read/write pixels aswell.

If you use alpha alot, I donīt think pixeloverdraw makes a difference at all.
Scratch all that. But this way would either way give you the best possible scenario Iīm very sure on that so that's my goal.

Sorry for blabbing incoherently, my gf is still on the hospital and Iīm not feeling any good.


I will try to come up with ideas later okay


Casaber(Posted 2016) [#127]
Global xres:Int = 1920 ; yres:Int = 1080 ; Global pixels:Int[xres*yres] ; Global pixels2:Int[xres*yres]
GLGraphics(xres,yres,32,60,GRAPHICS_BACKBUFFER + GRAPHICS_DEPTHBUFFER) ; HideMouse ' Fullscreen 
glViewport(0,0,xres,yres) ;  glLoadIdentity() ; glMatrixMode(GL_PROJECTION) ; glPixelZoom(1,-1) ; glOrtho(0,xres,yres,0,0,1) ; glRasterPos2i(0,0)

' C64 managed 2KB per frame just barely, To be able to do this was "elite" (120 KB / sec) (Triple buffering was pretty much invented here just to get things going)

' 1920 x 1080 32bit is 8MB per frame (0.5G Byte per 12 msec) (This example shows that One read of the screen + One write of the screen is possible under 12msec (60hz).

' A full read (0.5 GByte) and a full write (0.5 GB), makes a 1 Gbyte transfer happens between CPU and GPU per second.

' If you use any other resolution here's the numbers per frame it takes, just to get the feeling when you upsize pixels to something else.
' 1920*1080 takes 8MB, 0.5 GB per sec
' 1280*800 takes 4MB, 0.25GB per sec
' 1280*720 takes 3.5MB, 0.21 GB per sec
' 1024*768 takes 3MB, 0.18 GB per sec
' 800*600 takes 1.8MB, 0.1 GB  per sec
' 640*480 takes 1.2MB, 120 MB per sec
' 320*240 takes 0.3MB, 18 MB per sec

' Main
Repeat

	' Demo a CLS, example how to clear the array (non-optimized)
	For y=0 To yres-1 Step 1 ; For x=0 To xres-1 Step 1 ; pixels[(y*xres+x)] = 0 ; Next ; Next ' stepping is not needed if you only use 1
	
	' Demo a PLOT, example how to draw a pixel x,y,color (non-optimized and non-clipping)
	x=400 ; y = 300 ; c = 65535 ; 	pixels[x + y*xres] = c

        ' Demo
	a = a + 1 ; b = 64 * Sqr(a)*Cos(a) ; 	For y=0 Until yres Step 1 ; For x=0 Until xres Step 1 ; 	c = x + b * b Shr 8 * x+yy ; 	pixels[x + y*xres] = c ; 	Next ; Next
	
	' This reads an array from the GPU, make a dummy read of the entire screen before each frame and it just about manages to fetch an entire HD screen once and write it all once. 
        ' Living on the edge but it's a simple apporach. No slowdown on e.g. 2010 Mac's.
	 glReadPixels 0,0,xres,yres,GL_BGRA,GL_UNSIGNED_BYTE,Varptr(Pixels2[0]) ' Reads into an invisible array as a test.
	
	' This writes the array to the GPU, amazingly this is not the major bottleneck even on weak machines.
         glDrawPixels(xres,yres,GL_BGRA,GL_UNSIGNED_BYTE,Varptr(Pixels[0]))

Delay 1 ; Flip 1

Until MouseDown(2)
End



Casaber(Posted 2016) [#128]
Global xres:Int = 1920 ; yres:Int = 1080 ; Global pixels:Int[xres*yres] ; Global pixels2:Int[xres*yres]
GLGraphics(xres,yres,32,60,GRAPHICS_BACKBUFFER + GRAPHICS_DEPTHBUFFER) ; HideMouse ' Fullscreen 
glViewport(0,0,xres,yres) ;  glLoadIdentity() ; glMatrixMode(GL_PROJECTION) ; glPixelZoom(1,-1) ; glOrtho(0,xres,yres,0,0,1) ; glRasterPos2i(0,0)

' C64 managed 2KB per frame just barely, To be able to do this was "elite" (120 KB / sec) (Triple buffering was pretty much invented here just to get things going)

' 1920 x 1080 32bit is 8MB per frame (0.5G Byte per 12 msec) (This example shows that One read of the screen + One write of the screen is possible under 12msec (60hz).

' A full read (0.5 GByte) and a full write (0.5 GB), makes a 1 Gbyte transfer happens between CPU and GPU per second.

' If you use any other resolution here's the numbers per frame it takes, just to get the feeling when you upsize pixels to something else.
' 1920*1080 takes 8MB, 0.5 GB per sec
' 1280*800 takes 4MB, 0.25GB per sec
' 1280*720 takes 3.5MB, 0.21 GB per sec
' 1024*768 takes 3MB, 0.18 GB per sec
' 800*600 takes 1.8MB, 0.1 GB  per sec
' 640*480 takes 1.2MB, 120 MB per sec
' 320*240 takes 0.3MB, 18 MB per sec

' Main
Repeat

	' Demo a CLS, example how to clear the array (non-optimized)
	For y=0 To yres-1 Step 1 ; For x=0 To xres-1 Step 1 ; pixels[(y*xres+x)] = 0 ; Next ; Next ' stepping is not needed if you only use 1
	
	' Demo a PLOT, example how to draw a pixel x,y,color (non-optimized and non-clipping)
	x=400 ; y = 300 ; c = 65535 ; 	pixels[x + y*xres] = c

        ' Demo
	a = a + 1 ; b = 64 * Sqr(a)*Cos(a) ; 	For y=0 Until yres Step 1 ; For x=0 Until xres Step 1 ; 	c = x + b * b Shr 8 * x+yy ; 	pixels[x + y*xres] = c ; 	Next ; Next
	
	' This reads an array from the GPU, make a dummy read of the entire screen before each frame and it just about manages to fetch an entire HD screen once and write it all once. 
        ' Living on the edge but it's a simple apporach. No slowdown on e.g. 2010 Mac's.
	 glReadPixels 0,0,xres,yres,GL_BGRA,GL_UNSIGNED_BYTE,Varptr(Pixels2[0]) ' Reads into an invisible array as a test.
	
	' This writes the array to the GPU, amazingly this is not the major bottleneck even on weak machines.
         glDrawPixels(xres,yres,GL_BGRA,GL_UNSIGNED_BYTE,Varptr(Pixels[0]))

Delay 1 ; Flip 1

Until MouseDown(2)
End



Casaber(Posted 2016) [#129]
Doing two things now side by side,

Pixelwriter with FBO the other is Shader with FBO

Both takes about 2 screens worth of code, but I'll have to create an API to use everything and makes some examples. I'll promise I'll something.

You could try explain exactly what you need to do and what you need to read I will try see if it's managable to do it. okay?


Bobysait(Posted 2016) [#130]

under 12msec (60hz).



Unless I'm wrong considering what a Hertz is :
60 hz = 60 frames per second
= 16.7 ms per frame

So, what is supposed to be the 12 msec in your code comments ?


Casaber(Posted 2016) [#131]
I use the 12msec for some other uses, andI I also use it for extra overhead. Don't worry about that.


Casaber(Posted 2016) [#132]
It's just an average of the span I uses alot (10-16msec).

I guess I forgot to change it to specific numbers when showing them. Sorry for the confusion.


dw817(Posted 2016) [#133]
Casaber, the code above is pegging my CPU at 100%, do you think you can get it down a bit ?

Rapid speed of pixels, little to zero use of CPU - that's the ticket !


Casaber(Posted 2016) [#134]
Adding PBO to a VBO will take the same amount of time as readingpixels (if readpixels is nicely implemented in the driver) there's also least 4 main variations how to read pixels then a few different techniques using them but they all seem to share the same speed limits (the bus). But I think you got slowdown becuase of bad implementation So I will try find a better one.

In the meantime try changing GL_BGRA into GL_RGBA (this is less common but sometimes used on the GPU, it might help. I donīt think so but there's a chance.

Adding PBO will take away waitime from the CPU (things gets asynchrounsly). So everything will stay the same the speed for the pixels to get there is the same, it's only the CPU's that gets freed up totally.
In this example CPU have to wait at each read or write is finished. But PBO adds no magic speedup, just freeing the up so the R/W will become air for it.

Iīm going got the the lowest common denominator. That's why I want to keep things below 1GB.

I would like precise pixel access above anything else aswell so I will focus on that. VBO with PBO are my best hope so far but I need to work out the specifics that really drives up the speed.
I think that pegging in the CPU just happens to be that I happened to use a "bad" API path. Meaning it's likely that readpixels might be badly I think, and that it could do better.

I just need some motivation to know where to go, there's alot of options how to do everything in a good combination. How to mix features, What do we need?
Do we want to have bufferimages splatted, with alpha rotation and size applied and then be able to read back the pixels they made? You mentioned quads and wanting to warp the software buffers.

How to mix it all the working piece together in a nice way that's usable.

What are the actual practical things we need to be done quickest? The more detailed the better really.



My thoughts about the pixelwriter
I marvel at the fact that you could do 50 reads and 50 writes to a 320x240 screens (worth the same as 2 HD screens) Both are 1GB per second. And API latency for having 100 separate calls is minimal.

With the C64 you had 8KB bitmap and you could not even DREAM about to do more than 2KB per frame. (That's why tiling became so popular, it was 2K.. 25x40 bytes to fill a whole screen, exactly 1000 chars and 1000 bytes for colorinfo - you had your 2K to move in time)

Why I like that? becuase you had to draw everything manually back then, no alpha/blend no stretch rotation. It makes you humble of what you've got today.
Being able to do 50 reads and 50 writes to pixelbuffers of 320x240 buffers silky smooth is not to be thrown upon.

That's is a world in itself, worth exploring.


Casaber(Posted 2016) [#135]
I got painting to VBO and shader working nicely, meaning we can paint onto images/sprites with primitives and other sprites, but adding pixelaccess breaks it abit I need time to do update my
knowledge in the details to match the current common minimum denominmator, which is the sensible goal.

My gf got home from hostpital so I need to take care of her now and that might make the coding suffer abit. And I need to rest up too I guess I'm soo finished right now.

But I've got your mail. And The forum is good too.

We'll keep checking how this will progress with time allright?


dw817(Posted 2016) [#136]
Hi Casaber. You mentioned something about your girlfriend ! Is everything okay, what's happening there ?

Focus on that before anything else. Hope you are doing well. I see my own Doctor Wednesday. Psychiatric. Ah - they check up on me. :) But afterwards visit my sister out in the country on her farm.

So likely I'll be really GONE most of the day tomorrow.

And yes, I'm still working on the Carryall 750k, at this point the interface so it's easy to use as it is fairly complex what goes on inside.

out "[1] Change Encryption KEY, currently ("+key+")"
out "~q"+sdat2$+"~q"
out
out "[2] Get Code From current package"
out
out "[3] Compress & Encrypt File or Folder contents"
out "[4] Recreate Files or Folder From Code"
out
out "[0] END"


Casaber(Posted 2016) [#137]
I could write you a mail , It will just be a hectic time for a while, no worries.

I hope your appoint goes well !!

Really want to know about that CarryAll later aswll, you got me curious.


dw817(Posted 2016) [#138]
Never received mail. That's fine. I wish BlitzMAX had the ability to plot text on the screen where it scrolls when you hit the bottom, like most programming languages.

Anyways, I had to write that and am getting there on the Carryall program.


TomToad(Posted 2016) [#139]
I wish BlitzMAX had the ability to plot text on the screen where it scrolls when you hit the bottom, like most programming languages.

It does. Turn off "Build Gui App" from the Program - Build options menu. You will now have a console window where you can use Print and Input like most Basic's text mode.


dw817(Posted 2016) [#140]
Hi Tom. The problem with that is, it's true text and I tried running one of those applications in final EXE format. It is not the least bit attractive.

No, I have my own page scroller now and am using a 5x7 double-pixel font to display the information and ask questions needed for the 750k Carryall.