Sei sulla pagina 1di 15

Hello this is John from.

I'M ON THE STORY.

We're going to colour a moment to honour that may not sound like much but actually
can enable pixel

access effectively in this window which at the moment is black.

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.

Before we go on to setting individual pixels.

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

a finished project that I created by as I explained in a previous tutorial looking


up tutorials on the

internet relating to sdl and then changing a few things by consulting the API
official API documents

by searching for function names.

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.

But might my knowledge of S.T. alistar is not very in-depth.

I just figured having enough to get this working.

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.

Otherwise just watching them.

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

which we're going to construct later on.

But first I want to get just a basic main function that just illustrates the kind
of basic elements

of what we need here.

And later on I'm going to refactor it and make it more object oriented so that we
don't get into a tangle

when we have more and more code to this.

So in my screen class here I've got an init method and in here we are creating a
thing called a renderer

and a thing called a texture.

So my understanding here is that the renderer is something we use in s the L to


actually draw on the

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

and then telling the renderer to display in the window basically.

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

which will display on the window.

So there's like a chain of three different things here.

Maybe a simpler and better way of doing this.

But this this is a way that definitely works and it seems reasonably efficient.

So this is where I've I've kind of settled on.

But you may find a better way of doing this is possible.

So let's go to screen door H here.

And in screened at age somewhere this is still screened on s.p.

So we need to go down here.

Here's my renderer texture and buffer.

So.

So let's let's create those objects in our in our main file.

First of all Sunny to go to.

Right.

I get here but I've just created made up s.p.

And somewhere before we actually used these I'm going to have to create relevant
objects.

Let's maybe do it here.

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

down here steckel up.

So here we are still create renderer.

Let's type that out.

So s d l on the score create renderer

and what arguments do we need to pass to this.

Well let's take a look.

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.

So your computer screen is going to re refresh a certain number of times a second


like I don't actually

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.

Going from left to right again.

And if you try to draw something to the screen when a render is in progress like
it's halfway down you

see something called shearing.

Where is this Come effect where you see some flickering on the screen and there's a
visible line flickers

somewhere across the screen.

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.

The second one is minus one.

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.

As I said found out by looking at the API document by Googling.

By pulling this function name into Google.

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.

On this score I think its texture text.

Text your pointer.

I quite am having that asterisk next to the actual variables s added.

So a pointer to an S the text to which I'll call texture.

So this is the thing that the renderer is going to render and which work in a write
up pixel information

too.

If we take a look at that.

Then again quite complicated arguments will go through and bit by bit so what s the
L on the score create

texture still on the score.

Create texture.

Spot the semicolon and the brackets in there.

First argument is a renderer.

So let's put that in.

Ran down the second argument.

Here is this can be a number of possible arguments a number of possible constants


depending on how many

bits how many by spaceclaim you want to represent one pixel.

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.

So each pixel actually uses and actually uses 30 bit.

All four bytes.


Three of those bytes rep began to represent the colour information of the pixel red
green and blue and

each red green and blue value can have zero up to 255 different possible values 2 5
five is the maximum

value we can fit in one bite.

If we flip all the bits to one or the other fine here.

AIDS stands for Alpha which is basically a transparency.

We won't be using that.

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

but I'm not going to make use of it in this tutorial.

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

that flag enables us to do that.

So let's put that in.

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

how big scanner be.

That's format that so we got our texture and our renderer.

We also need to remember to de allocate resources allocated to those.

So I've done that in my final program in a method called close.

So here we are using S.T. destroy texture and still destroy renderer.

So let's go ahead and put that in.

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

using that destroyed renderer.

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

texture and passing texture.

Hopefully that should do the trick.

It's probably a good idea to check if these are null.

Let's take a look at the documentation and see if it says anything about returning.

No such a search google for the function name here.

And so it turns null if there was an error and we can call a still get error as
well.

So we could we could check that.

It's probably prudent to do so.

Let's say if renderer is equal to normal.

Then if you don't check in any programs basically to scan a crash if this doesn't
work properly that

say see out could not create Rend

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.

As I said previously it doesn't really matter.

If we could create the window but not the renderer we would probably eny the case.

We should probably call sdl Quit like this

if we if we could create the window.

So by this stage we have created the window so we should probably pop destroy
window in here as well.

Let's put destroy window before we caught STF queer.

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 let's destroy the renderer.

Now this is a lot of repetition of code.

We could refactor this and perhaps I will.

In the final tutorial.

So I don't really like or like in a later tutorial so I don't really like having
multiple calls to the

same functions in here.

We could have something that sort of checks.

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.

So we got our renderer and a textureless.

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

that memory and were going to basically write it to the texture.

So we're going to update the text with that information.

And what I'm going to use is this tie you in thirty 32.

So I'm going to say here new int thirty two pointer.

Now what is he doing.

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.

Could be something else.

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

here we've got four each pixel.

We've got four values red green blue and Alpha.

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

to be in that pixel all the colours of it basically.

So we're going to allocate enough memory for all the pixels on the screen and each
one's going to require

thirty two bets.

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

the screen height.

Because it is just the screen just a rectangle which is screen with pixels wide and
screen height pixels

high.

So that's our buffer.

And we must remember to free this later on as well.

So let's go down here and say Delete.

And we need the array brackets because it's an incinerator we've allocated their
delete buffer.

Okay so that looks good.

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.

But by default on most systems it will raise an exception.

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.

We're not ready gracefully.

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.

We then wouldn't be able to call these functions.

But I'm not going to worry about this for this program.

Ideally we will check for that.

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.

Then probably a lot of programs are going to be crashing anyway.

So this is kind of a justification of why I'm not checking this.

Ideally in a kind of professional program Ideally you'd probably check to see if


that memory could be

successfully allocated although I'd be willing to bet that very many programs that
are on sale do not

check.

But to be perfect we really should.

So I've allocated that I've allocated arend or in a texture and a buffer that we
need to contain all

the information for pixels.

And I've freed all those resources as well down here.

Now what we need to do is we need to update the texture with the information
contained in this buffer

which at the moment it's just garbage.

And I then need to tell the renderer to render.

In other words draw the texture.


So let's look at how we do that.

I really can't remember but I'm going to consult my final program again.

So if we look at the think screen update here.

No.

Yeah.

Here we go.

So we need this stuff.

So the first thing we need is the out of date texture and I'm good.

And eventually I'm going to move this into this Lou.

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.

Let's say s the L on the Scott date.

Texture.

Let's check what we do with that.

So we have the first argument is the texture to pass in our texture.

The second argument is null.

Take a look at what this is in a moment.

Then we pass in a buffer that we actually searched containing the information that
we want to update

the texture with or it will do.

Once we set that up and then we pass the pitch.

The pitch is the number of memory memory allocated to one row of pixels.

So if you think about what that is it's going to be screen width.

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.

I apologize for that.

But anyway I'll carry on.

So if we look at the documentation here.

So we've got the texture is the first argument that we need.


And the next argument is null if we want to update the whole thing and then we've
got the raw pixel

data that we want to update it with.

And finally we've got the pitch which is the number of bytes it says between rows
of pixel data.

So in other words that the number of bytes per row of pixels.

I'm not sure why says between.

But if you want to go from one road to the next.

This is how many bytes you have to add on.

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.

But that's not the case here.

So this seems to work fine so we don't the texture with the pixel information
contained in this buffer.

And the next stage is we clear the renderer.

So let's call it the old score ren renderer clear.

I think it is already clear and passan renderer.

Something wrong.

Maybe it's render clear.

OK.

There we go then we copy the text into the renderer.

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.

And what are these.

I don't know.

Well the rendering the texture obviously the render in the texture.

And then we've got no.

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 finally I think we've got render present.

So we got sdl on the score render present.

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.

Now if if I run nesse the results are going to be a bit random.

Let's try.

Let's try running.

Let's see what happens.

Rupp's that's the wrong that's the wrong thing.

That's my final program Australia so go to project Hill project and we'll run it.

So it's just black.

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.

So the first argument is the buffer.

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

going to be screen where.

Times the screen height number of pixels times size of in bytes view into thirty
two.

So hopefully I've got this right.

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.

So let's let's try that see what we get now.

So we've now we've got a white screen which is what we wanted.

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

most values by going a b c d e and f.

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

final integer that represents the colour of that pixel on screen.

I'll go into that later on.

But that's basically the advantage of it.

We need exactly two digits here to specify one bite.


And if your packing bytes into an int file you then it works out.

That's very easy to see which byte corresponds.

In our case to which colour board will get unstuck later.

So twenty five indexed decimal is f f like outnesses run again chell it still
works.

So that looks that looks really good.

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.

We could split this up into multiple different functions.

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.

Potrebbero piacerti anche