Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 29 May 2009
Offline Last Active Jun 10 2016 08:38 PM

#5206844 Some programmers actually hate OOP languages? WHAT?!

Posted by on 27 January 2015 - 12:16 AM

Two main points:


#1:  OOP programming languages are a fad, and to many programmers, a religion.

#2:  A great many programs and applications can be written without objects of any kind.


Having said that, I'll make a couple personal comments.


#1:  I absolutely loathe OOP programming languages.

#2:  Most but not all the programs I write are chock full of object oriented aspects.


Are you shaking your head in disbelief yet?


Perhaps the best way to explain this [perhaps] seeming contradiction is the following.  I absolutely loathe other people telling me what to do, and how to do so.  I absolutely loathe other people forcing me to do things "their way".  I also absolutely loathe putting application-specific mechanisms in programming languages.  I also absolutely loathe "hiding", which is not absolutely necessary in an OOP programming language, but they all are (that I know of).  I also absolutely loathe staring at code that I can't understand without needing to read 65536 to 4-billion lines of header files and other code.  I also absolutely loathe completely bogus, unreadable, incomprehensible operators... instead of completely readable, comprehendable function names.  I also absolutely loathe having 50,000 code libraries that don't work together, and have 148,000 "approaches" (yes, sometimes several approaches per code library).


Shall I continue?  Because I could continue for hours!


Here is another very relevant way to express the above.  My programs are chock full of object-oriented aspects, and I have no trouble whatsoever implementing those aspects myself in conventional C code.  And when I do implement OOP aspects in my programs, my programs remain completely readable and easy to comprehend.  I also don't need to learn enormous quantities of obscure syntax and methodologies (that are often not applied uniformly by everyone).  I can implement OOP aspects in plain old C code quite happily, BTW.  And each is appropriate to what I need to accomplish, not some attempt to hyper-generalize until cows turn into leptons, making everything sooooo general that it is chock full of clutter (required to be ultra-general), chock full of hidden or difficult-to-learn assumptions (sometimes to make hyper-generality even possible or workable).


KISS.  Keep it simple, stupid!


I can do everything... EVERYTHING... with C that anyone else can do with C++, and my code will be simpler, faster, more readable, more reliable, easier to modify, easier to collaborate with others, easier to document, and just plain better.






The short answer is, I can do absolutely everything with:


#1:  statements
#2:  variables
#3:  operators
#4:  functions


Did I forget something?  Probably one or two.  Maybe you don't think of "structures" as being variables.  Maybe you don't think of "structure declarations" as being "types".  You can argue the C language contains a few more kinds of gizmos, but frankly, very few.


?????  WHAT DOES THIS MEAN  ?????


This means I only need to know (or remember) how statements work, how variables work, how operators work, how functions work... and THAT IS ALL.


Well, guess what, noobies?  If you do everything with only half a dozen very simple and fundamental mechanisms... ALL DAY, EVERY DAY... you not only learn them thoroughly... you habituate them very quickly and thoroughly, so they become like "how to breath".  You do not forget!  You do not get confused.  You don't need 37 ways to walk, you just freaking walk.


And how about interoperation?  How about implementing code libraries?


They are pretty much all exactly the same.  They are a huge pile of functions.  PERIOD.  Everything works the same, because they are all functions, just like the functions in your own programs, and just like the functions in other libraries.  And when you look at a function declaration, you understand it.  Some arguments are inputs, some arguments are outputs (the arguments passed by address without "const").  And you KNOW how every single one of them is passed... either the value of the variable is passed, or the address of the variable is passed.  Just look at the type of each argument.  The value of "int" or "double" or any other type argument is passed directly.  If you see one or more "*" as part of the typename in function declarations, you know the address (or the address of the address, etc) of the argument is passed.  So argument type "int*" means the argument is an address (pointer-to) an int.  And so forth.  You know what's happening.  With C++, you don't even know what a reference type is, because they reserve the right to hide and obscure that (and millions of other aspects of "what's going on" under the covers where you cannot see, or even if you can, it may change next Tuesday).


I'm gonna stop here, because I know there are already at least 256 hit men trying to figure out who I am, so I can be "taken out" for my atheistic views of the world, and especially for wanting my life to be simple, yet utterly flexible.  Religious freaks hate thinking like mine.


Just for the record, I learned C++ before C.  I just hated C++ so much, I decided to give C a try.  It was like removing 65536 scorpion stingers from my brain!  What a freaking relief!!!  You cannot even imagine.


Nonetheless, the fact of the matter is, humans can learn, habituate and even love just about anything, including horrific abuse.  So if you do learn to program in C++, you'll eventually habituate some way of doing things in C++ (there are about 143-million ways, and roughly 1 way to do things in C, not counting trivia like "which style comments do you prefer").


BTW, if there are any advantages to C++ (and I'm sure someone can concoct some convincing-on-the-surface examples), the totality is absolutely, definitely, certainly much more complex and problematic with C++.  Best things about C is... it works the same for 30 years, and it will work the same for another 30 years unless some C++ lover decides to "destroy C from within".


Perhaps the biggest lie of all is... C++ is better for "large programs" with "lots of contributors".  Boy is that the opposite of true!  Holy smokes!  You know how to know this is a total line of BS?  Easy.  Do you think a group of programmers who do everything with 6 simple mechanisms ALL THE TIME (with zero to nothing hidden away out of sight) can work together and understand each others code easier than a group of programmers who adopt varying subsets of 87 mechanisms and 93 non-compatible class libraries?  Hahaha.  You guess!  The additional proof is this.  The way to write good, solid, reliable C programs is the same today as 20 years ago.  The way to write good, solid, reliable C++ programs has not been invented yet, but thousands of people (who claim C++ is the greatest thing since sliced bread) will swear on a stack of bibles that THEIR WAY is the best way in the history of the universe.  Decide for yourself which you suspect is true.


And good luck!  You're gonna need it!


PS:  If you love to be loved, and hate to be laughed at... you must adopt C++.  That's for certain.  If you just want to write great code that works for years, and interoperates easily, well, prepare to be hated and vilified by the most vocal self-proclaimed programmers on planet earth.

#5047542 Article Inspiration

Posted by on 28 March 2013 - 12:37 AM

Yikes!  My browse through the messages so far indicates some serious energy and interest, and some great ideas.  In fact, too many ideas!  Well, not too many, just too disorganized.


table of contents
What someone needs to do is create a tree hierarchy of reasonable topics mentioned so far, which could be in the form of a table-of-contents.  Then people can add their requests in the appropriate place, and everyone can see the fullness of the topics without reading a zillion messages --- just imagine this thread in a few months!



omit fad wars - keep ratings professional

I also have a question and request.  I don't have problems with ratings - that's a reasonable way to judge the quality and popularity of an article.  However, I have to point out one annoying problem that exists in gamedev as well as just about everywhere else.  That is the problem of ratings and commenting based upon "fads" rather than utility, quality and other values.  A huge number of people, especially close-to-newbies try to show how "in" or "hip" they are by trashing anything that doesn't conform to the current set of fads.  This just creates pointless fights.  But even worse, people with loads of experience get tired of being dumped on by fad-addicts (and "my-way-or-the-highway" types), and stop contributing.  Why should they help if their reward is being dumped upon?


So I'm a bit skeptical about a wide open rating system.  I'm not sure how to solve this problem.  I've seen a few of the moderators behave the same ways in gamedev threads, so I'm not sure leaving ratings to moderators is the solution either.  Only let authors who already contributed rate others?  Anyone have a solution for this problem?


Here are examples of what I want to avoid:

  - lots of negative votes for a great article about SIMD because "assembly language is stoopid" or "outdated".

  - lots of negative votes for a great article about "topic-X" because "C" or "java" or "pick-your-language" is not very popular.
  - lots of negative votes for a great article about "topic-X" because it contains OpenGL while D3D is more popular, or vice versa.
Hey, I always prefer to find that great articles formulate their examples in the programming language, shading language, graphics API, indenting-style that I adopted for my own projects.  But I never mark anyone down for their choices - that's just unprofessional, and tends to punish good folks who are simply trying to help others.
editing - author has last word
I very much appreciate when someone fixes my typos or grammar, or makes my language clearer, or adds an image, figure, example.  Unfortunately, more often than not, people who edit my stackoverflow messages make them less precise, more confusing, and insert errors (which people then assume came from me).  So while I love the idea of improving and perfecting articles, I don't know the best way to achieve this in practice in a wide-open community setting such as this.  My opinion is, the original author must have final say on his article.  My favored solution is for edits to be sent to the author, who can then choose to incorporate them or not.  A tool that emphasizes changes with different color text would make this process easy for authors and editors.

topic requests
Some topics I would love to see:
  - shadow maps
      - basic algorithm explained in exhaustive detail (explain everything, make no assumptions)
      - exponential shadow mapping (current state of the art - explain everything)
      - variance shadow mapping (current state of the art - explain everything)
   - compute geometric center of object (array of positions)
   - compute center of mass of objects with thin shells
   - compute center of mass of solid objects
topics from me
Some topics I might contribute articles about:
  - SIMD (32-bit mode with 8 128-bit xmm registers, and 64-bit mode with 16 256-bit ymm registers and AVX/FMA/etc)
      - for matrix multiply
      - for vertex transformation
      - for simultaneous computation of any combination of 4 sines/cosines of 4 input angles
  - collision detection
      - broad phase with SAP
      - narrow phase convex with GJK
      - narrow phase concave with new technique
   - procedurally generated content
      - 3D shapes - create, assemble, articulate, automate, destroy
      - textures
      - terrain
  - triangle-triangle intersection
     - fast technique that outputs all information
     - fastest known technique (outputs true or false)

#5045147 C++ Programming - What IDE to use ?

Posted by on 21 March 2013 - 12:09 AM

A new binary release of CodeBlocks was released just a few months ago after ~3 years.

But also, the latest version is always available too, called "nightlies".


IMO in order of best.


VS2012  // best for windows

QtCreator  // best for cross platform

Eclipse CDT  // good cross platform but kinda slow, can be difficult to setup.

code::blocks // light on resources but aged, new version in the works


Here is a pretty good list of IDE's by language.


#5042977 C++ Programming - What IDE to use ?

Posted by on 14 March 2013 - 12:36 AM

CodeBlocks for Linux development.

VisualStudio2010 or CodeBlocks for Windows development.

If you're creating both Linux and Windows applications, CodeBlocks alone is fine.

Eclipse is very slow and extremely annoying in certain ways.

#5042366 Best Practice for Values Return C/C++

Posted by on 12 March 2013 - 11:01 AM

The answer is --- "during development and to deal with changes in behavior of OS, API and library functions".


It seems we both agree that once we have our applications working (or even just functions or subsystems working), we almost don't get any errors at all.  However, when we write a couple thousand lines of new code, we might have made a mistake, inserted a typo, or misunderstood how some OS/API/library function/service is supposed to work [in some situations].  So that's mostly what error checking is for.


This might imply we can just remove the error checking from each function or subsystem after we get it working.  There was a short time in my life when I did that.  But I discovered fairly soon why that's not a wise idea.  The answer is... our programs are not stand-alone.  We call OS functions, we call API functions, we call support library functions, we call functions in other libraries we create for other purposes and later find helpful for our other applications.  And sometimes other folks add bugs to those functions, or add new features that we did not anticipate, or handle certain situations differently (often in subtle ways).  If we remove all our error catching (rather than omit them with #ifdef DEBUG or equivalent, we tend to run into extremely annoying and difficult to identify bugs at random times in the future as those functions in the OS, APIs and support libraries change.


There is another related problem with the "no error checking" approach too.  If our application calls functions in lots of different APIs and support libraries, it doesn't help us much if the functions in those support libraries blow themselves up when something goes wrong.  That leaves us with few clues as to what went wrong.  So in an application that contains many subsystems, and many support libraries, we WANT those function to return error values to our main application so we can figure out what went wrong with as little hassle as possible.


You seem like a thoughtful programmer, so I suspect you do what I do --- you try to write much, most or almost all of your code in an efficient but general way so it can be adopted as a subsystem in other applications.  While the techniques you prefer work pretty well in "the main application", they aren't so helpful if portions of your applications become a support library.  At this point in my career, almost every application I write (even something huge like my entire 3D simulation/graphics/game engine) is designed to become a subsystem in something larger and more inclusive.  So I sorta think of everything I write now as a subsystem, and worry how convenient and helpful it will be for an application that adopts it.


Anyway, those are my thoughts.  No reason you need to agree or follow my suggestions.  If you only write "final apps" that will never be subsystems in other apps, your approaches are probably fine.  I admit to never having programmed with RAII, and generally avoiding nearly everything that isn't "lowest-level" and "eternal".  The "fads" never end, and 99% of everything called "a standard" turns out to be gone in 5 or 10 years.... which obsoletes application that adopt those fads/standards with them.  I never run into these problems, because I never adopt any standards that don't look reliably "eternal" to me.  Conventional errors are eternal.  OS exception mechanisms are eternal.  Also, all the function in my libraries are C functions and can be called by C applications compiled with C compilers (in other words, the C function protocol is eternal).  This makes my applications as generally applicable as possible... not just to my own applications, but to the widest possible variety of others too.


There's no reason you or anyone else needs to make these same policy decisions.  I am fully aware that most people chase fads their entire lives, and most of the code they write becomes lame, problematic or worthless after a few years --- not because their code was bad, but because assumptions they and support libraries adopted are replaced by other fads or become obsolete.  All I can say is, my policies accomplish what I want extremely effectively.  Most of the code I write is part of a very large, very long term application that will end up taking 20 years to complete (and will then be enhanced and extended indefinitely).  So I literally must not adopt any fads, or anything that might become a fad in the next 30 years.  You would be completely correct to respond that not everyone needs to write in such an "eternal", "bomb proof" and "future proof" manner as I do.  People can make their own decisions.  That's fine with me.  I hope that's fine with you too.


One final comment that is also somewhat specific to my long term application (and therefore a requirement for every subsystem I develop).  This application must be able to run for years, decades, centuries.  True, I don't count on this, the application is inherently designed to recognize and create "stable points" (sorta like "restore points" in windows), and therefore be able to crash, restart and pick up where it left off without "losing its mind".  But the intention isn't to crash, restart, restore very often... the attempt is to design in such a way that this never happens.  Yet the application must be able to handle this situation reliable, efficiently and effectively.  Perhaps the best example of this kind of system is an exploration spacecraft that travels and explores asteroids, moons, planets (from orbit) and the solar-system in general.  The system must keep working, no matter what.  And if "no matter what" doesn't work out, it needs to restart-restore-continue without missing a beat.  Now you'll probably say, "Right... so go ahead and let it crash".  And I'd say that maybe that would work... maybe.  But physical systems are too problematic for this approach in my opinion.  Not only do physical machines wear and break, they go out of alignment, they need to detect problems, realign themselves, reinitialize themselves, replace worn or broken components when necessary, and so forth.  And those are only the problems with the mechanisms themselves.  The number of unexpected environments and situations that might be encountered are limitless, and the nature of many of these are not predictable in advance (except in the very most general senses).


I suppose I have developed a somewhat different way of looking at applications as a result of needing to design something so reliable.  It just isn't acceptable to let things crash and restart again.  That would lead to getting stuck in endless loops... trying to do something, failing, resetting, restarting... and repeating endlessly.  A seriously smart system needs to detect and record every problem it can, because that is all evidence that the system will need to figure out what it needs to fix, when it needs to change approach, how it needs to change its approach, and so forth.  This leads to a "never throw away potentially useful information" premise.  Not every application needs to be built this way.  I understand that.


I'm not sure what "error driven code" is supposed to be.  In my programs, including my 3D simulation/graphics/game engine, errors are extremely rare, pretty much vanishingly rare.  You could say, this (and many programs) are "bomb proof" in the sense that they are rock solid and have no "holes".  Unfortunately, things go wrong in rare situations with OS API functions and library functions, including OpenGL, drivers, and so forth... so even "a perfect application" needs to recognize and deal with errors.

In short: why choose to have your code full of error checking (which breaks code flow and makes the code harder to read - that is really undeniable, IMO) to handle errors that are rare and unrecoverable anyway? Leave those to exceptions (or just crash the process), and keep the error checking code for cases where you can intelligently handle them and take appropriate action. It's best not to conflate exceptional conditions with expected errors.

#5041824 Best Practice for Values Return C/C++

Posted by on 11 March 2013 - 06:55 AM

I have to disagree with part of your message.  In many of the functions in my engine, some resources further down in the function cannot be created unless the resources created earlier in the function succeed.  So you can't just willy-nilly "free everything" in one place... at least not in every function or situation.  Some of these problems can be eliminated by setting all resource variables to zero at the function entry, and then checking those resource identifiers for non-zero values in a single "free all resources if an error is encountered" spot near the end.  I used to do that sometimes years ago, but found that "freeing the appropriate resources" in each place is no big deal.  I suppose part of the reason for that is that these situations occur only a handful of times in even my large applications.


One thing that I always try to point out is this.  Over the years I have developed an extremely uniform and simple way of writing code.  Pretty much every function looks the same as every other, and all share the same general practices.  I admit this took quite a few years to figure out and solidify, but now that I've done that, I just don't have programming problems.  Sure, I still have design problems... figuring out ways to solve a problem [cleanly or efficiently], but the coding part is now easy.  What I'm trying to say here is... uniformity is probably more important than specific practices --- assuming we are choosing from a good solid set of alternatives of course.


BTW, though I write very large and complex applications, I freely admit that my coding style is very simple, straightforward and exceedingly consistent.  I go out of my way to avoid mixing and matching multiple [fancy] approaches like many people do (and pride themselves in doing).  This makes "being diligent" trivial and automatic (thoroughly habituated).  My approach works great for me, but won't satisfy some others.  For programmers who love complexity, and mixing and matching all sorts of approaches, I have nothing to suggest --- except "duck".


You simply claim without justification that my technique is a "code maintenance nightmare".

You're right, I didn't justify it. I'll do that now.

With RAII techniques, returning from the middle of a function often isn't such a big deal (although I'd still argue it makes the function harder to understand). (The only time I do early returns is for basic parameter checking at the beginning of a function).

If you're manually freeing resources though, it means you need to make sure to free the right resources at every exit point. This is obviously easier to get right if there is a single exit point. Otherwise, it's easy for someone to come along and add new code that allocates resources, and then forget to update the "free" code in one of the exit points. That's a code maintenance problem.

If it's just you working on the code and you are very diligent, then this may not matter to you.

#5041372 Best Practice for Values Return C/C++

Posted by on 09 March 2013 - 09:20 PM

Almost every function in my engine is of the form:

 error = function_name (arg1, arg2, arg3...);


The return value is always an error number.  However, if all the function needs to return is a positive integer, you can return that in the return value.


Almost every function call is followed by:


 if (error < 0) { return (error); }


... or sometimes some other code or function call might be tried before or instead-of the return(error); portion.


Overall, the following is common (though some elements are not required in many cases).


 error = value = function_name (arg1, arg2...);   // skip "value =" portion if only error values are returned
 if (error < 0) {
   free_resources (arg1, arg2, arg3...);
   return (error);
 // continue on with valid positive value


The above approach has proved the most convenient for me over many applications and libraries, after trying all sorts of alternatives.  One equally viable approach, and possibly better because it is more consistent, is to never return anything but error values from functions, and remove all values in arguments.  I didn't do that, but now and then think that's a better approach (because absolutely uniform in layout).

#5039269 Can't decide which math/physics basics book to get

Posted by on 04 March 2013 - 06:41 PM

Don't get the same book for "math" and "physics"... that's not very effective.  There's just too much to cover to expect a single book to do a good job.  For the physics part, I suggest "Game Physics Engine Development" as being easier to consume, highly practical, but less theoretical than the Eberly alternative.  Make sure you get the most recent edition (by Ian Millington, published 2010 July 23).


Which is the best math book for 3D graphics is more difficult to choose, but you've got some good suggestions already.


For "collision detection" I'd suggest you buy "Real Time Rendering", even though collision-detection is only one of many topics in this fabulous book.


Also, here is the single best resource to get you started on "narrow phase collision detection": https://mollyrocket.com/849 .  After you watch the video, wander through the forum.  This is a great resource.  If you decide to implement GJK for narrow-phase and/or sweep-and-prune for broad-phase and/or need to perform collision-detection on arbitrarily irregular "concave objects", you can contact me for more detailed conversations.

#5038265 OpenGL Programming Guide 4.3

Posted by on 01 March 2013 - 09:09 PM

I'm not sure why, but almost everyone ignores the OpenGL and GLSL specifications, which are free, downloadable PDF files on the www.opengl.org website.


Yes, they are not printed books.  Yes, they don't have boatloads of drawings and figures and pretty color photos.  However, they are VASTLY more helpful than the term "specifications" implies.  So the very first thing you should do is download, print-if-you-prefer, then read all the way through those documents.  They really are great.


As for "regular books", the OpenGL SuperBible has been the best OpenGL-specific book for several years.  And probably the best book that isn't OpenGL-specific is "Real Time Rendering".


These days, to do a great job, you almost need to have all these resources available:

  - the specifications
  - the best 2 or 3 OpenGL-specific books

  - the best 3 to 8 other 3D graphics books

  - the best 100~200 PDF files you can find on the internet


In my opinion, the official OpenGL books were never near the top of the list of "bests".  However, if they issue a full rewrite and it fully covers v4.30 (not just an addendum of newly added features), then it might be the first "real winner" from that series.

#5021547 help: cannot build my 3D engine (link problem)

Posted by on 14 January 2013 - 01:54 PM

In case anyone has the same problem someday, and their favorite search engine sends them to this thread, the probable cause of this strange situation is the following.


It appears that somehow I got 64-bit libraries in the 32-bit library directory.  Not sure how I could do something that off-the-wall, but when I replaced all the files in my 32-bit and 64-bit directories, the problem vanished.  So that was probably the cause.

#5019203 help: cannot build my 3D engine (link problem)

Posted by on 08 January 2013 - 03:50 PM

Later: I ran the dumpbin.exe program on cairo.lib and libcairo.dll and found the names of the cairo functions (like "cairo_create" and "cairo_destroy" for example), and they did not have __imp__ or __exp__ prefixes on the symbol names. So I'm at a total loss why VS2010 is trying to link in symbols with those __imp__ prefixes. What am I accidentally doing to cause that? I assume it is me who screwed up, but I don't understand. Also, I searched through my program and I don't have a single "dllimport" symbol anywhere. Of course cairo.h or other library files that I include might.


To mhagain:  Peace, brother.  A two character indirect comment is about as gentle, concise and non-intrusive as one could possibly be.  And besides, I type very fast, and that one has been a habit for quite some time.  I'm trying to discuss graphics programming problems.  It is not me turning 2 characters into flames.  I just want to solve this problem and get back to graphics programming, not build hassles.

#5019102 help: cannot build my 3D engine (link problem)

Posted by on 08 January 2013 - 11:45 AM

I've given you a -1 for "windoze" because it's rather silly and immature, but - without reviewing your full question - one item of info I cna give is that .lib files certainly can be .dll link stubs, and there are several examples of this throughout various MS SDKs (a .lib just contains code, and there's nothing to prevent that code from making LoadLibrary/GetProcAddress/FreeLibrary calls).


As an aside - any reason to not use Code::Blocks/MinGW on Windows?  It seems to me to make more sense to keep your builds consistent in this way than to deal with the hassle of moving between different build environments/processes.


Yes, I would like to develop with codeblocks on both platforms, and maybe someday I will go through the effort to do that.  In fact, I was going to make the switch now, but someone (from here on gamedev) wants to integrate my project with a project he is doing, and he is not willing to learn a new IDE.  So I'm putting up with VS2010 until I am finished helping him.


One problem with switching is that I have hundreds of #ifdefs LINUX and #ifdef OTHEROS in my code.  Right now they serve two purposes... differences between the two platforms/OS, and other differences.  In other words, I'm going to need to go look at every one of those #ifdefs and decide whether it needs to #ifdef on the basis of the OS-name, or on some other basis (like toolset: GNU vs VS).  I should have been more careful at the start, but I wasn't.


Switching to codeblocks/mingw should help me in another way too.  I have 4 separate assembly-language files for 32-bit linux, 64-bit linux, 32-bit VS, 64-bit VS.  In theory a single 32-bit assembly-language file in gas syntax should work on both, because the function protocols are the same, so presumably mingw gas should assemble and link the file correctly.  I'd still need a separate file for 64-bits, because the function protocols are drastically different.  It would still be a lot easier to translate them than currently, since they'd both be gas syntax.


Anyway, so the cairo.lib file might be a static DLL stub file that dynamically links to the cairo DLL file.  But my questions still remain.  Why doesn't it link?  What is that __imp__ prefix all about?  Why doesn't it find those symbols?  Maybe it is trying to link to the actual function names (as in a static linked library), but only finds those __imp__ prefix names.  Or maybe it is the other way around.


BTW, it is you who is incredibly immature.  Think about it.  Does bad spelling cause you cancer?  You can't believe how many times I've helped people, and spent a lot of time doing so, and not gotten thanks (or a +1 when here).  You are so petty or hyper-sensitive, I'm a bit stunned.

#5019063 help: cannot build my 3D engine (link problem)

Posted by on 08 January 2013 - 10:01 AM

I've been developing a 3D engine for a while, and it was working (on both linux64 and winxp64) when my winxp64 drive stopped booting. I bought a new disk drive, installed 64-bit win7 and vs2010, and now I'm trying to get my engine to compile again. It now compiles, but the linker generates the following errors:

1>igimage.obj : error LNK2019: unresolved external symbol __imp__cairo_status referenced in function _ig_image_create
1>igimage.obj : error LNK2019: unresolved external symbol __imp__cairo_create referenced in function _ig_image_create
1>igimage.obj : error LNK2019: unresolved external symbol __imp__cairo_image_surface_create_for_data referenced in function _ig_image_create
1>igimage.obj : error LNK2019: unresolved external symbol __imp__cairo_format_stride_for_width referenced in function _ig_image_create
1>igimage.obj : error LNK2019: unresolved external symbol __imp__cairo_surface_destroy referenced in function _ig_image_destroy
1>igimage.obj : error LNK2019: unresolved external symbol __imp__cairo_destroy referenced in function _ig_image_destroy
1>igimage.obj : error LNK2019: unresolved external symbol __imp__cairo_surface_write_to_png referenced in function _ig_image_save
1>igimage.obj : error LNK2019: unresolved external symbol __imp__cairo_get_matrix referenced in function _ig_image_get_font
1>igimage.obj : error LNK2019: unresolved external symbol __imp__cairo_toy_font_face_get_weight referenced in function _ig_image_get_font
1>igimage.obj : error LNK2019: unresolved external symbol __imp__cairo_toy_font_face_get_slant referenced in function _ig_image_get_font
1>igimage.obj : error LNK2019: unresolved external symbol __imp__cairo_toy_font_face_get_family referenced in function _ig_image_get_font
1>igimage.obj : error LNK2019: unresolved external symbol __imp__cairo_get_font_face referenced in function _ig_image_get_font
1>igimage.obj : error LNK2019: unresolved external symbol __imp__cairo_move_to referenced in function _ig_image_set_drawpoint
1>igimage.obj : error LNK2019: unresolved external symbol __imp__cairo_set_source_rgba referenced in function _ig_image_set_color
1>igimage.obj : error LNK2019: unresolved external symbol __imp__cairo_set_font_size referenced in function _ig_image_set_font
1>igimage.obj : error LNK2019: unresolved external symbol __imp__cairo_select_font_face referenced in function _ig_image_set_font
1>igimage.obj : error LNK2019: unresolved external symbol __imp__cairo_show_text referenced in function _ig_image_draw_text


I'm not sure, but I thought the __imp__ prefix on function names implies I'm trying to link to a DLL, not a static library. This confuses me, because the link targets I specify in VS2010 are the following:


Maybe I'm forgetting something, but I thought .lib files were static link libraries, not DLL link stubs or whatever. None of the other libraries are generating build errors.  Either that or the build process is stopped before it attempts to link additional subsystems.

I quadruple checked my various search directories, and cairo is included. Because I build 32-bit and 64-bit linux implementations and 32-bit and 64-bit windoze implementations (and just copy my whole project directory back and forth between my linux and windoze computers), I created a parallel directory structure for include files, library files, and so forth. They follow the general structure:



and inside each of the (usr/bin, usr/include, usr/lib) directories are the expected individual subsystem directories (cairo, pango, freetype, glib, zlib, etc), which contain the appropriate files.

For example, inside /usr/lib/cairo are the following files:


I don't reference any *.a or *.dll.a files in my project settings. I've been creating static builds (or think I have been) since the beginning of this project.

Of course, maybe those __imp__ symbol prefixes don't [necessarily] mean or imply DLLs, and my problem is elsewhere. I'm far from a guru when it comes to building apps in lots of different ways. In fact, I'm not expert on windoze in general, I do most of my work on linux, then just copy over the files and make sure they build and run on win7.

I downloaded my "binary" and "developer" files from <http://www.gtk.org/download/win64.php>, which has been a reliable place in the past. In fact, I've downloaded and copied the include and lib files from the cairo package three times now, trying to fix this problem.

Maybe I'm doing something totally stupid here, but I don't see it. The first time I tried to build this code on win7, VS2010 accepted the old project file and made an upgraded one without errors. And I've looked through the project settings at length and don't see anything obviously wrong (to dimwit me, anyway).

The application builds and runs in both 32-bit and 64-bit mode on linux. But of course that doesn't mean much, since the problem here seems to be in the build process, which is codeblocks and gnu tools on linux, and VS2010 on win7.

Any ideas?


#5019060 Fast sin and cos functions

Posted by on 08 January 2013 - 09:42 AM

Recently I wrote some SIMD/AVX assembly language functions that compute:


 - two sines (in xmm registers)

 - two cosines (in xmm registers)

 - four sines (in ymm registers)

 - four cosines (in ymm registers)

 - four sines or cosines (in ymm registers) --- an arbitrary mix of sines and cosines


The last one takes an integer argument that specifies whether you want the sine or cosine for each argument.  The input angles and results are all f64 values (64-bit "double precision" floating point).


Writing those routines was quite the learning experience, in more ways than one!!!


The main purpose was to get very good at the newest AVX/XOP/FMA* and related instructions.  I haven't done a lot of completely parallel routines with SIMD instructions, and these were definitely completely parallel, since they compute the sines and cosines of up to four arguments exactly simultaneously.  Believe it or not, the entire routine to compute a random mix of 4 sines and cosines has zero jmps (conditional or unconditional).  The code just flows all the way through from start to finish!  It was quite satisfying to find that I could write the code that way, and major congrats to the guys at AMD [and Intel] for having just the right instructions to support this kind of flow-through code.


The routines are fast, especially when you consider you're getting 4 results for the price of one.  I was able to organize the instructions so the code pretty much never needed to access the result of an instruction until at least 4 instructions later, which seems to be the latency of 256-bit wide ymm instructions.


However, there is one downside.  Since the results are computed in the SIMD registers, not the 80-bit wide FPU registers, there are certain angles where the results are not quite as precise as the FPU sine or sine-cosine routines.  The results are always correct to 16-digits from the decimal point, but at certain angles (pi/2 if I recall correctly), where the result is almost zero, some significant bits are lost (even though the result is still correct to 16-digits from the decimal point).  I was able to definitively pin down the problem to a place in the routine (and all similar cheby or taylor routines) where a subtraction of similar-size numbers occurs.


I organized my algorithm to minimize the error, but it was impossible to eliminate.  Of course, most people don't give a damn about this precision loss, since they still have 16-digits of precision from the decimal point.  But I'm one of those people who sweats the very last bits in some of the computations I do, for example astrodynamics (solar-system orbit computations).  I made absolutely sure I knew where the problem was, by writing a version of the routines that performed the precision-losing subtracts on the mantissas alone in 64-bit integers... and that solved the "problem".


I actually have 5 variations with 7, 8, 9, 10, 11 chebyshev coefficients. The longer ones are supposed to be more precise, but it appear like 7 coefficiencts is sufficient (and is obviously a bit faster).


Anyway, if you're interested in the nitty gritty, I'll post one or two of these routines here.  Or if you prefer, PM or email them to you.

#5018184 How to build a 3D Engine?

Posted by on 06 January 2013 - 07:57 AM

There are also a couple books about game engines, at least one of which includes a reasonably advanced engine.  You should at least read those books.  You might also consider finding a game engine project and offer to help on that engine.  You'll not only have a real example to work on, but you can certainly ask others about the subsystems they design and implement.


A powerful 3D game engine today is one huge project.  You can, of course, limit your engine to games in which thorough collision-detection and collision-reponse (physics) is not required, and that will reduce your workload by about 2/3.  You can always add them later.


In fact, if designed in an intelligent, modular way, it should be quite natural and straightforward to add capabilities and features one-by-one, once you have the essentials working (which means basic window display and management, 3D objects and hierarchies, 3D graphics, 3D rotation/translation/manipulation).


Still, a modern game engine is a huge project.  It is feasible, if you invest enough time, effort and diligence, but it will require a lot of work.