PDA

View Full Version : OT (ish): Quake2 Source Code



KuriousOrange
05-04-2003, 06:10 AM
Hello,
Just been browsing the Quake2 source code.
It's not very efficient drawing code, is it?
It doesn't use vertex arrays (for bsp drawing). Immediate mode using the GL_POLYGONS transfer mode....mmm.
It does a lot of texture bindings (doesn't appear to add polys into texture bins, with a renderbins function at the end of the traversal) - this is odd, because it has the depth test enabled, so it's not like it needs to render in a rigid back-to-front order (there could be a separate transparent poly bin container).

Any thoughts on the reason why this GL code is so bad? Taking into account it was written in 1997, it's still pretty naive coding considering vertex arrays were around at the time.

Just a lazy sunday conversation - so forgive me if I irritate you.

By the way - another thought on the quake2 code - it doesn't appear to have been "designed", if you know what I mean? It looks really like a couple of guys have decided on a basic client/server structure, come up with an agreed function prefix protocol, and just gone for it...heads down...let's get typing!!
I'm surprised because John Carmack is regarded as a supreme programmer - yet, all I'm left with is some respect at writing a very fast software rasterizer for Doom years ago.

Jan
05-04-2003, 07:13 AM
I didnīt look into the actual drawing code, but i was also surprised about the "design". It really doesnīt look that superior.
But then look into how it handles particles, itīs damned optimized with assembler.

Actually i donīt think the Q2 sourcecode is really helpful. I mean, when i look at my "engine" then all it does is traversing a tree, culling nodes, back-facing polys and using quite a good vertex-array structure.
However all the real hard work is not done by the engine, itīs done by the level-compiler, which culls lots of never-to-be-seen polys, creates the tree and does some other important stuff.

So, what i really would be interessted in, is the source of idīs level-complier, but as far as i know, that source is not released, is it?

Jan.

gibber
05-04-2003, 07:45 AM
So, what i really would be interessted in, is the source of idīs level-complier, but as far as i know, that source is not released, is it?

The source code to the Quake3 level compiliers is available on ID's FTP server. You also get the code to the radiosity processor (qrad3). Which is nice http://www.opengl.org/discussion_boards/ubb/smile.gif

zen
05-04-2003, 09:02 AM
I have taken a (little)look at the quake 2 code recently too. First off, correct me if I'm wrong but it is pure C code isn't it? Does JC still code in C. I think I read somewhere that he is using C++ and was somehow surprised(that he uses C++).
I too don't like the way the q2 and q3 engines does lots of things but other 'features' (rather trends it seems, wich I believe JC introduced) like the console, mods, shaders etc. are much more worthy of respect (as application-system design) than code design. Besides don't forget that deadlines and competition sometimes don't leave room for carefull planning of every detail.

Jan
05-04-2003, 09:41 AM
In some article it was said, that at the beginning of Doom 3 id decided to move on to C++. So Q3 is certainly also coded in C.
I was very surprised about them not using C++ in Q3, but i think it is better to use plain C, instead of a mixture of both.

idīs ftp server? Whatīs the exact url? ftp.id.com had nothing to offer.

Jan.

Mezz
05-04-2003, 10:01 AM
id's FTP server is ftp.idsoftware.com

Remember that Quake2 was written a long time ago (in the scheme of accelerated graphics), and it's data set also had to cater for a software renderer too. Also, if Quake's software renderer could render them all in effectively the same way (immediate mode) then an accelerator card would almost certainly be able to do it.

-Mezz

Pentagram
05-04-2003, 10:14 AM
I used the quake1 source (and looked quite a bit at the quake2 source).
They obviously never really taught about software design. It all works as long as you don't change it. If you do you'll quicly run into globals being modified, wich ones were?? you never know so just add your own http://www.opengl.org/discussion_boards/ubb/wink.gif
Then it's all plain vanilla C and even a "library" is something they don't use mucy I mean just some handy utitlity routines, thinks you often need... (like the Distance between 2 points http://www.opengl.org/discussion_boards/ubb/wink.gif )
You can give them some excuse because of "the speed" but still, look at the unreal engine that's fast to and it's all written in c++ with abstract classes and whatnot.
The map compilers are nice algothithms, but again they're hacky code, statically allocated big arrays etc...
I can only hope for the people who are going to licence the doom3 engine it's going to be cleaner http://www.opengl.org/discussion_boards/ubb/wink.gif (Maybe quake3 is cleaner... dunno...)

Charles

CAD_Swede
05-04-2003, 11:33 AM
Originally posted by Pentagram:
I used the quake1 source (and looked quite a bit at the quake2 source).
They obviously never really taught about software design. It all works as long as you don't change it. If you do you'll quicly run into globals being modified, wich ones were?? you never know so just add your own ;)

Speaking as someone who've coded against the Quake2 source code for a "real" game, licencing the Q2 code base for enormous amounts of money, I can tell you that it's a MESS. :-) Tons of things that could have been done better, tons of things that could have been done cleaner.

Still, in essence, it's a game engine written by one guy before any other game engines existed. Carmack is IMHO worthy all seven shades of respect for it. (Quake 2 is based off Quake 1, BTW, so much of the stuff is ugly because Quake 1 was ugly :-)

It's not pretty, it's not superb, but he put it out there. He made his money and he proved that he could "Get it Done", which is what software development really is about. :-)

The GOOD thing about this is that it makes us all feel much better. I mean, we can all say that we would have coded the damn thing a LOT cleaner, with a nice object hierarchy (instead of binary compatible C structs, that are extended differently depending on where in the code you are :-)

At the end of the day, he drives a Ferrari to where he flies rockets, all paid for by his own software, so... I say he's still worth all kinds of cred.

/Henrik, formerly "Switz" of Ion Storm's Anachronox team.

KuriousOrange
05-04-2003, 11:36 AM
Yes, I understand it was all written a long time ago in the context of hardware acceleration (1997 as documented in the source code). But, taking that into account, the core drawing code looks very similar to my quick-hack demos from a few years back, when I was just getting into realtime rendering - before I concerned myself with the efficiency/design/functionality balancing act.
I don't know, it's probably all the globals, the huge macros, the empty for loops, the goto's, the ambigious variable naming convention, the huge swathes of commented out but not deleted code segments, the fixme comments, the "should this work?" comments...etc.etc.
Shocking, sort of like catching the pope taking a prozy up the wrong 'un!

CAD_Swede
05-04-2003, 11:46 AM
Originally posted by KuriousOrange:
I don't know, it's probably all the globals, the huge macros, the empty for loops, the goto's, the ambigious variable naming convention, the huge swathes of commented out but not deleted code segments, the fixme comments, the "should this work?" comments...etc.etc.
Shocking, sort of like catching the pope taking a prozy up the wrong 'un!

yeah, the Q2 code isn't pretty. Not at all. However, to address something I forgot earlier, vertex buffers WERE included in the later patches of Q2. (The latest patch-version I saw was 20 or 21 or somesuch and there were code for vertex buffers in there, I'm pretty sure...At least for the entity drawing code.

EDITED: Yeah, about the vertex buffers.. That's exactly what the original poster wrote, so Nice Going There..I'm DUMB. :-)

Oh well... I'm sure hacking around in that codebase cut two years off my life. :-)

/Henrik




[This message has been edited by CAD_Swede (edited 05-04-2003).]

zen
05-04-2003, 11:48 AM
Allthough I can't remeber q2 very well any more just judging from all the initialization console messages and available info I'd say that q3 should be a little more organized compared to 2.
But still code organization and design has nothing to do with using a function for calculating the distance between two points or using a class hierarchy instead of structures. That's why I hate all that OOP hype. If OOP helps someone organize his code then that's great but C == hack && C++ == well_designed_code is not generally true.



d = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));

should be as clean, readable and well-designed to anyone with really basic algebra knowledge as:



d = dist(x1, x2, y1, y2);
or
d = p1.dist(p2);

or whatever else you can think of. And if it's not you can use a comment or a #define. Not that the other ways are worse, they just aren't better.
Not that all this makes q2 code any cleaner, but still I had to say it.

KuriousOrange
05-04-2003, 12:02 PM
Mmm, yes - I think I know what you're saying...not sure why you're saying it though. Nobody's mentioned OOP.
Seeing as though you bring it up though - I use template classes for my matrices, vectors, and general maths functions. Everything's inline'd, so it's basically more elegant than c macros, but equally as fast.
By the way, your example is pretty funny. If you think the first method is just as readable, then you should take a holiday!
Just inline it away, and then you can use it again!

Zeross
05-04-2003, 12:11 PM
Originally posted by Jan2000:
In some article it was said, that at the beginning of Doom 3 id decided to move on to C++. So Q3 is certainly also coded in C.
I was very surprised about them not using C++ in Q3, but i think it is better to use plain C, instead of a mixture of both.

idīs ftp server? Whatīs the exact url? ftp.id.com had nothing to offer.

Jan.

In fact Doom3 renderer is still coded in C, I've readen it in an interview a long time ago :

Voodoo Extreme -- The game side is C++, why not the rest of the code?

John Carmack -- It's still a possibility, but I am fairly happy with how the internals of the renderer are represented in straight C code.




[This message has been edited by Zeross (edited 05-04-2003).]

KuriousOrange
05-04-2003, 12:29 PM
It's not that the core render code is written in plain c that's the problem (c/c++, don't care - they both support structs), it's because it's so badly written in c that's the problem, and it's GL renderer module is very inefficient.
Anyway, as has been said - at least he got it out the door and made lots of money.

Korval
05-04-2003, 02:29 PM
should be as clean, readable and well-designed to anyone with really basic algebra knowledge as:

First of all, that's just bad coding practice. The distance function should be its own function so that, if you made a mistake in typing it, you only have to fix it in one place (rather than having to hunt it down throughout your entire codebase). And this is for any programming, C, C++, Java, Visual Basic, etc. A programmer who didn't break the distance formula into its own function obviously lacks some sense of code design.

Secondly, there's no way that "sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));" is a clear as "Distance()". At the very least, it takes longer to read the first one. Also, unless there is a comment in front of it, you have to take a moment to realize you're looking at the distance formula (even for the experienced, it takes a moment to recogize it in C). This isn't even a question; it's a fact.

The line "sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));" should have a comment. The line "Distance()" doesn't need one; you know exactly what it does by trivial inspection. A 10-year old understands it as well as an experienced programmer.

[This message has been edited by Korval (edited 05-04-2003).]

GPSnoopy
05-04-2003, 03:41 PM
On their official E3 movie you can see some lines of code of Doom III...

you ought to see some scary "typedef struct { };" construct! http://www.opengl.org/discussion_boards/ubb/eek.gif http://www.opengl.org/discussion_boards/ubb/rolleyes.gif

As far as I can tell Carmack never said he was a good programmers, in fact it's often said that he *is* a bad programmer. But he excels at finding solutions for problems.

But anyway I'm often shocked by the code of other people, it's just that Carmack's code is below average. http://www.opengl.org/discussion_boards/ubb/wink.gif
Hell, when I look at some code I wrote 6 months ago I already want to rewrite it again.

I don't really care how well done are the sources of a program if it works correctly. Unfortunatly you can explain most recurring bugs in Q1/2/3 simply by looking at the quality of the code, it's a bit unfortunate that most of these bugs could have been easily avoided if properly coded.

[This message has been edited by GPSnoopy (edited 05-04-2003).]

Pentagram
05-04-2003, 10:49 PM
Dist is pretty readable if you write it like this



d = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));

but well most of the time it would be more like



x1 = whatever expression to get you the x coord
x2 = whatever expression to get you the second x coord (involving [] -> or .)
....
d = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));


I mean'you can't be serious about this....
(Besides in quake it mostly looks like this)




vec3_t delta;

...
VectorSubtract(blah, bleh, delta);
d = Length(delta);


More readable but still more typing and an extra variable in the body needs to be added. (damn C needs to have them at the beginning of a block http://www.opengl.org/discussion_boards/ubb/biggrin.gif)

Charles

velco
05-05-2003, 12:41 AM
Originally posted by Pentagram:



vec3_t delta;

...
VectorSubtract(blah, bleh, delta);
d = Length(delta);


More readable but still more typing and an extra variable in the body needs to be added. (damn C needs to have them at the beginning of a block http://www.opengl.org/discussion_boards/ubb/biggrin.gif)

Charles[/B]

Yeah, prolly it be much better the C++ compiler to create 7-8 temporaries, eh ?

And before criticizing C, care to learn it ?

~velco

JD
05-05-2003, 01:12 AM
Yup, autos/temps are evil especially in high frequency calls. Making them static is better but they eat up memory. My timings showed 50% speed gain when using statics instead of autos. Anyone else noticed looping in quake1 math functions? Should be unrolled I think.

M/\dm/\n
05-05-2003, 02:08 AM
1st rule: C is generally faster than C++. 2nd rule: OK, OK, the coding style can change a lot, but, look at 1st rule http://www.opengl.org/discussion_boards/ubb/biggrin.gif

OK, enough http://www.opengl.org/discussion_boards/ubb/biggrin.gif 1st thing about quarks, they have been finished http://www.opengl.org/discussion_boards/ubb/biggrin.gif 2nd they were 'best' 3D's of that time. 3rd have you seen Half-Life code?
And finally, syntax could look ugly, but somtimes it just works http://www.opengl.org/discussion_boards/ubb/biggrin.gif and you could have supa-dupa structures through 10 classes game->ogl->bsptree->to->left->bottom->prerender->render that'll have such a hell of overhead that it'll have -1 fps on R9800. The thing I like about classes is that they make code more readable and you can finish + sell that s**t http://www.opengl.org/discussion_boards/ubb/biggrin.gif, though in c you 'can' do that faster http://www.opengl.org/discussion_boards/ubb/biggrin.gif

KuriousOrange
05-05-2003, 02:28 AM
I don't know how it happened, but this suddenly turned into a c vs c++ debate.
How tedious - I thought the contributors to this forum were above that sort of thing.

Ysaneya
05-05-2003, 02:30 AM
1st rule: C is generally faster than C++.


I'd call that "first myth".

Y.

M/\dm/\n
05-05-2003, 03:45 AM
I just wanted to say C++ allows writing programs easier, so eliminating some part of performance oriented style (are you allways thinking about const/dest, copy, etc. functions?), but allowing to finish project faster.
But, fact is, sometimes, non-rational code can run well http://www.opengl.org/discussion_boards/ubb/biggrin.gif
OK, plzzz forget it http://www.opengl.org/discussion_boards/ubb/biggrin.gif

zen
05-05-2003, 05:13 AM
I don't know how it happened, but this suddenly turned into a c vs c++ debate.

I know what happened. I should have never made that damned post. I knew it would turn into that, sorry. What I just wanted to say was that I'm fed up with all the hype about how the only way to write structured code is through C++ and classes. You can break down your app in small chunks which only do specific things with well-defined interfaces in C just as well. And C++ isn't slower than C, how can it be? C++ is a superset of C so you can just use C features if you like. Ok so some features can have a lot of overhead but using C the wrong way can be slow too. Besides not all parts of a program need to be super-fast. Not that I personally like C++,I don't, but still the truth has to be said.
Now about that distance thing. As you said it would take a moment to figure out what it does if you see it in some elses code. So this won't really impair readability if put inside a well defined function. Say if a function calculates the distance of a bounding volume from a frustum plane for culling and only that, then a line like the long one I made the mistake to post would be obvious as to its purpose. On the other hand I've seen enough 600-line I-do-it-all functions where something like that might makes things worse but if you get to that point you've got bigger problems.
So to sum up (and hopefully be done with) what I want to say: There's more to code organization than nice, cute tricks to make the code look more like natural language.

PS:
Is



Matrix.Copy(MatrixA, MatrixB);

so much clearer and easier than



copy_matrix(m1, m2);

Is a class with a bunch of members so much more organized than a source file with a bunch of(nicely prefixed if you want) functions?
I don't know...

KuriousOrange
05-05-2003, 07:29 AM
Errm, well if you're using an IDE (like I do, guess which one http://www.opengl.org/discussion_boards/ubb/smile.gif ), then organising stuff into classes or namespaces helps tremendously. If you're using VI, then I suppose it may be a little annoying toggling between files, but hey it's 2003. Get a mouse!

You've just got to think about other people - the style of coding you're advocating (distinguish functionality by shoving things in separate files, isn't it?) is certainly not one that many people I've worked with would be happy to deal with on a modify/debug basis. You'd certainly have to make your own coffee in the office, I would think!
It's fine to be like that if your code is never going to be touched by anyone else, but otherwise it's just bloody-minded.
I imagine ID softwares new employees would just keep their mouths shut http://www.opengl.org/discussion_boards/ubb/smile.gif

tfpsly
05-05-2003, 09:34 AM
> C vs C++
It should be procedural programming vs OOP, as you can do OOP in C. =P

Please don't think I just want to make a childish point, I'm doing OOP in C in my job, I know it can be a pain in the ass at the beginning.

> C faster that C++
Everyone should have know how stupid this phrase is for ten years.

> If you're using VI, then I suppose it may be
> a little annoying toggling between files,
> but hey it's 2003. Get a mouse!

LOL =)

Ok, seriously, using only keyboard is still faster than switching between the keyboard and the mouse. And vim is really fast at this game.

KuriousOrange
05-05-2003, 11:40 AM
Ok, seriously, using only keyboard is still faster than switching between the keyboard and the mouse. And vim is really fast at this game.

Ho hum, I don't agree. Most of my time is not spent typing, most of it is spent constructing a mental model of the architecture of the application I'm trying to write/debug. An IDE definately helps enormously with this process.

fresh
05-05-2003, 01:15 PM
A lot of you are probably not in the "industry". There's something to be said for knowing how to get things done vs. academia. Carmack knows how to get things done. Who cares if nobody can understand or read it, the point is it works and he made a LOT of money on it. I don't think any gamer cares that he wrote 10 duplicate copies of the distance function versus doing it the "right way" and having a templatized C++ Point class that can do it for you.

Those of you who are anti-globals, anti-goto's, etc have probably never worked on a real project with real deadlines. Sometimes you just gotta get it working and that's the difference between sitting at home being able to spend months on designing a "neat looking" engine with all the latest OOP-isms and shipping a product. There's a hell of lot more to shipping a game than the engine.

Coriolis
05-05-2003, 01:58 PM
I think an even bigger myth than "C is faster than C++" is that "C++ is more readable than C". C is almost always a lot easier to read and learn than C++. There is so much implicit stuff that goes on in C++ that understanding it can be a nightmare. For example,

result = function(a + b);

In C, I can instantly see what this does, and can immediately find the definition of function. In C++, I have to figure out if function is in the global scope or is it a class member? If it is a class member, is it static or not, and is it defined in this method or in a parent? Are there any additional implicit arguments to the function from default arguments? Are there any implicit conversions or overloaded operators in the "a + b" expression? How about in the assignment statement? There could be as many as 4 implicit constructor calls in that simple line of code, not counting any implicit conversions in the called function.

I've worked in the quake3 code base for many years and in the quake1 codebase for an entire project. The q3 code base is a lot better than q1, beyond question. I also had the chance to evaluate the latest Unreal source a while ago as a potential engine to use on a project, and it was nearly impossible to understand anything it did, exactly because of its rampant use of C++. The small sampling I've taken of other industry people I know who've worked in both code bases reveals similar conclusions... the C++ code base tends to be a lot harder to work in.

Doom3 is entirely C++ now, even the renderer. Carmack said this at the last quakecon I believe; the renderer was the last holdout for the longest time.

C++ is not inherently inferior to C, I tend to use it myself instead of C for most code I write, but my C++ code is usually written very similarly to the way I'd write C code so that other programmers (including myself in a few weeks or months) have a chance of understanding it.

KuriousOrange
05-05-2003, 11:51 PM
Oh yes, I agree with you on that one. Overuse of the more exotic extensions in C++ is pretentious and annoying. But 'straight' C++ - in other words, using C++ to give you polymorphism, and only overloading maths operators for maths classes is a gods send, and makes for some beautiful and easy to follow applications.


Those of you who are anti-globals, anti-goto's, etc have probably never worked on a real project with real deadlines. Sometimes you just gotta get it working and that's the difference between sitting at home being able to spend months on designing a "neat looking" engine with all the latest OOP-isms and shipping a product. There's a hell of lot more to shipping a game than the engine.
Sounds like you've been working for some quite short-sighted companies, fresh. Maybe in the last few weeks some globals and goto's may crop up, but not in the fundamentals of the application you're writing. If your company has no intention of re-using the codebase, then goto away! But if you have any desire to cut development time and cost, then you have to think carefully about what you're doing - this probably explains carmacks move to c++ - it forces people to think about what they're doing, to some extent.

Ysaneya
05-06-2003, 12:51 AM
I definately switched to C++ the day i recoded a physics engine i was working on, from C to C++. It was 10 times shorter, the code was much cleaner and simple to understand.

I still remember the days, when coding in C, i was spending hours to find good coding conventions to make things as clear as possible. I recently had a look at my old code, it looked like a nighmare (although at the moment it seemed so nice). Yet, for years i never accepted to code in C++.

To be honnest, i think it's all a matter of habits. When you are used to a language, it's hard to switch to another, unless you are forced to; and that's independantly of pros/cons for the languages. That's just human nature :)

Y.

M/\dm/\n
05-06-2003, 01:01 AM
Yeap, that's right, I thought a bit and realizet that FINALLY http://www.opengl.org/discussion_boards/ubb/biggrin.gif

But if we are talking about habits, will MS force us to use C#?

[This message has been edited by M/\dm/\n (edited 05-06-2003).]

zen
05-06-2003, 01:29 AM
Yes I tend to like those fanatic anti-gotoers myself. Sure using goto for just about every 'jump' in the code can make things pretty bad but what about this:



for(i = 0; i < 10; i++) {
for(j = 0; j < 10; J++) {
if(f(i, j) == 0) goto done;
...
}
}
done:...

Situations like these come along pretty often anti without evil gotos this would look like:



for(i = 0; i < 10; i++) {
for(j = 0; j < 10; J++) {
if(f(i, j) == 0) {
flag = 1;
break;
}
...
}
if(flag)
break;
}

Not that the last version would be that much bad but I consider the first cleaner and neater.
In the end of the day it doesn't matter wether you use C++ or C or gotos but wether you know how to use whatever you're using.And C++ might help you there but only by enforcing one specific coding style. If you like that in language that's fine, I prefer general purpose tools tat give you the choice to decide.

Maj
05-06-2003, 04:44 AM
Originally posted by fresh:
A lot of you are probably not in the "industry". There's something to be said for knowing how to get things done vs. academia. Carmack knows how to get things done.

<rant>

I am in the industry, and I'm really ****ed off with this l33t engine coder attitude that games are somehow exempt from sensible programming practices.

To you it might seem like 'getting it done', but in most cases other people are going to have to debug and extend that code, and they won't have the benefit of all the comments and understanding you've got stored in your head.

I have personally spent *days* on tasks that should have taken half an hour because someone decided that only they needed to understand their code.

Ignoring good practice is not the practical choice.

</rant>

passalis
05-06-2003, 05:30 AM
The problem with C++ and generally OOP is that you need proper planning and time spent in designing before you write the code. I think few in the game industry have extra time to spend. Also even if you design well your engine in the beggining it is possible that later you will have to implement something (like a new special FX) you haven't thought before that will screw completely the OO design.

Anyway, I think carmack writes almost all the engine code himself so he does not need to worry about understanding what the code does. So why whould he bother to write it clean? Moreover the fact that many companies actually buyed that code proves that not only he did a good engine but he also did it fast enough to be ahead of the competition. I guess everyone in the forum given enough time can write a Q3 engine with very good looking code - but by that time Cramck will have finished his Doom4 engine :-)

VikingCoder
05-06-2003, 06:29 AM
Originally posted by passalis:
The problem with C++ and generally OOP is that you need proper planning and time spent in designing before you write the code.

*laughs* So, you're saying there's some other language or technique where you DON'T need proper planning and time spent in designing before you write the code? I'd love to use that language or technique!

This is a rediculous post, passalis. If you're beginning a large project, you always need to plan and design. Always. Ignoring those stages of development is a sure fire way to write garbage code that's completely unmaintanable.

kehziah
05-06-2003, 06:59 AM
I for one find the second part of his post more interesting. A game engine is not likely to be used in industrial plane simulators for 10 years. It is an entertainment product. In this context, shipping the game 4 months before competing products (eg shipping it by Christmas, instead of March the year after) is critical. If so-called bad coding practices can make the difference (especially if the guy codes the entire engine by himslef), then it is ok. Granted, companies that license the engine will spend time (and thus money) to find out what's going on. But that's their problem. If they think it will cost too much, then they pick another engine. Experience seems to indicate that many companies think otherwise.

EG
05-06-2003, 07:00 AM
"Two royal scientific commissions advised the King against backing Columbus because they believed his calculations were incorrect. His request was denied. It was at this time that, when told of the negative answer to his request for an impossible venture that Columbus asked for a hard boiled egg and challenged his interlocutors to try to stand it on end -- which, of course, they could not. He then cracked one end and stood it up. The meaning was clear -- all things are difficult or impossible until you find the solution, then all will follow."

...and many probably found much cleaner and nicer ways to crack the egg, but while they were busy improving egg-cracking technology, where do you think was Columbus going?

http://www.opengl.org/discussion_boards/ubb/wink.gif

dorbie
05-06-2003, 07:11 AM
And while you experts are debating the finer points of his last engine Carmack is off working on his next.

Says it all really.

KuriousOrange
05-06-2003, 08:04 AM
Well, no it doesn't say anything really, dorbie.
He's obviously had this debate before (whether with his imaginary friend or with his fellow programmers), otherwise why do you think he changed to c++?
I think question has to be asked though - would you call the quake engines a success considering they're only used in PC first-person shooters?
Renderware is much better - even though it has it's own problems, at least it has an architecture open enough to allow optimisations for specific platforms. The Quake2 engine (at least, don't know about q3/doom4) seems very rigidly hard coded by comparison.

As I said, this was just a lazy sunday afternoon conversation I wanted to have - but it's tuesday now, so I'm happy to leave it at that.

passalis
05-06-2003, 09:08 AM
VikingCoder you seem to misunderstood my post. Of course designing should be done before the actual writing of the code but in order to use the advantages of OOP you need to spend more time in that. All I am saying is that no matter how well you design it is probable that you will want to implement a feature that you didn't thought off during the designing and may need to take a "shortcut" through the hierarchy chart you have so well designed. This wil result in ugly come that will need even more time to make it look nice.

And don't tell me that every game programmer(s) know exactly what features their engine will finally have. A typical game developement spans for almost 2 years and 2 years are a lot in gaphic hardware terms. Many games were delayed in order to add new features that has been just introduced in hardware and other even changed half of their engine code midway. Take for example quake1. when released it had a software renderer an I think only after some months came the Glide version for the new (at that time) Voodoos. So should carmack have spent more months in the beggining to make a nice OO design for the code when he couldn't even know that there would be a decent 3D graphic card an a new API?

Also about code reusability, many applications need to be very well designed because they will probably survive many years and will be several versions released. Well, usually games don't belong to this group of applications. It is true that some engines will be used in more than one project. but if a company wants a engine that will be used in different games then they should expect that this engine will take more time to develop.

sorry about the long post

GPSnoopy
05-06-2003, 09:42 AM
Nice coding isn't just a gimmic for applications that'll last more than a year or so.
A proper coding style and a good knowledge of your tools (e.g. C++) does cut the developement time.

I mean, most common bugs (e.g. memory leak, buffer overrun, heap corrumption, null pointers, etc...) can be avoided with a good coding style. If more people were correctly using the C++ features and its standard library (the ex-STL) there wouldn't be such bugs (well... almost).
Just think how many bugs are related to C'strings and memory allocation; and most of the time those can be avoided by simply using std::string and std::vector.

Most parts of Quake 2 can be rewritten in C++ in a short amount of time; and they'll be shorter (in lines of code), easier to understand, probably faster, and certainly less buggy. It's a win win situation.

Most people think that a good coding style is useless in practical apps. I was often thinking like that too, but it's just an ignorant attitude.
There is nothing to lose by trying new ways, especially for small projects.

A good coding style isn't just for other people looking at your code, it's firstly for yourself!

[This message has been edited by GPSnoopy (edited 05-06-2003).]

passalis
05-06-2003, 10:11 AM
GPSnoopy, you are right that most bugs in C come from the things you mentioned. But I don't think that you can always say that C++ code is more readable (for the author) than C. It depends. Also I think it is true that whether C or C++ is faster it depends on the compiler and how the coder uses the language.

I personally use a mix between C/C++. The only reason I posted in the first place was because I believe that there is no black and white. The best language to use is the one you are more confortable with, and it will do the job whether it includes ugly or nice code.

kehziah
05-06-2003, 10:28 AM
GPSnoopy, you sure make interesting points, but this thread was about Quake (and other id) engines.

Some people are able to put up well-designed code straight. Some others are quicker at writting "dirty code", with tricks and hacks everywhere.

Assuming that someone writting poorly-designed code (from an aesthetic point of view) is ignorant seems wrong to me.

And it's always easier to design a neat engine when working on things that have already been done. When pioneering in challenging fields such as computer graphics, hard coding some parts can make it easier to experiment and get the whole thing working. If you have time later to improve, rewrite some functionnalities differently, with better software design, that's fine. But from a company's point of view, when the engine is written, tested and running, you won't be allowed to spend extra months to make it look nicer. I hear you : "why not write it with good design in the first place"? I don't know. Maybe that's what is called "iterative developement". The whole cycle can span over several shipped products.

Coriolis
05-06-2003, 02:44 PM
The idea that id throws together engines in a hacky manner because they are disposable is kind of naive. The current code base that id is using for the new DooM started in the code base for quake1, which was begun at the very end of 1994 / start of 1995 if memory serves. A lot has changed, but a lot is the same.

From looking at the difference between the Q1 and Q3 code bases you can tell that id's software is maturing. Jim Dose has had a big influence on the code there, too, from listening to Carmack's talks. In particular, he is the sole reason why id now uses C++. Dose used to work at Ritual; I worked with a lot of his code on my previous project, and it was entirely C++. Annoyingly so, in fact; lots of things were hard to understand and impossible to debug because of it. To be fair the debugging problems were more due to the system design than to the C++ implementation, but it was a system you probably wouldn't think of designing in straight C.

The notion that just hacking things together being acceptible in a game is also naive. The only time this is acceptible is when you have absolutely no other way to meet a milestone, and even then it is sometimes better to slip. Sloppy code almost always ends up costing more development time in the long run, and invariably leads to systems that are more bug-prone and unmodifiable.

passalis
05-06-2003, 03:46 PM
You sounds like you believe that bugs,immature code , etc are a feature only in C programs. Did the commercial applications got generally better since they started using C++? Or before the introduction of C++ there was not any good code in the applications?

Anyway because the post got really away from the purpose of the forum I will attempt to bring it back:

"Do you think that OpenGL should evolve and become an object oriented API like Direct3D? Maybe OGL2 is a good opportunity to do the switch?"

(my personal opinion is that the comparison between D3D and OGL reflects all the advantages and disadvantages of C/C++ programming everyone of us descibed above)

Korval
05-06-2003, 05:04 PM
"Do you think that OpenGL should evolve and become an object oriented API like Direct3D? Maybe OGL2 is a good opportunity to do the switch?"

First of all, the very question itself is loaded. You presume the notion that D3D is more "evolved" than GL. Secondly, you assume this more "evolved" state comes from it's object oriented-ness.

Personally, I don't care too much for the state-based approach of OpenGL. It would be nice for GL2 to take a more object-based approach (and it might even make implementing it easier), but that doesn't require C++. You can write object-oriented code in straight C. Indeed, the first C++ compilers first compiled into C.

And this isn't because I see OOP as something more "evolved" than a state-based approach. It is merely because it more closely mirrors the graphics hardware. You know that changing the state of some object, unless that object is bound to the hardware currently, will not cause undue stalls in the graphics pipe.

Also, with so many types of objects in GL already (program objects, texture objects, buffer objects, display list objects, etc), taking the plunge into an object-based approach doesn't cost anything. Indeed, it's all pretty trivial to have all the functions that set texture parameters take a texture object, rather than having to rely on the currently bound one. It makes the API cleaner.

However, I don't consider it more "evolved". It is simply more... appropriate for the task of graphics these days. The state-based appropach made sense back when GL was originally written. Nowadays, however, it does not.

The difference is that the state-based approach could be faster, because it can more easily read the differences between the previous state and the next one. That way, it only has to change certain state. However, typically, once you change state in hardware, it doesn't matter how much you change; the damage is done. So changing a parameter passed to a vertex program is no worse than swapping out the entire vp (as long as it is resident in video memory).

Coriolis
05-06-2003, 05:40 PM
Extensions would become a nightmare in a C++ model. You can have a dozen people add global functions that take an opaque handle with no problems so long as they behave themselves with their naming conventions. If you get two people to add methods to a class, you're screwed.

Also, tying an API too closely to current hardware implementations rather than to abstract concepts makes evolution of the hardware much more difficult.

Lastly, the state-based approach of OpenGL makes some coding tasks simpler, since you don't have to pass a bunch of handles around or to keep a bunch of globals internally. It also promotes the good practice of doing a bunch of stuff on the current object before switching, since that is more convenient than doing one thing on each object in turn.

OpenGL's approach is simply better suited to the problem.

zeckensack
05-06-2003, 06:06 PM
Funny thread.

OpenGL is the ultimate cross-breed of OOP and efficiency. If you don't see that, you don't want to see it.

Select an object:
glBindTexture(GL_TEXTURE_2D.yipiieh);
Change its state:
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR_MIPMAP_LINEAR);

Would you rather have this?
glChangeState(GL_TEXTURE_2D,yippieh,GL_PARAMETERS, GL_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);

No. If you batch changes to the state of one object together, the first few parameters are redundant. You would want to leave out superfluous parameters on your precious entry points. Which, in consequence, leads you to what OpenGL currently is.

The API couldn't be made any better in its fundamental design concepts.

Bonus flame: there is no design capability in Redmond. Random quotes from the MSDN:
If this bit is set on an active control, it means that the control changes the value of the property whose name is the value of the named property. Otherwise the named property is changed.

If the function succeeds, the return value is ERROR_SUCCESS.

This parameter is not used. Set to zero.

These people know nothing about software design. Or at least they try hard to make the appearance.

Coriolis
05-06-2003, 06:27 PM
My favorite issue in the MSDN is when a function returning an unsigned integer has the comment that "a return value of -1 indicates success". I forget what function I saw that on, though.

Korval
05-06-2003, 06:33 PM
Originally posted by Coriolis:
Extensions would become a nightmare in a C++ model. You can have a dozen people add global functions that take an opaque handle with no problems so long as they behave themselves with their naming conventions. If you get two people to add methods to a class, you're screwed.

I said nothing about C++. As I pointed out, you can implement an object-based methodology in C.

As it stands now, OpenGL has lots of object-based things, but interacting with them requires doing a glBind* and then changing their parameters. This glBind* operation is not guarenteed to be light-weight.

Also, it is changing hardware state to do something that is, for all intents and purposes, client-side. If you happen to be rendering at the time, and you just want to do some setup work for some shaders you will be rendering with later in the frame, you've just inserted a stall in the pipeline for no real reason. The only reason this stall happens is because these objects have to be accessed in a state-based fashion.


Also, tying an API too closely to current hardware implementations rather than to abstract concepts makes evolution of the hardware much more difficult.

On the plus side, it makes current applications faster. That can't be discounted either.


Lastly, the state-based approach of OpenGL makes some coding tasks simpler, since you don't have to pass a bunch of handles around or to keep a bunch of globals internally.

Just because GL won't have a C++ interface doesn't mean that you can't use C++ to get around these, rather trivial, issues.

Yes, you don't have to pass someone an object to allow them to change the texture's state, but, as I pointed out, doing a glBindTexture actually forces an immediate upload of the texture to the card, regardless of whether or not you intend to render with it. If you're only binding it to change a parameter or two... you've murdered your performance for no real reason.


It also promotes the good practice of doing a bunch of stuff on the current object before switching, since that is more convenient than doing one thing on each object in turn.

First of all, why is that "good practice"? Because it happens to be perhaps a bit more cache friendly, depending on the internals of the object in question? As I pointed out, a glBind* can easily induce a stall bubble into your pipeline. As such, doing glBind*'s (which is the only way to change an object's state) is about the best way to kill your performance.

Korval
05-06-2003, 06:51 PM
Originally posted by zeckensack:
Funny thread.

OpenGL is the ultimate cross-breed of OOP and efficiency. If you don't see that, you don't want to see it.

Select an object:
glBindTexture(GL_TEXTURE_2D.yipiieh);
Change its state:
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR_MIPMAP_LINEAR);

[quote]Would you rather have this?
glChangeState(GL_TEXTURE_2D,yippieh,GL_PARAMETERS, GL_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);

Oh, sure, create a really stupid example, rather than making a reasonable one that someone would actually propose. It makes your fallicious argument seem much more rational.

A reasonable way to do an object-based mechanism would be:




glTexParameteri(TexObjName, <standard parameters> );


No need to call the horribly costly glBindTexture call. It just changes some internal state that is local to the texture object. There is no need to change the currently bound texture, and thus induce a stall in both the CPU and GPU, to perform this basic function.


No. If you batch changes to the state of one object together, the first few parameters are redundant.

Yes. Did you know that, every time you call a member function of a class, the compiler silently tacks on a "this" pointer?

Besides the blatent, and intensional, idiocy of your "example" function, you need the texture object if glTexParameter is to function.The way OpenGL works currently is that the functions only act on the currently bound texture object. Because glBindTexture is also bound to uploading the texture, it means that you can't change texture parameters on an unbound object. Thus, you have no choice but to wait until you're actually going to use that object before making any changes to it. This is hardly optimal.

Let's say, I want to iterate through all my textures and turn on anisotropic filtering (because the user just selected it from a menu, perhaps). The GL method forces me to upload each and every texture object I have into video memory, because that's what glBindTexture does. My method, because it only involves changing a few parameters in the texture object (which doesn't change the texture's data), is much faster. Indeed, you can do it without any performance hit at all. You can do it without inducing a stall in the GPU or waiting for the texture to finish uploading.

Lastly, you don't damage the caching mechanism used by drivers. By binding a texture, you announce your intension to use it. As such, the driver, after uploading it, now must say that this texture was recently used. Very recently. You have to run through the vast majority of your textures to apply this change, which means all of them have been recently used. If their caching mechanism is not terribly good, you can page out textures you actually intend to use, in favor of ones that you don't.


Which, in consequence, leads you to what OpenGL currently is.

Alternatively, you stop dreaming up rediculous examples and actually give the other side a fair shake. You might be surprised that you like the alternatives better.


The API couldn't be made any better in its fundamental design concepts.


Bonus flame: there is no design capability in Redmond.

Oh, of course. If you say it, it must be true. I'm sure you've fully explored the other posibilities outside the OpenGL API and, after careful and fair-minded consideration of the alternatives, have settled on this design as optimal http://www.opengl.org/discussion_boards/ubb/rolleyes.gif

Had you actually posted a reasonable alternative, as I did, to state-based code, I wouldn't feel nearly the need for sarcasm.

matt_weird
05-06-2003, 07:07 PM
..err..guys..speaking of high level API: could you also check the topic i've posted in 'High Level APIs', maybe you could help? http://www.opengl.org/discussion_boards/ubb/wink.gif Thank you! http://www.opengl.org/discussion_boards/ubb/smile.gif

Coriolis
05-06-2003, 07:14 PM
Korval:

You're entire page of arguments hinges on the assumption that OpenGL has to upload a texture the instant that a glBindTexture call happens. I don't think that is a valid assumption. Every single case you've mentioned would work just as well if the driver was clever enough to realize that not all cases of binding a texture require it to be uploaded to the card. In fact, there's no reason to assume that the driver does any uploading of the texture to the card until the next vertex is given to OpenGL.

I will grant you that a naive driver implementation in your proposed model would be better than a naive driver implementation in the current OpenGL model, but that's all you've managed to show.

tfpsly
05-06-2003, 10:52 PM
Originally posted by KuriousOrange:
Renderware is much better - even though it has it's own problems, at least it has an architecture open enough to allow optimisations for specific platforms.

Ok, Renderware can be a nice toy if you want a simple rendering engine (one texture, 2 at max, per object; basic per vertex lighting model; very simple shadow map rendering), but as soon as you want some spetial fx, you'll need to code platform specific code (which we're doing where I'm working, for multitexturing, nice shadows that are casted properly, and the like).

rgpc
05-06-2003, 10:54 PM
Originally posted by zeckensack:
Bonus flame: there is no design...

Don't forget "To shut down your PC, click the START button".

KuriousOrange
05-06-2003, 11:40 PM
Originally posted by tfpsly:
but as soon as you want some spetial fx, you'll need to code platform specific code
Well, yes - that was my point - you are free to do that without hacking around in bsp traversal source code.
Bear in mind that renderware is taking care of the rendering/collision for some of the best games around on the consoles (gta3 and the burnout series to name a couple).

zeckensack
05-07-2003, 04:51 AM
Korval, let's make a habit out of this "I throw a blatant statement on the floor. You tell me I'm wrong" thing. Makes these forums much more spicey http://www.opengl.org/discussion_boards/ubb/smile.gif



glTexParameteri(TexObjName, <standard parameters> );
<HR></BLOCKQUOTE>Whis is pretty much the OpenGL design. Or is it not?
OpenGL gives you 'object selection' in place of the this pointer. There is no difference between these two concepts, really. A naive implementation of object selection might even look like this:

class
Object {...};

Object* current_object=NULL;

APIENTRY void
BindObject(int selector)
{
current_object=(Object*)selector;
}

APIENTRY void
ChangeObjectState(int value)
{
current_object->change_state(value);
}

What was it, that you are arguing about?



No need to call the horribly costly glBindTexture call. It just changes some internal state that is local to the texture object. There is no need to change the currently bound texture, and thus induce a stall in both the CPU and GPU, to perform this basic function.You would change state of a texture you're not going to render? Okay, during level load time and similar occasions this is a good thing to get everything prepared.
But I digress, changing texture state will not cause a quality driver to instantly stall. Nor will just binding a texture, flipping a bit, and then rebinding the texture that was last used for actual rendering, if you're into that sort of thing.

Trust me, I've written something that might be called a "graphics driver". There are ways around this that are simple enough that I really cannot imagine the 'big guys' haven't found them.


Yes. Did you know that, every time you call a member function of a class, the compiler silently tacks on a "this" pointer?I knew that, thanks. I don't know exactly how this is meant to relate here. But it makes a good introduction for my next point:
You don't funnel a this pointer through an API entry. Every time this pointer is used, it must be checked for validity if you don't want to risk your driver going down due to an app error. Object selection allows this check to be performed during binds, and can guarantee that the 'internal' this pointer is always valid. Saves a fair bit of overhead from the state modifying functions. Nice, huh? I'm glad to see that your proposal handles this right.


Besides the blatent, and intensional, idiocy of your "example" function, you need the texture object if glTexParameter is to function.The way OpenGL works currently is that the functions only act on the currently bound texture object. Because glBindTexture is also bound to uploading the texture, it means that you can't change texture parameters on an unbound object. Thus, you have no choice but to wait until you're actually going to use that object before making any changes to it. This is hardly optimal.You state that binding causes uploading. That's just as blatant a claim as my initial post.
I'll give you the benefit of doubt, you probably meant a flush. Would be nice if you could actually say whether you've benchmarked that. This is hardly a design flaw of OpenGL, if it's really the case. Implementations don't need to do this and indeed they shouldn't.
I'm with Coriolis on this one, and if I may say so, I've done it myself and it performs nicely.


Let's say, I want to iterate through all my textures and turn on anisotropic filtering (because the user just selected it from a menu, perhaps). The GL method forces me to upload each and every texture object I have into video memory, because that's what glBindTexture does. My method, because it only involves changing a few parameters in the texture object (which doesn't change the texture's data), is much faster. Indeed, you can do it without any performance hit at all. You can do it without inducing a stall in the GPU or waiting for the texture to finish uploading.I believe everything's been said above. There's no fundamental difference between 'your' design and OpenGL design. If your design can avoid this problem, an OpenGL implementation can as well.

Lastly, you don't damage the caching mechanism used by drivers. By binding a texture, you announce your intension to use it. As such, the driver, after uploading it, now must say that this texture was recently used. Very recently. You have to run through the vast majority of your textures to apply this change, which means all of them have been recently used. If their caching mechanism is not terribly good, you can page out textures you actually intend to use, in favor of ones that you don't.No. See above.


Alternatively, you stop dreaming up rediculous examples and actually give the other side a fair shake. You might be surprised that you like the alternatives better.
Oh, of course. If you say it, it must be true. I'm sure you've fully explored the other posibilities outside the OpenGL API and, after careful and fair-minded consideration of the alternatives, have settled on this design as optimal http://www.opengl.org/discussion_boards/ubb/rolleyes.gifI've seen my fair share of DirectX (I'm using the version 5 Interfaces for sound and input; I've looked at D3D6; and I've used D3D7 and 8). D3D7 is actually a nice target for my more outlandish work. I also know the strengths (and weaknesses) of D3D8's vendor neutral shading. But wasn't this about OOP? If anything Direct3D is OOP, OpenGL is, too, you bet. Filling a structure with function pointers to be used with the '->' operator has nothing to with OOP.
If you're so inclined, get a recent DDK and look at what Direct3D really is (look for the 'thunk layer').

Had you actually posted a reasonable alternative, as I did, to state-based code, I wouldn't feel nearly the need for sarcasm.Korval, I know you're a clever chap and I have nothing against you personally. I've applied brevity and harshness as I did in the other thread (you sure know which one I mean), because I had hoped that I'm understood anyway and might get away with it. Now I get the feeling you 'hunt' me here, in part because you've hunted me there.
I must admit that my willingness for giving thorough explanation of (what are IMO) obvious things isn't what it used to be right now, and you make me feel sorry for it. But really, there's no need for getting generally mad at me.

[This message has been edited by zeckensack (edited 05-07-2003).]

KuriousOrange
05-07-2003, 05:05 AM
!uhhumm!
Sorry, I was just clearing my throat.
http://www.opengl.org/discussion_boards/ubb/smile.gif

passalis
05-07-2003, 05:23 AM
I knew it was easy to shift this post to a more OpenGL-related subject :-)

Just another remark about OpenGL. The current iplementation (state machine) is much-much better in terms of teaching for begginers. I think it is easier to teach the basics of opengl than messing with direct3d. I was an assistant to a opengl course and it wasn't that bad even though most students weren't good on C (let alone C++). I guess it would be a nightmare to do the same for D3D.

I am using DX for sound and input and I just hate the fact that in order to call the simplest function I have to fill a stupid stuct with parameters that won't be eventually used.

Korval
05-07-2003, 08:47 AM
But I digress, changing texture state will not cause a quality driver to instantly stall. Nor will just binding a texture, flipping a bit, and then rebinding the texture that was last used for actual rendering, if you're into that sort of thing.

Go ahead. Try it out.

From what Cass/Matt have mentioned in the past about how state changes are handled, they seem to flip some bit whenever you make a state change (like binding a texture). Now, when a glBegin, or glBegin-equivalent function, occurs, they check the modified bit for that particular state. If it is set, then they will re-upload the texture state for that object. Why? Because downloading the current hardware state and comparing it with the current texture object is slow. Therefore, they will check their modified bit, and if it's set, they have to upload the new texture state.

Do some performance tests where you glBind a texture, then bind the previous one several thousand times per frame.


You state that binding causes uploading. That's just as blatant a claim as my initial post.

Maybe, but mine also has the remote possibility of being true.


There's no fundamental difference between 'your' design and OpenGL design.

The fundamental difference is that there is no "global" state that can be acted upon; only object. Objects can be bound and rendering can occur, but functions that alter the state of objects really do need to take the object as a parameter. As such, you don't get into the problem of multiple glBind*'s for the purpose of simply changing the state of the object.

From a semantic point of view, it is not a good architecture either. The concept of a glBind* is to take the object data and attach it, in some way, to the rendering system so that it can be used. To have glBind* be used simply so that you can change the state of a free-standing object is silly.

Lastly, it's easier to write an implementation of an object-based system than a state-based one. Those "texture objects" that glGenTextures generates could be first-class pointers to some C++ object that the driver defines. So, when you say, glTexParameter*(texObj, etc), the implementation can just take texObj, cast it to the appropriate, driver-specific type, and use it as needed. And a glBindTexture call actually does do the upload/etc.

A state-based system has to have some global pointer to the current object. Then, it has to have a modified bit so that it can tell whether or not to upload it at a glBegin*. Then, every function that is a glBegin-equivalent call (glDraw*, etc) must now check all of these modified bits and upload state as appropriate.

Sure, nowadays, this point isn't that much of an issue, when people already have implementations of OpenGL written that are made to function in this capacity. However, writing these was not trivial. And there are many low-end video cards that have no GL support because the company that makes them can't devote the resources to writing a full-fledged implementation. Also, with GL2 possibly arriving (though with new ARB extensions, it makes little actual sense), we have even more that an implementation writer has to accomplish.


I've seen my fair share of DirectX (I'm using the version 5 Interfaces for sound and input; I've looked at D3D6; and I've used D3D7 and 8).

Is your thinking limitted to only D3D and OpenGL? It's easy enough to design a better API than GL from first principles.



The current iplementation (state machine) is much-much better in terms of teaching for begginers.

It's been a long time since I was a beginner. Indeed, it's been a long time since most experienced GL programmers were beginners. I'm not advocating making the API needlessly obtuse to the neophyte GL programmer, but making the API grow with you wouldn't hurt.

KuriousOrange
05-07-2003, 11:13 AM
No, no, no, no - leave the API as it is.
One of the major advantages OpenGL has over Direct3d is that it is consistent.
It works, and it works well. Leave-it-alone.

Michael Steinberg
05-07-2003, 12:20 PM
I've seen people quotion code like:



v1 = v2.dot(v4);

or

m2.copy(m1);


Now where would that be good c++ design anyways?
An operation like = (which should be copy after all, shouldn't it?) and + is not the property of an item of a set, it's how the set defines operations on the items. Thus the only logical way anyways is to create friend functions in the same namespace.

Example:




float whatever = lin_alg::dot_product( v1, v2 );


This not only makes more sense seen for a mathematical POV, it also helps to avoid unnecessary fat interfaces to types.
Temporaries can be cut down big deal with lazy evaluation and all that, especially for big types like matrices. Those technuiques also can be "hidden" to the one who uses the lib. And never underestimate what the compiler can do for you.

(Note that i didnt flame on c vs. c++, im proud of that http://www.opengl.org/discussion_boards/ubb/biggrin.gif )

knackered
05-07-2003, 11:26 PM
Michael Steinberg,
corr! now there's a blast from the past... http://www.opengl.org/discussion_boards/ubb/smile.gif

fresh
05-08-2003, 09:58 AM
Sounds like you've been working for some quite short-sighted companies, fresh. Maybe in the last few weeks some globals and goto's may crop up, but not in the fundamentals of the application you're writing. If your company has no intention of re-using the codebase, then goto away! But if you have any desire to cut development time and cost, then you have to think carefully about what you're doing - this probably explains carmacks move to c++ - it forces people to think about what they're doing, to some extent.

Yes I've worked for some short sighted companies and some way better ones (like my current employer). Our engine is very flexible, very C++ (with bits of assembly here and there) and we even license it out. I'm just saying that using goto's or globals isnt the end of the world. Whenever we get fresh out of university people here, the first thing they do is write a templatized, operator overloaded vector/math library *puke*. When am I ever gonna use a double or a char for a vector? And why is "A.add(B)" so much more difficult than "A=A+B". We use "C with extensions". We use some templates, single inheritance only, and very very rare instances of operator overloading. Makes for a clean engine. After working at several places, this is definitely by far the most well designed engine I've had the pleasure of working on.

oliii
05-09-2003, 04:15 PM
Flame Wars! Burn the Witches!Burn 'em!

Oh well, with the current machines nowadays, I'd rather have a module that is 10% slower but 70% easier to debug. Time is money, and time is very short indeed for game developers. Anyway, as usual, when there is a will, there is a way. There are ways to make C code maintainable (are there? hmmm....), and C++ code efficient. It's all a matter of opinion and standards. Personnaly, I hate looking at other people's code, and for sure, our engine coders'd better be using C++, because they have no time to document it, and I have no time to bust my head open trying to understand what all his code was on about.

I'd advocate for a nice modular design, with an abstract class to access modules. For the rest, he can as well code the guts of his code in Java, as long as it is suppose to do what it is suppose to do. If it doesn't work, I won't be the one responsible for debugging his mess.

As far as I'm concerned, I always try to make the code as clear as possible, and then optimise the core routines. Basically, there is no need to make an interface as obfuscated as possible, just to gain an extra clock cycle. I remember one of our engine coder who created an abstract layer around the whole physics. Really really nice, and the drop in performance was negligeable. Besides, he could work on his physics without ever touching the rest of the code. It was actually released to us as a stand-alone library. On the other hand, the renderer coder was an old-skool C kind of guy, and his render class was 4 pages long, with platform specific functions and mind bending dependencies, and more statics than a busted TV set.

Now, I'm working at another company, and the nightmare continues. I haven't seen a design doc or a schedule so far, it's total anarchy. The code looks like a mess, although the engine guys do their best. We are constantly fighting for 3000 lines files, the executable is over 4 megs (statics all over the place), and we have 4 month before release, with bugs crawling all over the place. How we gonna pull it off, I don't know.

I've had a look at the quake3 point release source code, and it does seems sensible after what I've been working with. And that's pure C. Bad C++ code design is a crime. Besides, I much prefer using OpenGL than the rubbish COM interface for DirectX. Although, OpenGL with a nice C++ layer...

Obli
05-12-2003, 06:55 AM
Excuse me if I interrupt your discussion.

Looks like someone there knows a bit of D3D. I would also learn a bit of it, can someone point me to some nice documents which are not "google"? Something you already checked out and raccomand, even a printed book to buy, something.
Just for fun (and to have a wider vision of 3D APIs) since I guess I'll need it.
Thanks!

blender
05-12-2003, 08:36 AM
Who's using goto:s? Don't you think that using goto:s in c/c++ code is a sign of a really bad design. IMHO goto should not even exist.