Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

RobTheBloke

Member Since 22 Jun 2002
Offline Last Active Yesterday, 07:32 PM
*****

#5064728 C++ create an array of nested class objects in a class

Posted by RobTheBloke on Yesterday, 03:50 AM

That's great ta:

Firstly I was just trying to encapsulate the code as it seemed the natural progression if I were creating objects in objects. Is it wrong to try this kind of nesting? Would I be better off just creating a separate class?

 

I tend to use nested classes in cases where the classes never need to be accessed publicly (i.e. they are only used in private areas of a class). It's just a stylistic thing really, and there's no real problem doing either.

 

Secondly I was trying to avoid vectors as I thought that you couldn't save them in .bin files. only vars and arrays! Is that a falsehood?

 

 

#include <cstdio>
 
void save(std::FILE* fp, const std::vector<cTroupObj>& objs)
{
 uint32_t num = objs.size();
 std::fwrite(&num, 1, sizeoff(uint32_t), fp);
 if(objs.size()) //< important! (otherwise you'll hit NULL if empty)
 {
    std::fwrite(&objs[0], objs.size(), sizeof(cTroupObj), fp);
 }
}
 
void load(std::FILE* fp, std::vector<cTroupObj>& objs)
{
 uint32_t num = objs.size();
 std::fread(&num, 1, sizeoff(uint32_t), fp);
 objs.resize(num);
 if(objs.size()) //< important! (otherwise you'll hit NULL if empty)
 {
    std::fread(&objs[0], objs.size(), sizeof(cTroupObj), fp);
 }
}



#5064641 C++ create an array of nested class objects in a class

Posted by RobTheBloke on 24 May 2013 - 05:47 PM

It looks as though you're trying to create a horrific mashup between a freelist and a monostate? There are reasons why I could see it being useful in some high performance contexts, or some really underpowered architectures, but I suspect this will end badly in this case (static variables are just globals, and that's usually always a bad idea). The biggest problem you'll face is that you're going to implicitly tie together the implementations of a few classes, and code reuse will go flying out the window. But anyway.... 

 

The easiest way would be like this:

 
#include <vector>
 
class cTroops
{
public:
 
  class cTroopObj
  {
    friend class cTroops;
    cTroopObj(int type /* add more construction args if needed */ ) 
      : miType(type), miHealth(100) /* initialise remaining member vars here */ { }
    ~cTroopObj() {}
  public:
 
    /* member funcs here */
 
  private:
    int miType,
      miHealth,
      miRally,
      miSpeed,
      miXloc,
      miYloc,
      miZloc;
  };
 
  cTroups() : m_troups() {}

  void addTroup(int type /* more args if needed */) 
  {
    m_troups.push_back( cTroopObj(type /* more args if needed */) );
  }
 
  void removeTroup(size_t index)
  {
    m_troups.erase(m_troups.begin() + index);
  }
 
  cTroopObj& operator [] (size_t index) 
  {
    return m_troups[index];
  }
 
  const cTroopObj& operator [] (size_t index) const 
  {
    return m_troups[index];
  }
 
  size_t size() const 
  {
    return m_troups.size();
  }
 
private:
  std::vector<cTroopObj> m_troups;
};
 
// to use ....
cTroups troups;
 
troups.addTroup( 1 );
troups.addTroup( 2 );
troups.addTroup( 3 );
 
for(size_t i = 0; i < troups.size(); ++i)
{
  troups[i].someMemberFuncOrWhatever();
}
troups.removeTroup( 0 ); // remove first troup
 
// remaining troups will be destroyed when troups goes out of scope

 

/edit what the hell is wrong with gamedev? Why are tabs being stripped from everything?
/edit3 And newlines as well? WTF????
/edit7094  Ok, so code tags strip tabs and spaces. Source tags strip newlines. Wut?

/edit7075 F**k it. Have the screwed version.




#5062302 Something somewhere screwed up my co-ordinate system

Posted by RobTheBloke on 16 May 2013 - 09:48 AM

The problem here is that in order to make the movable objects show up properly I need to invert the x and z axis.

If you need to invert 2 axes, it means you're performing a 180 degree rotation (around Y in this case), and not a coordinate system change. That might be accounting for the confusion possibly?




#5061785 COLLADA or FBX?

Posted by RobTheBloke on 14 May 2013 - 08:22 AM

But what problem has COLLADA?



There is only really one flaw. It attempts to write data into 'common profiles', and also allows 'custom profiles'. The theory is that anything you write into the common profile will work with all packages. In practice, what actually happens is that a lot of exporters simply dump data into a custom profile instead. This can lead to a number of if(max) elif(maya) elif(xsi) code constructs.

It's not really a deal killer though - it's just something you might encounter if you need to support mroe than one of: Max/XSI/Maya/Houdini.

FBX is the clear winner and for a very good reason: It supports inspecting a scene at any given time within an animation.



That argument is a fallacy. The question here is which data transfer protocol is most useful for the OP. Being able to evaluate animation and geometry deformations does not help you transfer data, it's just another feature that you won't be using within your game.

At run-time you want to perform only linear interpolation between key frames, as linear interpolation is the fastest.
In practice, there are many ways to perform interpolations between key frames, but using the FBX SDK you can create a
run-time system that only uses linear interpolation.



No. At the very minimum you want to use normalised linear interpolation for rotations, and linear interpolation for everything else.

Basically you run through an animation and set a bunch of key-frames, then you eliminate any key frames that don’t change the result if linearly interpolating between the 2 key-frames around it.



That's one of the worst compression schemes available for runtime animation systems. It fails to provide any random access capabilities at all, so you'll be forced to utilise precious memory bandwidth to find the correct keys. It simply won't scale.

The FBX SDK will generate all the values for each track considering each interpolation mode for you, so with the FBX SDK it is very easy to handle efficient animations and key-frame reduction.



As will Maya, Max, Xsi, Motionbuilder, Endorphin, Morpheme, Houdini, and even blender. That kind of processing is best left to the artists. Doing it at the asset packaging stage is only going to introduce animation accuracy glitches that will only appear within the game. Taking the control of anything away from the artists is always a bad idea imho.

I’ve worked with FBX for years, I have encountered no bugs, I am not displeased



Appeal to authority fallacy.

I've worked with FBX for years, and I think it's a horribly broken system that requires far too much hand holding from animators to make it work reliably.

By far the biggest problem with FBX is the excessive number of memory allocations the SDK utilises when performing interpolation internally (pretty much one alloc per float-key). It's just about ok to sample the keys from a single character, but if you have multiple characters & takes within an FBX, then you will have to start jumping through numerous hoops to keep the number of allocations within check (as in, you will be writing a custom memory allocator for the library, usually followed up by an extremely unhelpful chat with the Autodesk devs).
 
The second related problem, is that FBX has a notorious failure rate as soon as you start using secondary animation generated from expressions / constraints / IK rigs / etc. Now, if you've never seen it go wrong, you're ether not doing anything that complicated with it, or you're working with a bunch of artists who know how to correctly bake out their animations before export. If you are simply exporting characters from Maya or XSI, FBX will fail more often than not. I'd go so far as to say that most animation/rig import problems I saw when working on morpheme, were as a direct result of FBX.

Collada has pros and cons.
FBX has pros and cons.
dotXSI has pros and cons.

Evaluate them all yourself, and choose the one that works best for your project. They're all crap in one way or another, so don't spend too much time worrying about the right choice....
 


#5061550 COLLADA or FBX?

Posted by RobTheBloke on 13 May 2013 - 10:50 AM

I'd really use Assimp for this. They're both a mess, and vary from the modeling packages you use to export them.. Assimp will make your life easier in every way and will probably increase the odds you get something reliable working.

 

That's just a collada problem primarily - and assimp won't make that problem disappear.




#5061528 COLLADA or FBX?

Posted by RobTheBloke on 13 May 2013 - 09:13 AM

Neither and both. Evaluate the API interfaces and choose the one that seems most sane to you.




#5060868 Looking for a tutorial on how to make a plugin for 3DS Max or Wings 3D

Posted by RobTheBloke on 10 May 2013 - 08:47 AM

3DS Max is a particularly unpleasant API to work with (as in, literally the worst API ever invented!). There is a fairly decent source code example to be found in the devkit (I can't remember the name of it, but you should be able to find it fairly quickly). Effectively you have a hierarchy of INodes, and any given INode may have some geometry objects associated with it. You then call EvalWorldState to bake the modifier stack into a bunch of triangles (which you can then extract). If you need skinning (or any other deformation) data, then you'll need to use an IDerivedObject to iterate over the modifiers in the modifier stack.

To get the actual transform data from the INodes, simple get the object TM after world space modification. You'll need to decompose the world space transforms into pos/quat/scale manually (which can be annoying). To be perfectly honest though, you'd make life much easier for yourself if you just used collada instead.

 

p.s. an exporter tutorial for maya




#5059322 normals in tangent space question

Posted by RobTheBloke on 04 May 2013 - 06:59 PM

you don't make normals in tangent space, you just make normals. The tangent, bi-normal, and normal, make up the TBN 3x3 rotation matrix which is used to transform light rays into the coordinate system of your texture. The tangent & bi-normal therefore represent the u & v directions of your texture (which you can deduce by inspecting the texture coordinates). 




#5058046 Recursive functions - code critique?

Posted by RobTheBloke on 30 April 2013 - 06:53 AM

Why do you hate int so much - because it can be different on different systems?

I just prefer the standard sized ints - a uint64_t requires less brain power than unsigned long long...
 

 

And why did you remove the namespace - is it because you think there may arise a problem with identifiers mismatch?

'using namespace std' is plain lazy. Removing any namespace makes life a little trickier if you need to move code between cpp & header files (and it's just sloppy technique). Doing something like this is better (although I personally find it a bit annoying):

 

namespace MyAnimLib
{
using MyMathLib::Vec3;
};

 

 

I guess the main points are that I should have passed vector by reference rather than using a global(I guess I should have done this but seeing as it's a really small app I guess I just didn't bother - though I guess it's good practice to get used to not declaring globals when they are not really needed) and giving more descriptive names to my variables/functions etc.

Globals are fixed points in code. Any code that uses *any* globals is a bitch to maintain and refactor.

 

And why exactly do you use camel case for everything?


Just function names and variables. Most people tend to use PascalCase for classes. It just makes it easier to see which identifiers are types, and which are variables/function calls. Is the following a function call, or a call to a constructor? It's difficult to tell if PascalCase is used everywhere...

foo = FibNumber(1);

 

I'm using them to keep my console up.

I can see the reason for it, but in VC++, you can keep it open by just running the program (instead of debugging it). the sync/ignore doesn't really add anything imho (and stuff like that can easily be forgotten, causing untold annoyances and extra debugging later on....)
 




#5058027 Recursive functions - code critique?

Posted by RobTheBloke on 30 April 2013 - 04:56 AM

#include <iostream>
#include <vector>
#include <cstdint> //< I cringe when I see 'int'...

// using namespace std; //< UGH! keep the namespace imho.

int32_t computeFibonacciNumber(int32_t); //< camel case

// Recursive functions  //< a crap comment. I don't need to know this to use it.
void constructFibonacciArray(std::vector<int32_t>& inputArray, int32_t index); //< descriptive function names
void writeIntArray(const std::vector<int32_t>& array);

int main()
{
    int32_t fibIndex = 0;
    std::vector<int32_t> fibArray; //< globals are bad M'KAY!

    std::cout << "Enter an index for the Fibonacci number you want: ";
    std::cin >> fibIndex;

    std::cout << "Here's the number at that FibIndex: " << getFibNumber(fibIndex) << std::endl;

    std::cout << "Enter the index up to where you want the Fibonacci numbers: ";
    std::cin >> FibIndex;

    std::cout << "Here're the first " << (fibIndex + 1) << " Fibonacci numbers: " << std::endl;

    arrayFib(fibArray, fibIndex);

    writeIntArray(fibArray);

    return 0;
}

int32_t computeFibonacciNumber(int32_t index)
{
    if(index < 2)
    {
        return index;
    }

    // no need for else here

    return computeFibonacciNumber(index - 2) + computeFibonacciNumber(index - 1);
}

void constructFibonacciArray(std::vector<int32_t>& inputArray, int32_t index)
{
    switch(index)
    {
    case 0:
        inputArray.push_back(0);
        break;

    case 1:
        inputArray.push_back(0);
        inputArray.push_back(1);
        break;

    default:
        // Recursion
        constructFibonacciArray(inputArray, index - 1);
        inputArray.push_back(inputArray[index - 2] + inputArray[index - 1]);
        break;
    }
}

void writeIntArray(const std::vector<int32_t>& array)
{
    if(array.size())
    {
        std::cout << array[0];
        for(size_t i = 1, n = array.size(); i != n; ++i)
        {
            std::cout << ", " << array[i];
        }
        std::cout << " The End!" << std::endl; //< pointless cruft.
    }
}



#5056138 Starting without wanting to find a job

Posted by RobTheBloke on 23 April 2013 - 12:54 PM

I could never focus while at school, and though I got A's and B's, I was always thinking about development, engines and games.


Then go back to school, and get more A's and B's.

Last minute assignments and high grades.


Then blagging your way through A-Level's and a degree will be easier for you than for other people.

I know alot about how games work, how engines work, know JavaScript and core programming concepts like variables and functions. I am also skilled at Hardware and PC's.


But how's your knowledge of Lagrangian mechanics? Poisson distributions? Standard deviation? The rules of integration and differentiation? Pipelined architectures? Data structures? Computational efficiency? BN notation? Colour theory? The physics behind lenses? Mutexs? Locks? Lock-free code? SIMD? Solutions to sparse matrices? Can you dervie the equations to convert a quaternion to a matrix from scratch?

You know, the stuff you're forced to learn in univeristy and A-Levels?

I have bought Accelerated C++ (understanding it well enough so far) and begun learning the language, gathered people I can trust and are enthusiastic about game development too, some are coders, others are interested in modelling or sound.


Well that's great, but can you learn from them? I'm sure you'll all be able to learn the basics together, however that's very different from being taught by, or working with, people with bucket loads of experience. You'll learn far more, at a much quicker pace, than you ever will in a group of beginners.
 

Is it necessary to attend college, to finish Year 12 in order to be successful in the Games Industry as an independent developer?



Most companies have HR departments that filter CV's before they get put infront of the team leads. The filters they use are rudimentary, and mainly involve the question: "Do they have a degree?". If the answer is no, it will be binned.
The ONLY people in the games industry who've made it without a degree, are those individuals who made a name for themselves. For example, I know one guy who was hired as a developer on 3ds Max when he was 16, because for the 3 years prior, he'd been publishing and releasing plug-ins for 3ds Max that were better than the ones written by Autodesk, so they offered him a job. So yes it's possible to make it without a degree, but only if someone is already offering to hire you. Otherwise, no chance.

Can you succeed with a clear idea, skill and unlimited time?


Yes, however you do not have unlimited time, so the answer will always be no. Simple fact is, if you are not studying, you will need to find work sooner or later. Once you start working 40 hours a week, you really won't have anywhere near enough time to spend learning games programming. You'll then be competing against a load of students who can devote every hour, of every day, to doing nothing but learning about games programming. In 5 years time, they'll know a hell of a lot more than you, and their degree will get them through the first HR recruitment hurdle.

Education is what you make of it, and the more you put into it, the more you'll get out. Yes G.C.S.E. and A levels are a bit tedious, but at university, things get a lot more flexible. If you are doing a CS degree, but want to learn more about maths, it's easy to ask a tutor from the maths dept if you can sit in the back of their lectures, and they usually say yes. Learn as much as you can, from as many people as you can, and then getting a job in the industry will be easy. If you simply try to learn everything yourself, you'll just avoid learning the most useful information, and instead end up picking up a lot of bad habits. Go to university. It is worth it in the end....
 


#5056022 Loading textures in another thread & reserving memory

Posted by RobTheBloke on 23 April 2013 - 07:23 AM

But maybe OpenGL (3.x) also has special functions for smoothly loading texture data nowadays?

Nope.

But instead of throwing them away, I could also put new textures in unused "slots" (if the resolution / format equals of course). Is that useful?

Not really. Instead of issuing a glDeleteTextures + glGenTextures + glTexture2d, you could just issue a glTexture2d call to resize the currently bound texture. This may help in some minor edge cases, but in the bigger scheme of things, it's unlikely to make a difference. If anything, keeping the symmetry in your code (i.e. create/destroy) will make the code easier to maintain.

The same question for VBO's.

glBufferData if you need to rezise the buffer, otherwise keep the symmetry to keep the code clean.




#5053111 Academia

Posted by RobTheBloke on 14 April 2013 - 05:17 AM

o god, that's horrid, and so incredibly inefficient, I don't even know.

It was all like that, but his exam marking was his worst offence. He'd often fail 50% of a year group, and barely pass the rest. All because he had absolutely no clue. If the students had me as a second marker, they were lucky. Some other 2nd markers weren't as diligant though :(
 

Why do you need to name your class fields as c, cc, d, e? What the hell are you trying to obfuscate?

 

Most lecturers are generally pretty level headed, and do try to keep their code clean and readable. The more research based they are however, the more chance there is for strangeness to creep in. Academic research can be quite an isolating experience, so you don't often have people around to bounce ideas off, which does tend to encourage people to slip into some really bizarre habits.

 

There is also a tendancy for some senior academics to stick their name on top any paper from any student they are supervising. This experience can make a junior researcher quite paranoid, and overly protective of their work. Once they've got a Phd, often this paranoia doesn't leave the academic, but simply becomes much more engrained. Maintaining secrecy, and deliberately obfuscating code, is not uncommon in the academic world as a result..... 




#5053095 Academia

Posted by RobTheBloke on 14 April 2013 - 04:41 AM

I was a demonstrator / lecturer for a few years, and had to demonstrate for one particularly terrible lecturer. Most of his code was so far beyond bad it simply wasn't funny. The one code example he gave to students that sticks out most, was his OBJ loading & rendering code. I've ommitted support for the normals and UVs, but I think you get the idea.....

struct Vertex
{
   int index;
   float x;
   float y;
   float z;
   Vertex* next;
};
float getX(Vertex* head, int index)
{
   Vertex* p = head;
   while(p)
   {
      if(p->index == index)
         return p->x;
      p = p->next;
   }
   return 0;
}
float getY(Vertex* head, int index)
{
   Vertex* p = head;
   while(p)
   {
      if(p->index == index)
         return p->y;
      p = p->next;
   }
   return 0;
}
float getZ(Vertex* head, int index)
{
   Vertex* p = head;
   while(p)
   {
      if(p->index == index)
         return p->z;
      p = p->next;
   }
   return 0;
}
struct Face
{
   int index;
   int i0;
   int i1;
   int i2;
   Face* next;
};
int getV0(Face* head, int index)
{
   Face* f = head;
   while(f)
   {
      if(f->index == index)
         return f->i0;
      f = f->next;
   }
   return 0;
}
int getV1(Face* head, int index)
{
   Face* f = head;
   while(f)
   {
      if(f->index == index)
         return f->i1;
      f = f->next;
   }
   return 0;
}
int getV2(Face* head, int index)
{
   Face* f = head;
   while(f)
   {
      if(f->index == index)
         return f->i2;
      f = f->next;
   }
   return 0;
}
void drawMesh(Face* f, Vertex* v, int n)
{
   glBegin(GL_TRIANGLES);
   for(int i=0;i<n;++i)
   {
       glVertex3f(getX(getV0(f,i)), getY(getV0(f,i)), getZ(getV0(f,i)));
       glVertex3f(getX(getV1(f,i)), getY(getV1(f,i)), getZ(getV1(f,i)));
       glVertex3f(getX(getV2(f,i)), getY(getV2(f,i)), getZ(getV2(f,i)));
   }
   glEnd();
}



#5050146 Visual studio like app on MFC

Posted by RobTheBloke on 04 April 2013 - 04:49 PM

Please don't use MFC for new code.

 

It's ancient, unsupported, non-idiomatic C++, and full of evil pitfalls and gotchas. It really needs to just go die in a corner somewhere.

It's not that terrible. If you only want to target Windows, it's perfectly fine. MFC is structurally pretty much like wxWidgets, but I never hear people complaining about that being evil.

 

It is so beyond terrible it's not funny, and wxWidgets is the only GUI library known to mankind that is noticeably worse. I've got many wx-related 'tales of horror from the trenches', but I'm not going to go into details. It took years of counseling before I was able to forget about those poor souls who died by the millions in the trenches alongside me, and it's an experience I do not want to be reminded of!

Seriously, use windows.forms or Qt.

 

 

Perhaps you could elaborate on what aspects of MFC it is that you think makes it suck so much more than other toolkits?

Because it's C++ only, and it's so limited in it's scope, it's just plain retarded in comparison to the competition. With Qt, you can put together the core app in C++, but then quickly add huge swathes of GUI code using one of the many script bindings for it (e.g. pyQT). With windows.forms, you can do the same thing using C#/VB/python (via the CodeProvider classes). All of this allows you to create, modify, and test the GUI at runtime, which makes the turnaround time for adding new features to your app many orders of magnitude quicker. In Qt, you've got extensive support for OpenGL and OpenVG, so it's trivially simple to knock up a custom node-editing framework, or any other visually appealing UI you can think of. Both Qt and windows.forms have an extensive community behind them, so there are many actively developed extensions available (again, cutting down your dev time). Qt is cross platform, unlike MFC and wxWidgets. Yes I know wx claims to be cross platform, but in reality that means a basic dialog with a few basic controls. As soon as you do anything mildy complex, you soon realise that you're going to have to rewrite most of it to make it work on say linux. The X version of wx is missing a huge number of features, so much so, that the best options for wx on linux is to use the Win32 version, and link it against the WINE libraries. This means you'll be (mostly) restricted to Windows 95 controls, which means you'll be missing localisation support due to a lack of wide string support. Once you encountered THESE things, you'll understand why everyone is saying that wx and MFC are a pile of shit. It's not because we're being arsey, it's because they truly are a pile of stinking shit, and they need to be left to fucking die.

 

 

Perhaps you want write all of your program in one language? It's not like it's an order of magnitude more difficult to use MFC than to use winforms.

If you really think that writing user interface code in C++ is a good idea, you need therapy. I'd suggest trying some C# for a bit, look at the C# CodeProvider classes, and understand the benefits of being able to write your GUI code from within your application, whilst it is running.

 

 

Most people who shout "MFC sucks" have never used it extensively.


I have used it extensively, and have also used wx, Qt, and windows forms to the same degree. If I was about to embark on writing an app from scratch, I'd use winforms for personal projects (or projects that I know will only ever need to target windows), but I'd use Qt if there was even a wiff of the possibility that the app may need to be cross platform one day.






PARTNERS