PDA

Click to See Complete Forum and Search --> : OGL: Using OGL Code in Classes


NOMADMAN
Jun 16th, 2002, 04:32 PM
I have a class called cube to keep track of my cubes, corner points and so on. In it I have a public function that is called DisplayCube(). In that function it has glBegin(GL_QUADS) and glEnd() with all the stuff to draw a cube for me. But when I put someCube.DisplayCube() in my RenderScence() I get linker errors for all my functions in my Init.h file...

I am #include-ing init.h in my cube class header file. But init.h has #ifndef... in it so whats going on? Can I only have glBegin(...) in the RenderScence Function? What can I do?

Thanks!

NOMAD

parksie
Jun 16th, 2002, 04:35 PM
What linker errors? Are they multiply-defined symbols, undefined symbols, ...?

NOMADMAN
Jun 16th, 2002, 04:53 PM
Multiply Defined

main.obj : error LNK2005: "void __cdecl ChangeToFullScreen(void)" (?ChangeToFullScreen@@YAXXZ) already defined in cube.obj
main.obj : error LNK2005: "struct HWND__ * __cdecl CreateMyWindow(char *,int,int,unsigned long,bool,struct HINSTANCE__ *)" (?CreateMyWindow@@YAPAUHWND__@@PADHHK_NPAUHINSTANCE__@@@Z) already defined in cube.obj
main.obj : error LNK2005: "bool __cdecl bSetupPixelFormat(struct HDC__ *)" (?bSetupPixelFormat@@YA_NPAUHDC__@@@Z) already defined in cube.obj
main.obj : error LNK2005: "void __cdecl SizeOpenGLScreen(int,int)" (?SizeOpenGLScreen@@YAXHH@Z) already defined in cube.obj
main.obj : error LNK2005: "void __cdecl InitializeOpenGL(int,int)" (?InitializeOpenGL@@YAXHH@Z) already defined in cube.obj
main.obj : error LNK2005: "void __cdecl Init(struct HWND__ *)" (?Init@@YAXPAUHWND__@@@Z) already defined in cube.obj
main.obj : error LNK2005: "void __cdecl DeInit(void)" (?DeInit@@YAXXZ) already defined in cube.obj
main.obj : error LNK2005: "long __stdcall WinProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WinProc@@YGJPAUHWND__@@IIJ@Z) already defined in cube.obj
main.obj : error LNK2005: "bool g_bFullScreen" (?g_bFullScreen@@3_NA) already defined in cube.obj
main.obj : error LNK2005: "struct HGLRC__ * g_hRC" (?g_hRC@@3PAUHGLRC__@@A) already defined in cube.obj
main.obj : error LNK2005: "struct HDC__ * g_hDC" (?g_hDC@@3PAUHDC__@@A) already defined in cube.obj
main.obj : error LNK2005: "struct HWND__ * g_hWnd" (?g_hWnd@@3PAUHWND__@@A) already defined in cube.obj
main.obj : error LNK2005: "struct tagRECT g_rRect" (?g_rRect@@3UtagRECT@@A) already defined in cube.obj
main.obj : error LNK2005: "struct HINSTANCE__ * g_hInstance" (?g_hInstance@@3PAUHINSTANCE__@@A) already defined i

parksie
Jun 16th, 2002, 04:58 PM
It looks like you're defining and supplying code for global functions inside a header file which is then being included into two source files.

The #ifdef/#define trick only works on headers. As far as the compiler's concerned, it's totally separate for the two source files so it'll happily generate code for the same functions in different object files.

You need to move the code into one source file only and it should sort it :)

NOMADMAN
Jun 16th, 2002, 05:19 PM
So I can't have OGL code in a class, unless I template it. And the code that I need to move to the source would probably be the OGL code in my class gets moved to my RenderScene file (render.h). Would that work?

parksie
Jun 16th, 2002, 05:21 PM
No, you can have OpenGL code in a class, but you can't redefine the same functions.

Can you post your code?

NOMADMAN
Jun 16th, 2002, 05:35 PM
This is from the cube class (cube.cpp)


float r, g, b, a;
float x, y, z;

glBegin(GL_QUADS);

// These vertices create the Back Side (BkBmL BkBmR BkTL BkTR)
// ( 0, 1, 2, 3 )
point[0].GetColor(r, g, b, a); point[0].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[1].GetColor(r, g, b, a); point[1].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[2].GetColor(r, g, b, a); point[2].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[3].GetColor(r, g, b, a); point[3].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);

// These vertices create the Front Side (FBmL FBmR FTL FTR)
// ( 4, 5, 6, 7 )
point[4].GetColor(r, g, b, a); point[4].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[5].GetColor(r, g, b, a); point[5].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[6].GetColor(r, g, b, a); point[6].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[7].GetColor(r, g, b, a); point[7].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);

// These vertices create the Bottom Face (BkBmL BkBmR FBmL FBmR)
// ( 0, 1, 4, 5 )
point[0].GetColor(r, g, b, a); point[0].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[1].GetColor(r, g, b, a); point[1].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[4].GetColor(r, g, b, a); point[4].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[5].GetColor(r, g, b, a); point[5].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);

// These vertices create the Top Face (BkTL BkTR FTL FTR)
// ( 2, 3, 6, 7 )
point[2].GetColor(r, g, b, a); point[2].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[3].GetColor(r, g, b, a); point[3].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[6].GetColor(r, g, b, a); point[6].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[7].GetColor(r, g, b, a); point[7].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);

// These vertices create the Left Face (BkBmL BkTL FBmL FTL)
// ( 0, 2, 4, 6 )
point[0].GetColor(r, g, b, a); point[0].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[2].GetColor(r, g, b, a); point[2].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[4].GetColor(r, g, b, a); point[4].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[6].GetColor(r, g, b, a); point[6].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);

// These vertices create the Right Face (BkBmR BkTR FBmR FTR)
// ( 1, 3, 5, 7 )
point[1].GetColor(r, g, b, a); point[1].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[3].GetColor(r, g, b, a); point[3].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[5].GetColor(r, g, b, a); point[5].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);
point[7].GetColor(r, g, b, a); point[7].GetCorner(x, y, z);
glColor3ub(r, g, b); glVertex3f(x, y, z);

glEnd();
}



point is an array of corner s another class. It hold 3d point and color info. GetColoe and GetCorner have all &reference vars.

parksie
Jun 16th, 2002, 05:47 PM
I meant all the code. It's a problem with how your code is organised between the files.

NOMADMAN
Jun 16th, 2002, 06:08 PM
I didn't understand, I'm not that far so if I should just start over thats fine, I've only got a couple hours of work in it.
Heres a zip file of my project. Its MS VC++, hope that good for you.

NOMAD
(Parksie, Thank You. I know you don't have to do this and I really appreaciate it!)

Zaei
Jun 17th, 2002, 07:18 PM
Ok, some fun for you NOMAD =).

Create a .cpp files with the same name as each of your .h files. Then, take all of the function definitions (the code, not the prototypes), and stick them into the .cpps. Now you have .h files with only prototypes in them. DONT #include the .cpps into other .cpps or .h files. Just leave them in the project, and compile.

The reason for your errors is fairly simple. Take 2 files:

// File 1
// x.h
#include <iostream>
using namespace std;

#ifndef _FILE1
#define _FILE1

void x()
{
cout << 10 << endl;
}

#endif

and:

// File 2
// main.cpp
#include "x.h"

void x()
{
cout << 20 << endl;
}

Just follow the pre-processor. First, it includes x.h. It sees that _FILE1 is not defined, so it continues. But the compiler sees this:

...
void x()
{
...
}
...
void x()
{
...
}

Get it? Two definitions. The solution is simple. Define the function only once, in an individually compiled .cpp file. Each cpp in your project is compiled into its own .obj file. As long as there is a prototype for a function, you will get this .obj from your cpp. It is the Linker's job to actually resolve all of these .obj files into an exe. So, when it sees that main.obj and init.obj BOTH have void x() defined in them, it yells. What you do is only have void x() defined in one of the cpps, and simply let the other know it is there. We end up with this:

// file init.cpp

#include "init.h"

void x()
{

}


// file init.h
#ifndef INIT
#define INIT

void x(); // prototype ONLY

#endif


// file main.cpp
#include "init.h" // just the prototype!

int main()
{
x();
return 0;
}


See how it all fits? main.cpp doesnt have an implementation of void x(), but it knows it exists, because of the prototype defined in init.h. init.cpp has the actual implmentation of the function, and the linker will resolve the dependencies between the .obj files.

If it seems a bit complicated, just read it over a few times. It will make sense eventually =). Its easier then it looks.

Z.

NOMADMAN
Jun 19th, 2002, 12:33 PM
I think I've fixed any problems like that Z. I main doesn't define any functions other than main... Why does it still say its already defined in main?

These are my errors:

Linking...
Init.obj : error LNK2005: "bool g_bFullScreen" (?g_bFullScreen@@3_NA) already defined in main.obj
Init.obj : error LNK2005: "struct HGLRC__ * g_hRC" (?g_hRC@@3PAUHGLRC__@@A) already defined in main.obj
Init.obj : error LNK2005: "struct HDC__ * g_hDC" (?g_hDC@@3PAUHDC__@@A) already defined in main.obj
Init.obj : error LNK2005: "struct HWND__ * g_hWnd" (?g_hWnd@@3PAUHWND__@@A) already defined in main.obj
Init.obj : error LNK2005: "struct tagRECT g_rRect" (?g_rRect@@3UtagRECT@@A) already defined in main.obj
Init.obj : error LNK2005: "struct HINSTANCE__ * g_hInstance" (?g_hInstance@@3PAUHINSTANCE__@@A) already defined in main.obj
Scene.obj : error LNK2005: "bool g_bFullScreen" (?g_bFullScreen@@3_NA) already defined in main.obj
Scene.obj : error LNK2005: "struct HGLRC__ * g_hRC" (?g_hRC@@3PAUHGLRC__@@A) already defined in main.obj
Scene.obj : error LNK2005: "struct HDC__ * g_hDC" (?g_hDC@@3PAUHDC__@@A) already defined in main.obj
Scene.obj : error LNK2005: "struct HWND__ * g_hWnd" (?g_hWnd@@3PAUHWND__@@A) already defined in main.obj
Scene.obj : error LNK2005: "struct tagRECT g_rRect" (?g_rRect@@3UtagRECT@@A) already defined in main.obj
Scene.obj : error LNK2005: "struct HINSTANCE__ * g_hInstance" (?g_hInstance@@3PAUHINSTANCE__@@A) already defined in main.obj
Scene.obj : error LNK2001: unresolved external symbol "public: __thiscall cube::~cube(void)" (??1cube@@QAE@XZ)
Scene.obj : error LNK2001: unresolved external symbol "public: void __thiscall cube::DisplayCube(void)" (?DisplayCube@cube@@QAEXXZ)
Scene.obj : error LNK2001: unresolved external symbol "public: __thiscall cube::cube(float,float,float,float)" (??0cube@@QAE@MMMM@Z)
Debug/CubeControl.exe : fatal error LNK1120: 3 unresolved externals
Error executing link.exe.

Thanks!

NOMAD

NOMADMAN
Jun 21st, 2002, 11:57 AM
I apologize for giving up and thowing error messages up for someone else to fix for me! Next time I do that tell me to look harder.

I'm still stuck, I guess I reorganized my project to what you guys said. All functions are in the appropriate cpp file, globals and prototypes are in h files.
I found that when I remove the #include "Init.h" line from my cube class .h file the linking errors go away, but then I get glBegin and the rest of the OGL functions in my class are undeclared.
Is all this from me having my globals in the Init.h file? what can I do, I need those as globals. Where can I put them?

If you want to look at my project to see where I have everything I'll include that too.

Thanks, NOMAD!

NOMADMAN
Jun 22nd, 2002, 04:42 PM
I got it! Thanks for your help, I figured out what you're talking about. It works now!

Thanks y'all!

NOMAD

Zaei
Jun 22nd, 2002, 05:03 PM
No problem =). Its better that you get your organization down right before your project gets bigger, because THEN it gets to be a real problem.

Glad you got it working =).

Z.