So, it's only 9 months past when I initially released it, but I'm finally
posting it to my projects
page and writing this perfunctory blog post about it.
In a nutshell, it's a portable, single header library, written in clean-C
(ie C++ safe), implementing OpenGL 3.x ish. In other words, it runs
entirely on the CPU and its only dependency is C99, though all the
examples and demos use SDL2.
You can read more about it and look at the examples here.
A few days ago I added created 4 new repls of 4 of my C projects. I added repls
These join the one I had for my Goodreads SQLite database. So you can now try
all of these out in the browser here
I recently finished some relatively major changes and improvements to CVector.
Since the most recent changes involved actual changes to the API, both adding new functions and modifing a few existing ones,
I've bumped the version up to 4.0.
Since I've never done an update post like this, and you can look at the main project page and documentation
etc. for all the details I'll just sum up some changes from about the last year (since about 3.1.0 give or take):
- Changing elem_init to return an int to indicate failure/success (and adding that checking where it's called)
- Renaming copy functions to match type-as-suffix convention
- Adding a copyc function that does initialization first, ie copy constructor
- Adding a CVEC_STRDUP macro wrapper which defaults to internal cvec_strdup if user doesn't set it
- Adding "move" function varieties (m suffix) for non-POD vectors that do not call elem_init/elem_free or CVEC_STRDUP/free.
- Adding a remove function that doesn't call elem_free/free (predates "move" functions... should I add an m even though the normal
"remove" is called erase? Or rename remove to erasem for consistency?)
- Fixing several bugs and semi-bugs/QOL issues
- Adding lots of new tests to cover most if not all new functionality
- probably more that I'm forgetting
Renaming remove to erasem occurred to me briefly, and I do appreciate the consistency, but I already had remove and theoretically
not breaking existing code (even if it's just mine) is a worthy goal and I feel the english connotations of erase vs remove are
appropriate here. Sigh, now I've pretty much talked myself into adding an erasem wrapper macro that calls remove.
So a little over a month ago, I thought it would be cool to try out emscripten and
WebAssembly with one of my students. We had previously done some "hello world"
type graphics programs and a simple game port and I thought it'd be fun to see
how easy (or not) it was to get those to run in the browser.
While I think it was a good exercise, and emscripten is much better than it was a
couple years ago, I don't think it's ready for primetime yet. You cannot simply
compile your existing graphics/game code and expect it to work. If you're lucky
you only have to make a few minor changes and with an #ifdef you can use the same
code for your regular executable to. If you're not, you might have to re-do your
whole program because of the limitations emscripten (which are really the limitations
of the browser/DOM rendering model. These include turning infinite loops into callback
functions and restricting yourself to OpenGL ES 2/3 which gets translated to WebGL 1/2.
In any case, here are our results:
For some reason we could not get file loading to work and the movement in sdl2_interactive is very
inconsistent for no reason that we could determine. We originally wanted to port simulate
which we had previously already ported to C but due to the mainloop callback requirement, it would have required a complete redesign.
I've posted a new project, opengl_reference.
As it says, it's going to be a growing repo of small to medium OpenGL programs.
Some will be very simple examples, almost tutorial type programs. Some will
demonstrate 1 or 2 specific features of OpenGL. Some will show specific aspects/behavior
of OpenGL (like it's left-handed canonical coordinate system or what happens when you draw
lines on the exact edges of the view volume). Finally, a couple will be template
programs, meant to be copy-pasted to start new projects of a certain type.
In the course of developing these, I'll be building my OpenGL helper libraries
(math, mesh/buffer/texture/shader management etc.) and refining/improving them. I'll
also be using/learning glm but I prefer using/writing my own for various reasons.
So I've resolved once again to try to post to this blog once
a week or so. Hopefully it'll help motivate me to make more
progress on my programming projects so I'll have something
to say. In addition, maybe I'll eventually make this site
look like it wasn't built in the 90's.
STATUS UPDATE 2/4/16: epic failure, recommitting.
Anyway, I've been tinkering with my collection of sorting algorithms
and the benchmarking program I wrote for them years ago. I've
also been looking at how to display the timing results in a pretty
graph. For now I'm playing with matplotlib in python.
On to the coding! I wanted to see how my algorithms stacked up against
the C stdlib qsort function (and C++'s std::sort but I only made a graph
for C). Since it uses a C style generic quicksort I decided to write
my own version with the same interface and compare all my quicksort
- qsort, standard recursive implementation
- qsortlib, C's qsort function
- genericqsort, my version of above
- iterqsort, iterative version of qsort
- qinssort, same as 1 but switches to insertion sort <=25 elements
As you can see, the 3 non-generic implementations 1, 4 and 5 all
perform roughly the same, especially at higher N, while the 2
generic versions are about half as fast due to the extra overhead
involved. My generic version is a tad slower but I think I'll try
adding insertion sort for smaller groups and see if that makes the
You can see the code I used here.
I compiled it as is but am only talking about main.c, or benchmark, not cppbenchmark.
Running this from the build directry (after build and running benchmark)
will generate the graph. I had to expand and save it manually ...
I need to figure out sizing the whole image programmatically.
I know there are a million lists of common programming mistakes (for almost every language) but I thought I'd do one myself. Hopefully in writing about my most common mistakes I'll quit making them or at least remember to check for them first when my code doesn't work. So . . .
1.) Forgetting a semi-colon.
I know it's the most obvious mistake in C/C++. Whether it's at the end of a class, struct, do-while loop or just a normal statement, I always seem to forget at least one semi-colon the first time I compile something.
2.) Adding a semi-colon to the end of an if statement.
I think one time I made this mistake was in my Watering Lawn project. I think I had the following (lines 100-104 in wateringlawn.cpp):
which of course drove me crazy because my program was compiling and I knew I had written it right but it wasn't doing what I wanted. Weird how your eyes can travel over the same place over and over again and you just get used to the semi-colon and totally ignore it. Unconsciously you just accept that it should be there. Fortunately I figured it out without too much head banging.
3.) Putting one equal sign in an if statement.
Yes I recently commited this mistake for I think the first time ever. I was just typing too quickly and without really focusing. I realize that there may be some edge cases where you might actually want an equal sign in if statement but I can't think of any and I haven't had any so far.
4.) Not looking at the entire line.
This is especially annoying if I've spent quite a bit of time staring at the line trying to figure it out after already having spent time isolating which line it is. I had the following line and of course was getting an error. Thing is I had already fixed the quotes (double to single) for the '('. I was so focused and frustrated that the compiler was complaining about something I'd already fixed I didn't notice the ones around the A.
5.) Using double quotes when I need single quotes.
See above. Sometimes I'm just not paying attention and typing to fast.
6.) Using gcc when I'm coding in C++.
7.) Not keep track of exactly where my pointers are pointing.
(and realizing when things are pointing at the same thing instead of different things passing C strings around etc.)
8.) Not using sizeof when using memory functions in C.
(I know you can leave it out for primitives like char and int but I should just always use it so I won't forget for the complex structures).
9.) Forgetting a break statement.
10.) Forgetting to increment a counter.
Or similarly forgetting to set the pointer to the next one while looping through a linked list.
Most of these (especially 7-10) I made while writing C PIM. Hopefully I can use these as a self checklist or something.
EDIT: 11.) Forgetting to close a file stream.
EDIT 2: 12.) Allocating the wrong amount of memory.
EDIT 3: 14.) Type problems (wrong conversions, underflow and overflow in arithmetic both integer and real).