The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
Linux port tutorial for "Handmade Hero" using SDL
David Gow
Guest

Hey all,

I've been writing a tutorial on how to port Casey Muratori's "Handmade
Hero" game project to Linux, and am using SDL quite heavily. "Handmade
Hero" is a set of videos detailing, line-by-line, the development of a
game in C: http://handmadehero.org/

The Linux tutorial, which uses SDL, is located here:
http://davidgow.net/handmadepenguin/

Hopefully people who are learning to use SDL might find a few bits and
pieces there useful.

Cheers,
— David



_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Alex


Joined: 19 Sep 2014
Posts: 35
In my opinion your lessons is not good for SDL2. You are going not "SDL2 way" Smile.
Quote:
Chapter 3: Allocating a Backbuffer

When you allocating this buffer, you trying to use software rendering instead of hardware accelerated. (You can use SDL_Surface as software pixel buffer if you really need this.)
Quote:
We're going to be using SDL_TEXTUREACCESS_STREAMING, because we'll be chainging the texture every frame.

This is not very good idea to update texture with SDL_UpdateTexture every frame (this is not very fast function). Better to load your images (all or some of them) to a texture(s) one time at game start and then use SDL_RenderCopy to copy images from your "image-storage" texture to work area when you need to change something. You can use texture to texture rendering, this is much faster then SDL_UpdateTexture.
If you want to draw gradient filled rectangles like in your example (Chapter 4), you can draw only one filled rectangle, then put it to a texture and then SDL_RenderCopy this rectangle from this texture as many times as you need.

And instead of
Quote:
(from Chapter 4)
int BytesPerPixel = 4;
you can use something like:
Code:
#define BYTES_PER_PIXEL 4
(macro constant) or put this variable in a struct.
If you using SDL_Surface as software pixel buffer, then all this vars already in this struct. Bytes per pixel: SDL_Surface->format->BytesPerPixel, bits per pixel: SDL_Surface->format->BitsPerPixel and pitch: SDL_Surface->pitch (width and height in pixels too).

If you really need software pixel buffer, I suggest to use SDL_Surface. This is better and easier than using your own pixel buffer.
If you want hardware acceleration benefits from SDL2, then use SDL_RenderCopy from a texture to render each frame and occasionally SDL_UpdateTexture (only if you really need it).
MrPhil


Joined: 23 Feb 2014
Posts: 3
Location: Reno, NV
Worth noting that Handmade Hero is currently showing software render on purpose as a learning exercise. The plan is to do hardware acceleration later after software rendering is done.
Alex


Joined: 19 Sep 2014
Posts: 35
MrPhil wrote:
Worth noting that Handmade Hero is currently showing software render on purpose as a learning exercise. The plan is to do hardware acceleration later after software rendering is done.

I don't speak about Casey Muratori's "Handmade Hero" - it is not positioned as SDL tutorial. May be this tutorial is made for learning software rendering as you said.

I speak about this tutorial (David Gow's). This is two different tutorials and this one is based on previous. But this one is positioned as SDL tutorial from the start. Because of this reason I post here my opinion about this tutorial.
I think developers, who started to learn SDL, should not reinvent the wheel. In my opinion good teacher must teach them best practices in SDL development. This is looks strange when someone teach me bad practices, but he plan to teach me good later.
May be better to write in SDL tutorial: what is SDL_Surface, what fields in this srtuct, and how we can use this fields including pixel buffer. And explain why SDL_UpdateTexture is not best function to use every frame. And if we using software rendering (for learning or other reason), we should use SDL functions and structures for software rendering (not only for hardware accelerated).
Imagine that someone read this tutorial and think: "this is best practices in SDL" or "this is only way to do this tasks in SDL". May be this developer start to develop with SDL using wrong practices.
If author want to teach SDL development, he must use "SDL way" (all SDL functions, best rendering practices etc). If he don't teach SDL, why his tutorial looks like this is SDL tutorial?
All of this is my own opinion.

In all cases (even if I am wrong), I don't understand why author don't use SDL_Surface for software rendering (if he teach SDL development).
Linux port tutorial for "Handmade Hero" using SDL
Jared Maddox
Guest

Quote:
Date: Mon, 24 Nov 2014 18:02:22 +0000
From: "Alex"
To:
Subject: Re: [SDL] Linux port tutorial for "Handmade Hero" using SDL
Message-ID:
Content-Type: text/plain; charset="iso-8859-1"

In my opinion your lessons is not good for SDL2. You are going not
"SDL2 way" Smile.

Quote:
Chapter 3: Allocating a Backbuffer

When you allocating this buffer, you trying to use software
rendering instead of hardware accelerated. (You can use SDL_Surface
as software pixel buffer if you really need this.)


If you go back and check, then you'll find that all that he's doing is
explaining how to translate a base-layer from SOMEONE ELSE'S tutorial
so that it works with SDL. Further, while we can't know what
capabilities will be required since the tutorials are very early into
their development (it's expected that the tutorials will likely
require somewhere in the vicinity of a year AT MINIMUM), we DO know
what the tutorials are using as their base layer: a backbuffer, in
main-memory, which will be used to implement a CUSTOM software
renderer.

Using software rendering is therefor EXACTLY what should be done.


Quote:
Quote:
We're going to be using SDL_TEXTUREACCESS_STREAMING, because we'll
be chainging the texture every frame.

This is not very good idea to update texture with SDL_UpdateTexture
every frame (this is not very fast function). Better to load your
images (all or some of them) to a texture(s) one time at game start
and then use SDL_RenderCopy to copy images from your
"image-storage" texture to work area when you need to change
something. You can use texture to texture rendering, this is much
faster then SDL_UpdateTexture.

The game is liable to use pixel-to-pixel rendering, including any
number of mixtures of bitwise ANDs, IORs, XORs, and comparisons.
Readeing to and from main memory is highly prefered over reading and
writing over the peripheral buses.

Updating a single texture once per frame is NOT a realistic
performance concern for any half-way sanely sized texture. Updating
textures starts becoming insane on the basis of the combination of the
AMOUNT of data moved and HOW OFTEN you move it.


Quote:
If you want to draw gradient filled rectangles like in your example
(Chapter 4), you can draw only one filled rectangle, then put it to
a texture and then SDL_RenderCopy this rectangle from this texture
as many times as you need.


Actually the SDL rectangle rendering functions might be faster, but
that's just some VERY EARLY stuff so it doesn't even count for
determining the correct way to do things.


Quote:
And instead of
Quote:
(from Chapter 4)
int BytesPerPixel = 4;
you can use something like:
Code:
#define BYTES_PER_PIXEL 4


No, don't do this. This is not some retro version of C, if you want it
to be constant then use a const qualifier on a variable (even if that
can be cast away).


Quote:
(macro constant) or put this variable in a struct.

Why would you put it in a struct? To avoid globals? Global variables
don't steal your fingernails and toenails while you sleep to build
ships for Loki to speed the onset of Ragnarok, so you shouldn't act as
if they're boogiemen. They aren't ideal, no, but a global stuct IS a
global variable.

Besides, the stuff that makes sense being packaged up gets packaged up
later. You should REALLY be watching the primary tutorials if you want
to critique this stuff.


Quote:
If you using SDL_Surface as software pixel buffer, then all this
vars already in this struct. Bytes per pixel:
SDL_Surface->format->BytesPerPixel,
bits per pixel:
SDL_Surface->format->BitsPerPixel
and pitch:
SDL_Surface->pitch (width and height in pixels too).


This is a small glue layer for someone else's tutorials, based on the
glue layer that THEY are doing, but done in SDL2 instead of Win32.
Doing it your way might aid in understanding SDL2, but it would ALSO
add unjustified incompatibilities to the glue layers, while ALSO
increasing the likelyhood of typos.


Quote:
If you really need software pixel buffer, I suggest to use
SDL_Surface. This is better and easier than using your own pixel
buffer.

This I probably WOULD do, particularly since you CAN do an update from
one if you're willing to dig in to it.


Quote:
If you want hardware acceleration benefits from SDL2, then use
SDL_RenderCopy from a texture to render each frame and
occasionally SDL_UpdateTexture (only if you really need it).


The tutorial writer DOESN'T want hardware acceleration. The intent of
the original tutorials is PRECISELY to pass along the tips and tricks
of old-aschool software renderers, so hardware rendering would get in
the way.
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
MrPhil


Joined: 23 Feb 2014
Posts: 3
Location: Reno, NV
Thanks Jared!
Linux port tutorial for "Handmade Hero" using SDL
David Gow
Guest

Hi all,
Quote:
I speak about this tutorial <http://davidgow.net/handmadepenguin/>
(David Gow's). This is two different tutorials and this one is based
on previous. But this one is positioned as SDL tutorial from the
start. Because of this reason I post here my opinion about this tutorial.
Alex, I think you make really good points. I have tried (clearly not
entirely successfully) not to position this as an SDL tutorial, but
rather as a tutorial, which happens to use SDL, for porting the Handmade
Hero code. I'm trying to keep the code as close to the original as
possible, so that people following Casey's much more detailed tutorials
don't have to change things unnecessarily.

Quote:
Quote:
We're going to be using SDL_TEXTUREACCESS_STREAMING, because we'll be
chainging the texture every frame.


This is not very good idea to update texture with SDL_UpdateTexture
every frame (this is not very fast function).
As Jared said, this is not really an issue here, for two reasons:
firstly, the original tutorial is not very worried about performance at
this point (using the Win32 GDI's StretchDIBits is not exactly the
fastest function, either); and secondly, this function is more than fast
enough given that's we're uploading a single, screen-sized texture. I've
shipped a few games using this method (albeit in OpenGL, rather than the
SDL rendering API), and it was recommended in the SDL Wiki's Migration
Guide.

Quote:
May be better to write in SDL tutorial: what is SDL_Surface, what
fields in this srtuct, and how we can use this fields including pixel
buffer. And explain why SDL_UpdateTexture is not best function to use
every frame. And if we using software rendering (for learning or other
reason), we should use SDL functions and structures for software
rendering (not only for hardware accelerated).
Imagine that someone read this tutorial and think: "this is best
practices in SDL" or "this is only way to do this tasks in SDL". May
be this developer start to develop with SDL using wrong practices.
I've tried to point people towards the documentation for more
"idiomatic" ways to do things, and have just updated Chapter 5 to
mention SDL_Surface as an option for those who are trying to write a
game in SDL, rather than porting this existing one. As I'm writing these
mostly during the hour-long Handmade Hero streams, there isn't time to
go into these things in detail myself, but I've had several people email
me to tell me that they have looked up and used SDL functions and
features that I've simply mentioned in passing. Again, clearly I need to
make it more obvious that this isn't intended to be an "SDL Tutorial".

Thanks very much for reading the tutorial. As much as I've been trying
to rebut all of your comments, they are very valuable, and will
certainly affect how I continue to write it.

Thanks, too, to Jared for your detailed response!

Cheers,
— David
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Alex


Joined: 19 Sep 2014
Posts: 35
Ok, ok, everyone fight against me Smile
I have not wish and time to make big discussion like this. I just post my own opinion about this tutorial.
But I feel I must answer to some posts here.
To Jared Maddox:
Quote:
The game is liable to use pixel-to-pixel rendering, including any number of mixtures of bitwise ANDs, IORs, XORs, and comparisons.

I agree, but you can use SDL_Surface: it contain memory buffer. You can use this buffer any way you like, including work with each pixel (pixel-to-pixel rendering) and bitwise operations.
Quote:
Readeing to and from main memory is highly prefered over reading and writing over the peripheral buses.

And about peripheral buses. Every time you call SDL_UpdateTexture, you use peripheral buses. Many of other SDL functions use peripheral buses too. And if you use OpenGL functions you use peripheral buses.
No way to output graphics to screen without using peripheral buses. You can make some rendering in main RAM, but you always use buses after this. And if you use hardware acceleration, which is much faster then rendering in RAM, when you use GPU and video memory to rendering, then you always use buses.
Quote:
Quote:
...
#define BYTES_PER_PIXEL 4

No, don't do this. This is not some retro version of C, if you want it to be constant then use a const qualifier on a variable (even if that can be cast away).

May be I use old-style code sometime (I think, I'm not), but show me please where in new C standard (ISO C99 for example) #define macro is prohibited? I try to use mostly C99 standard in my code. I use both #define macro constants and const qualifier, when I think this is better.
I can use "const int BytesPerPixel = 4;", or with C99 types like "const int_fast8_t BytesPerPixel = 4;", or with SDL types like "const Uint8 BytesPerPixel = 4;" (in SDL_Surface Uint8 type used for bytes per pixel and bits per pixel), and I can use "#define BYTES_PER_PIXEL 4". And I can use enum's to make a set of constants.
I learning programming on a source code of best (professional made) libraries (including, but not only, SDL Smile ). Look to SDL source code: you can see many #define's in this code. This practice is not invented by me, I try to use best practices, which I learned reading professional source code.
Quote:
Why would you put it in a struct? To avoid globals?
..... (stupid words are removed)
They aren't ideal, no, but a global stuct IS a global variable.

Yes, I know this. I know we can't live without global vars. But this is common practice to make a struct with fields related to some "object". Global struct is better than tons of global vars, IMO.
As I said above, I read sources of some professional software (many thanks to free software), and as I can see in most libraries (may be in all) this is common practice to use global structures instead of separate vars. As I can see in this tutorial, author in first chapter, started to use C++ (not a C), then he can make a class with all fields and methods what he need. I use C for developing and I use structures instead of classes and functions instead of methods.
Look again to SDL code: all objects are structures. There are a lot of structures. But imagine all fields of this structs as a separate vars, then SDL goes to be very hard to use (may be impossible to use) library.
Quote:
You should REALLY be watching the primary tutorials if you want to critique this stuff.

Hm, strange logic. Why should I watch primary tutorial? May be primary tutorial is very good, may be I watch it later, but I think I can start to read this tutorial even if I never watch original before. And I can write my opinion about this text what I reading.

To David Gow:

I have nothing against your tutorial, but I post here my opinion about how to make this tutorial better. This is my own opinion and as I see no one share my opinion Sad.

I think you can use SDL_CreateRGBSurface instead of malloc, but you can write about both ways. First way more SDL oriented and easy to use, second (malloc'ed buffer) you can use too: this is absolutely correct way. You can show both ways in your tutorial, if you want to show not only SDL oriented ways.

I think original tutorial is good, but you don't need to keep your tutorial as close to the original as possible. You can follow the original, but add extra information above original. Show to your readers common SDL practices, which can replace that practices, used in original. You can show both ways: "SDL way" and "original-tutorial way". Make your readers think in correct directions, when they develop using SDL or even without SDL.

Sometime I "reinvent a wheel" too, to better learn something, but this is not common practice in developing.

One more example: look to SDL-Image library source code. The IMG_LoadTexture function (which load image from file to texture) use SDL_Surface as a buffer in the middle of IMG_Load (load from file function) and SDL_Texture. At first step it load an image from file to a surface with IMG_Load, next it use SDL_CreateTextureFromSurface to load image data to texture, after this it free surface (we don't need this surface anymore) and finally it returns a texture with image data.
No one said: this is only way to do this - we can make all this in another way, but this way used in a library, this way is more "SDL way".

PS: I have ported to SDL2 my own image file format. My function create a SDL_Surface with buffer size I need, then my code process image file and load pixel data immediate to surface pixel buffer (like IMG_Load). Next I can continue using this surface or use SDL_CreateTextureFromSurface to put this data to a texture. I can use malloc'ed buffer instead of surface and load data to texture with SDL_UpdateTexture, but I use surface because I need some fields from surface struct. Using surface free me from creating my own struct and creating malloc'ed buffer. For me surface is "all in one" solution, ready to use. Only one call to SDL_CreateRGBSurface function give me a struct with all fields I need and allocated pixel buffer. And I can use this surface later in my code if I need.

Sorry for very long post Smile And sorry if I made some mistakes in this text (English is not my native language).
MrPhil


Joined: 23 Feb 2014
Posts: 3
Location: Reno, NV
Quote:
Hm, strange logic. Why should I watch primary tutorial? May be primary tutorial is very good, may be I watch it later, but I think I can start to read this tutorial even if I never watch original before. And I can write my opinion about this text what I reading.


It's because you are missing the intended spirit of Handmade Hero and a lot of your suggestions run counter to it. The primary goals is not to be a tutorial on modern game development or SDL2 practices but to show the "old school" way of doing things before graphics cards and SDL2.
Linux port tutorial for "Handmade Hero" using SDL
Jared Maddox
Guest

Quote:
Date: Tue, 25 Nov 2014 18:02:15 +0000
From: "Alex"
To:
Subject: Re: [SDL] Linux port tutorial for "Handmade Hero" using SDL
Message-ID:
Content-Type: text/plain; charset="iso-8859-1"

Ok, ok, everyone fight against me Smile
I have not wish and time to make big discussion like this. I just post my own opinion about this tutorial.
But I feel I must answer to some posts here.
To Jared Maddox:

Quote:
The game is liable to use pixel-to-pixel rendering, including any number of mixtures of bitwise ANDs, IORs, XORs, and comparisons.

I agree, but you can use SDL_Surface: it contain memory buffer. You can use
this buffer any way you like, including work with each pixel (pixel-to-pixel
rendering) and bitwise operations.


And on the preferability of SDL_Surface I did agree last time... but
on further review and consideration I realized that allocating raw
memory probably DID resemble more strongly the practice employed in
the primary tutorial series.

Regardless, were I writing a renderer myself I certainly would use a
SDL_Surface.


Quote:
Quote:
Readeing to and from main memory is highly prefered over reading and writing over the peripheral buses.

And about peripheral buses. Every time you call SDL_UpdateTexture, you use
peripheral buses. Many of other SDL functions use peripheral buses too. And
if you use OpenGL functions you use peripheral buses.
No way to output graphics to screen without using peripheral buses. You can
make some rendering in main RAM, but you always use buses after this. And if
you use hardware acceleration, which is much faster then rendering in RAM,
when you use GPU and video memory to rendering, then you always use buses.


I suppose I should give a better explanation.

The operations that are likely to be performed are basically "anything
that you can do in C". If you have render-to-texture support then this
can be done in shaders, but doing that is a rather large leap,
particularly since you have to translate between languages. You can
get around that by doing reads and writes across the peripheral bus,
but if you make very many of those then you rapidly approach the point
where you do MORE peripheral bus transactions than if you had simply
kept everything in memory in the first place. This is so much the case
that the standard SDL2 advise is that if you'll be doing frequent
modifications of a texture then instead of copying it from the GPU
when you want to modify it, you should keep a copy in memory at all
times, and only update it from the GPU copy if the GPU copy might have
been modified, AND you need to modify it yourself.

Some peripheral bus transactions can't be avoided with graphics, but
by reducing the number that you use you can reduce your chances of
negatively affecting OTHER peripheral bus transactions, such as those
that the GPU driver might be performing in the background to move a
texture from memory/disk back to the GPU (I don't know that it's
common right now, but it's very possible for them to do). At the same
time you reduce the chances of exceeding the peripheral bus's
bandwidth, and simplify the code required.

Conclusion? If you're doing this sort of rendering then you should
start by keeping a copy of the texture in memory and just working with
that.


Quote:
Quote:
Quote:
...
#define BYTES_PER_PIXEL 4


No, don't do this. This is not some retro version of C, if you want it to be constant then use a const qualifier on a variable (even if that can be cast away).


May be I use old-style code sometime (I think, I'm not),

You are using old-style code in this case. I don't think it's to the
level of having a third argument in main(), though.


Quote:
but show me please where in new C standard (ISO C99 for example)
#define macro is prohibited?

It's not PROHIBITED, otherwise you would have had an error during
compilation at some point or another. Defines are done by a system
that at the least is logically distinct from the actual compiler, and
in some cases is a seperate program. The compiler I commonly use (a
GCC branch) will pass info about defines from the preprocessor on to
the compiler, which is useful for debugging, but it's still NOT a best
practice: best practice converts THESE sorts of defines into const
variables instead.


Quote:
I use both #define macro constants and const qualifier, when I think this is better.

I try to restrain my use of define & friends to things that simply
make the most sense in the preprocessor (this class of things is
mostly include guards, code generators, and some feature/platform
detection). I personally consider the preprocessor to be weaker than
it should be (I'd like to see count-down loops, a for-each derivative
with some inspiration from C++11 variadic templates, and a define
syntax modelled on #if/#endif, which would be useful for e.g.
automatically generating switch statements and array contents in
conjunction with each other), but I still wouldn't use defines to
replace cases where const variables can be successfully used instead
(note that I might use them to INITIALIZE those consts, especially if
I wanted that to be compile-time configurable, but I wouldn't use it
as a replacement for them).


Quote:
I can use "const int BytesPerPixel = 4;", or with C99 types like
"const int_fast8_t BytesPerPixel = 4;", or with SDL types like
"const Uint8 BytesPerPixel = 4;" (in SDL_Surface Uint8 type used for bytes
per pixel and bits per pixel), and I can use "#define BYTES_PER_PIXEL 4". And
I can use enum's to make a set of constants.

The only one I definitively advise against is using the define to
REPLACE any of the others. The first two are conceptually the ideal
cases if you just want A value instead of SEVERAL POSSIBLE values (in
which case the enum is the way to go), but for historical reasons the
third case makes sense as well.


Quote:
I learning programming on a source code of best (professional made) libraries
(including, but not only, SDL Smile ). Look to SDL source code: you can see many
#define's in this code. This practice is not invented by me, I try to use
best practices, which I learned reading professional source code.


Ironically enough, those very same libraries will often contain the
sort of non-recomended practices that you're speaking against here!
Honestly, "professional" often isn't the same as "clean", and "clean"
seems to be what you're looking for. What I would actually recommend
you seek out is "professional": just not the define thing, we have
better practices than that now (it dates from a time when C didn't
have the const qualifier).


Quote:
Quote:
Why would you put it in a struct? To avoid globals?
..... (stupid words are removed)
They aren't ideal, no, but a global stuct IS a global variable.

Yes, I know this. I know we can't live without global vars. But this is
common practice to make a struct with fields related to some "object". Global
struct is better than tons of global vars, IMO.

It's too early into the codebase for tons of global vars to be an
issue. Also, where you REALLY want to use a global struct instead of a
global var is where you either have some logically distinct GROUPS of
variables that you might want to have multiple sets of at a later
point in time, so that you can simply make another instance of those
variables then. The author of the original tutorials basically goes
into this in one of the videos (maybe video 4? I forget).

Regardles, I'm going to give you a piece of advice that the original
Unix developers apparently followed: "If you do it more than once,
consider writing a script for it". For the C/C++ case, that becomes
"If you do it more than once, consider writing a struct, function, or
class for it". Globals are globals, packaging them into structs when
you'll neither have several instances or more understandable names is
productively identical to slapping a coat of paint onto a car. You
haven't actually changed anything, you've just told yourself that you
have.


Quote:
As I said above, I read sources of some professional software (many thanks to
free software), and as I can see in most libraries (may be in all) this is
common practice to use global structures instead of separate vars. As I can
see in this tutorial, author in first chapter, started to use C++ (not a C),
then he can make a class with all fields and methods what he need. I use C
for developing and I use structures instead of classes and functions instead
of methods.

Some of them will be genuinely designed as objects: these are the ones
that you should look to duplicating. Others will be designed as
namespaces: this can be done, but if you can't concretely point to WHY
you're doing it that way then I'd recommend AGAINST it, as it's
usually a symptom of an anti-pattern (specifically, a symptom of an
automatic knee-jerk reaction against globals: I believe this specific
one came from a mixture of poor understanding of object-orientation,
and experience with code bases that mostly or entirely used globals,
sometimes due to the language involved lacking name scoping: even the
goto statement has it's exceedingly, astonishingly rare, sensible
use-cases).


Quote:
Look again to SDL code: all objects are structures. There are a lot of
structures. But imagine all fields of this structs as a separate vars, then
SDL goes to be very hard to use (may be impossible to use) library.


It's not actually THAT hard to use (you replace pointers to objects
with indexes into arrays: annoying, but actually practical), though it
IS ill-advised if the variables really do have sufficient relation to
deserve being an "object" (whatever you have to do in your language to
actually implement it). The PARTICULAR problem in this case is that
the changes that you called for in the code would have taken it
further away from the tutorials. WELL DESIGNED implementation of your
suggestion in a codebase that had already gone through all of the
tutorials (including the many that haven't been done yet) would be
good (unless you stuck with the advise to stick everything in a global
struct: there's just no good reason to universally do that), but doing
it in this case would just make the tutorial series more confusing.


Quote:
Quote:
You should REALLY be watching the primary tutorials if you want to critique this stuff.

Hm, strange logic. Why should I watch primary tutorial? May be primary
tutorial is very good, may be I watch it later, but I think I can start to
read this tutorial even if I never watch original before. And I can write my
opinion about this text what I reading.


The tutorials that you are critiquing are themselves a commentary on
the ORIGINAL tutorials. Thus, to properly understand what THESE
tutorials are trying to say you have to consider them in conjunction
with the original tutorials, since THESE tutorials were never MEANT to
be considered by themselves. You can certainly write your opinion of
these tutorials in isolation, but the resulting critique will be
mostly invalid due to the inherent disconnect. This is simply the way
that things go within the context of inter-connected systems:
understanding a part is NOT often enough to understand whether the
part is well-designed.


Quote:
To David Gow:

Quote:
PS: I have ported to SDL2 my own image file format. My function create a
SDL_Surface with buffer size I need, then my code process image file and load
pixel data immediate to surface pixel buffer (like IMG_Load). Next I can
continue using this surface or use SDL_CreateTextureFromSurface to put this
data to a texture. I can use malloc'ed buffer instead of surface and load
data to texture with SDL_UpdateTexture, but I use surface because I need some
fields from surface struct. Using surface free me from creating my own struct
and creating malloc'ed buffer. For me surface is "all in one" solution, ready
to use. Only one call to SDL_CreateRGBSurface function give me a struct with
all fields I need and allocated pixel buffer. And I can use this surface
later in my code if I need.

This is the only part of this section of your post the I'll comment
on. If I was designing an image format library I would probably base
the interface on SDL_Surface as well (and if I couldn't, then I'd
probably try to make a derivative of SDL_Surface that I COULD base it
on), but I wouldn't incorporate this directly into the "core" API.
Instead I would have the functions in question take pointers to the
appropriate variables, and provide a seperate file that provided
standardized wrapper functions that DID directly use SDL_Surface. The
reason is simple: I have found that often you will want to use some
particular library, but it's designed for another library that for
some reason you want to avoid (example: you might be writing a plug-in
for a program that uses something else), so you have to go pouring
through the source code of the library (that you know from previous
experience works perfectly fine), just for the sake of making minor
modifications.

It's basically to make it EASIER to not reinvent the wheel. I mention
this because you seem to want your code to be inherently good, so I
think you'll find the idea occasionally useful.
_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Alex


Joined: 19 Sep 2014
Posts: 35
I have posted before that I don't want (and have not possibilities) to make big discussion in this topic. This discussion is going to be offtopic. Sorry, Jared, no more answers.
Just my last words about #define: ok, as you said the SDL library developers using bad practices in development, then lets look to other libs, for example libc, zlib etc etc. Or look to linux kernel source (of course kernel developers is much better programmers than me Smile ). Everywhere you can find macro constants. Is all of this software used bad practices (even kernel)? I don't mean you must use macro const everywhere, I mean this constants is not evil and not a problem, and not a source of errors if you correctly use it. Additionally the C99 standard allow me to use all types of constants (and I use it). If I make a function call like: "myfunction(MY_CONST);" or "myfunction(4);" this two calls absolutely equal (if MY_CONST is 4). Using macro constants is equal to using numeric constants (or other types, if you need). And every time you call something like: "SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO);", you use macro constants SDL_INIT_VIDEO and SDL_INIT_AUDIO.
I must stop myself because I can't long discuss about this.

And return back to the topic:
If you really want to use clean old-style software rendering or you want to make your own software renderer, then stop using SDL_Texture and SDL_Renderer (this technologies is not a software rendering). Do your software rendering clean, like in this example. Make your own software renderer write to the window without a texture in the middle.