Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
We're going to colour a moment to honour that may not sound like much but actually
can enable pixel
And we're going to just make sure that the things basically working by setting the
window to white.
Here we go.
So we've got a black window at the moment I've just accidentally started three
copies of this and we're
going to enable pixel access here and then just make the whole thing turn white
which is quite easy
to do.
So of course this isn't strictly speaking speaking an sdl to tutorial it's a C++
tutorial on disusing
sdl as an example of the graphics API because we need some kind of API.
And I don't have all the details of the sdl API in my head so for that reason I'm
going to refer to
internet relating to sdl and then changing a few things by consulting the API
official API documents
So I'm going to kind of cannibalize my own code here and copy them bit by bit.
In fact I'll type it out and I'll explain as much as I can as we go along.
I hope you'll forgive me for now actually copying my own code rather than just
speaking from the top
of my head.
I could have memorized this stuff but it would have been a little bit sort of fake
because I certainly
don't know.
Still all that well and by the way I hope that you'll follow along and after each
video implement your
own version of this program either exactly the same or even slightly different.
But that's a really good thing to do to get the most out of these videos.
This this will kind of never sink into your head unfortunately.
So let's let's take a look at the program that I actually finished particle
explosion program which
is done here I've called it sdl test and if we go to my I've got an object class in
here called screening
But first I want to get just a basic main function that just illustrates the kind
of basic elements
And later on I'm going to refactor it and make it more object oriented so that we
don't get into a tangle
So in my screen class here I've got an init method and in here we are creating a
thing called a renderer
window.
We've got a window but we need a rendering to render stuff in other words draw
stuff on it.
And we also need a texture which is ganor is like a bitmap that we can draw
directly to.
So we'll be creating the renderer doing stuff with the texture and then passing the
text to the renderer
Let's take a look at the head of file here because I need the types for the
renderer and the texture.
And we've also have also created here what I've called a buffer.
And what this is is just an area of memory where we're going to get insect
information that's going
to relate to pixels.
And we're going to actually then use that memory to to right to the texture which
will pass to the renderer
But this this is a way that definitely works and it seems reasonably efficient.
So.
Right.
And somewhere before we actually used these I'm going to have to create relevant
objects.
Sinder esta L underscore renderer pointer and let's call that renderer.
And we need to set that equal to the return value of our create renderer function
which is somewhere
So that the first argument is the windowed render is going to render in2.
That's tight that so we've called that just window to pointed to the window.
The next argument is minus one which if we look at the documentation.
Well Lester Dillon is seconds at the moment we've got a syntax error that prevents
the documentation
showing.
Or you could just paste this into Google and the last argument.
I figured out by looking at the API document that's still renderer present V sync
something to coppula.
And what this does is it ensures that a rendering is synchronized with the vertical
refresh of the screen.
know how many that say it's 30 times the second 50 times.
I'm not sure and it refreshes from the top left hand corner.
It goes across the rows and moves downwards so it redraws the screen from the top
left goes right across
to the to the top right and then it does the next row a bit further down the
screen.
And if you try to draw something to the screen when a render is in progress like
it's halfway down you
Where is this Come effect where you see some flickering on the screen and there's a
visible line flickers
Or is unpleased.
We want to we want that not to happen to want to make sure that eye rendering is
synchronized with that
refresh so that we don't try to render to the window when the screens actually
refreshing and at least
on my machine.
Adding this flag here to create renderer synchronize seems to synchronize properly
and it prevents shearing.
If we look at the crate renderer documentation here then we see the first argument
is our window.
Just say that you want to just initialize the first rendering driver available
whatever that is.
Anomaly Sure and but is basically a kind of default option there and the last one.
So that's how renderer created and that's let's go back and sipping creditex to
here.
So now we need s d l S T L.
So this is the thing that the renderer is going to render and which work in a write
up pixel information
too.
Then again quite complicated arguments will go through and bit by bit so what s the
L on the score create
Create texture.
So I'm going to use this sdl pixel former r.g. be a 888 8 which uses one byte for
each pixel So that
means through each pixel we've got we can select one of zero to two hundred fifty
five different shades
of each colour.
each red green and blue value can have zero up to 255 different possible values 2 5
five is the maximum
And I've read lots of reports that doesn't work in sdl and that seemed to be my
experience.
But actually I think that you can set very flags here and there to various
functions to get it working
In any case let's let's take a look at what's next so now we've got aestival Text
to access static.
Now this this has to do with the way they were writing to the texture.
I can't really remember the details of this but basically we want to take a load of
memory containing
values for each pixel then write them directly to the texture every time we go
around this loop and
And finally we've got the screen width and screen height so that it's just coppula
as we've already
got these constants defined in our program appear so we can put those in because
the text needs to known
So here we are using S.T. destroy texture and still destroy renderer.
We destroyed the text first because it's using the renderer So we probably should
destroy that first.
Otherwise we're going to have if we destroy a renderer then we're still going to
have a texture that's
I'm not sure if that matters but it's prudent to get known in the appropriate
order.
Let's say est the old destroying renderer renderer and after that we can do s s d l
destroy texture
Let's take a look at the documentation and see if it says anything about returning.
And so it turns null if there was an error and we can call a still get error as
well.
Then if you don't check in any programs basically to scan a crash if this doesn't
work properly that
endler and let's just return some non-zero integer to signal an error and say if
texture equals null.
Scummer caps lock on here then see out kurd's not create texture.
Mendler.
And then our return some other than you could just return not to.
If we could create the window but not the renderer we would probably eny the case.
So by this stage we have created the window so we should probably pop destroy
window in here as well.
If we are able to create the renderer but not the texture we should probably
destroy at least the the
renderer.
So at this point by this point we've created the renderer but not the texture.
So I don't really like or like in a later tutorial so I don't really like having
multiple calls to the
If any of those are normal and destroys then they are not nor they toron Rather
than repeating all this
stuff.
We'll leave it for a moment because the object for the moment is just to get a
basic program working
even if it's ugly that demonstrates the basic principle and then we can refactoring
and make it more
elegant.
There's another thing that we need now which is we need some sort of area of memory
that can that is
big enough to hold the information for all the pixels on the screen because we're
going to take that
And what I'm going to use is this tie you in thirty 32.
Thirty two.
This is a type declared by the L which on most systems will be equivalent to an int
an int is usually
32 bits but it's possible that on some systems because C++ is not absolutely
standardized that a anent
might not be thirty two bits.
Civil that reason sdl of have defined this tie which is guaranteed to be 32 bits
but it's basically
an int.
We want to allocate enough enough of these for all the pixels on screen because if
you think about it
Each of those is one byte So for every pixel we got four bytes which is 32 bits
four times eight is
thirty two.
So for every pixel we need a incise a 32 bit bitter memory to represent all the
information that's going
So we're going to allocate enough memory for all the pixels on the screen and each
one's going to require
So let's say here are collick buffer buffer just means an area of memory basically
equals new new.
Thirty two.
And the amount of memory that I have to allocate is going to be a screen where off
screen width times
Because it is just the screen just a rectangle which is screen with pixels wide and
screen height pixels
high.
And we need the array brackets because it's an incinerator we've allocated their
delete buffer.
Now you might wonder what happens if memory allocation fails some C++ systems new
will return null at
that point and we can we can actually configure new to make it do that.
We haven't looked at exceptions I'm saving that for my Intermedia C++ course which
is probably coming
next.
But the bottom line is your program will crash possibly with an error message but
it will crash.
But sir hopefully somewhat gracefully if we can't allocate memory at that point.
The trouble is because we're not doing anything with this exception.
But I'm not going to worry about this for this program.
But this is going to succeed unless your computer is incredibly tight on memory If
it's so tight on
memory that we can't allocate in like 32 bits for each pixel on the screen.
successfully allocated although I'd be willing to bet that very many programs that
are on sale do not
check.
So I've allocated that I've allocated arend or in a texture and a buffer that we
need to contain all
Now what we need to do is we need to update the texture with the information
contained in this buffer
I really can't remember but I'm going to consult my final program again.
No.
Yeah.
Here we go.
So the first thing we need is the out of date texture and I'm good.
So they were updating the texture every time this loop occurs.
But for a moment I'm just going to put it above this loop.
Texture.
Then we pass in a buffer that we actually searched containing the information that
we want to update
The pitch is the number of memory memory allocated to one row of pixels.
That's the number of pixels multiplied by size of you in 32 which is four bites.
Well we could just passin screen with times for someone seems to be soaring
something in the background.
And finally we've got the pitch which is the number of bytes it says between rows
of pixel data.
It's possible if we'd allocated some really strange size for the window that we
might have extra bytes
at the end of a row of pixels that aren't actually used for rendering.
And then maybe the picks are will be different to the number of pixels in a row.
So this seems to work fine so we don't the texture with the pixel information
contained in this buffer.
Something wrong.
OK.
So let's do that.
So sdl on the score ran rend copy first argument is the render then the texture
then no.
No and no.
I don't know.
Well the rendering the texture obviously the render in the texture.
And that's the sort the first Noel is specified that we want to use the entire
texture.
And the second all is to specify that we want to use the entire renderer.
And this is basically it's just actually doing the renderer it's presenting rander
at the window.
It's actually rendering it so were copying the pixels to a buffer then passing the
buffer to the renderer
after after clearing it and then were presenting the resource to render on the
screen.
Let's try.
That's my final program Australia so go to project Hill project and we'll run it.
It wouldn't have.
It would not have surprised me if I had seen a load of garbage in there because we
allocate this memory
is going to contain just what whatever happens to be in that memory that was
allocated.
And it seems that for me this time at least there's nothing in that memory so it's
just blank.
But the reason it could be something in that memory what we want to do now is we
want to write something
into write some pixel information into this buffer so that we can see something
happening on the screen.
I'm going to use that very very very useful function which everyone should know
about called memes set
members that allows you to set a block of memory with a particular value.
The second argument is the value that we're going to write into every bye to that
memory.
So let's put two five five because we want to try to get every by sakal to its
maximum value ragweed
blue an alpha and that should give us a wide colour.
And then if I remember rightly we need the number of bytes we want to set which is
going to be it's
Times the screen height number of pixels times size of in bytes view into thirty
two.
We're going to write the maximum value that we can put in a by in every byte in all
of these bytes.
The Mam'selle is a very quick function which one of the reasons it's very very
useful.
Now another way of representing 2 5 5 which are going to be using this tutorial
rather than 1 2 5 5
probably for the most part is we can write this in hexadecimal so hexadecimal is
it's another number
system like binary like the familiar decimal where we use each digit can have one
of 16 possible values
starting at nought and going up through one two three four five six seven eight
nine and then we supplement
So in hexadecimal 2 5 5 0 x f f.
The reason this is particularly useful by the way o is is to prefix in C++ to say
this is a hexadecimal
value and the reason this is really useful is because if we well see later on and
if we want to pack
multiple bytes into one into one single you Win32 value 32 the end then we end up
with just two digits
per byte in the hexadecimal system which means it is easy to see which byte
represents what's in the
So twenty five indexed decimal is f f like outnesses run again chell it still
works.
Probably in the next tutorial what will do is well that there are several things to
do next.
But basically we need to deal with pixel access next and were probably going to do
that in the next
tutorial.
We also need to think about the colours how we're going to devise what colours to
draw on the screen
and I might do that in this basic program as well but if you look at this program
now is this is a big
main function.
And we could carry on like adding stuff to this but by the end it would be really
huge and not easy
to understand.
That's kind of C style programming but what would guno be doing is letting this
offensive classes begin
to continue working with this for the moment because before I won a refactoring to
classis I wanted
to make sure we got a little demo program and it is still quite little rarely.
That just demonstrates all the basic things that we need to do and then we can
proceed forwards in confidence
so I will probably take a look at pixel access and possibly colours in the next
tutorial centre then
encoding.