Hi. Could somebody help me with this problem? I am trying to make OpengL/SDL wrapper library. The library and test program compile fine, but linking gives an undefined reference wherever I use struct Pattern in the test program. I am completely mystified because struct Pattern should work and is used in the library. Does anybody have any ideas?
NewProject.cpp
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include <stack>
#include <iostream>
using namespace std;
//Globals:
SDL_Surface* screen;
struct Vector{
float x,y,z;
Vector(){
x=0.0f;
y=0.0f;
z=0.0f;
}
Vector(float x2,float y2,float z2){
x=x2;
y=y2;
z=z2;
}
Vector operator+(Vector v2){
Vector tmp;
tmp.x=x+v2.x;
tmp.y=y+v2.y;
tmp.z=z+v2.z;
return tmp;
}
Vector operator-(Vector v2){
Vector tmp;
tmp.x=x-v2.x;
tmp.y=y-v2.y;
tmp.z=z-v2.z;
return tmp;
}
Vector operator*(Vector v2){
Vector tmp;
tmp.x=x*v2.x;
tmp.y=y*v2.y;
tmp.z=z*v2.z;
return tmp;
}
Vector operator/(Vector v2){
Vector tmp;
tmp.x=x/v2.x;
tmp.y=y/v2.y;
tmp.z=z/v2.z;
return tmp;
}
void operator+=(Vector v2){
x+=v2.x;
y+=v2.y;
z+=v2.z;
}
void operator=(Vector v2){
x=v2.x;
y=v2.y;
z=v2.z;
}
Vector operator+(float v2){
Vector tmp;
tmp.x=x+v2;
tmp.y=y+v2;
tmp.z=z+v2;
return tmp;
}
Vector operator-(float v2){
Vector tmp;
tmp.x=x-v2;
tmp.y=y-v2;
tmp.z=z-v2;
return tmp;
}
Vector operator*(float v2){
Vector tmp;
tmp.x=x*v2;
tmp.y=y*v2;
tmp.z=z*v2;
return tmp;
}
Vector operator/(float v2){
Vector tmp;
tmp.x=x/v2;
tmp.y=y/v2;
tmp.z=z/v2;
return tmp;
}
void operator+=(float v2){
x+=v2;
y+=v2;
z+=v2;
}
void operator=(float v2){
x=v2;
y=v2;
z=v2;
}
};
Vector mVector(float x,float y,float z){
Vector tmp(x,y,z);
return tmp;
}
struct Pattern{
stack<Vector> col;
int length,procedure;
Pattern(){
length=0;
procedure=0;
}
Pattern(Vector c){
col.push(c);
length=1;
}
Pattern(Vector list[],int len,int proc){
for(int i=0;i<len;i++)col.push(list);
length=len;
procedure=proc;
}
void Push(Vector vector){
col.push(vector);
length+=1;
}
void Pop(){
col.pop();
length-=1;
}
Vector Top(){
Vector tmp;
tmp=col.top();
return tmp;
}
void Procedure(int proc){
procedure=proc;
}
};
struct Polygon{
stack<Vector> draw;
int length,type;
Polygon(){
length=0;
type=0;
}
Polygon(Vector a){
draw.push(a);
length=1;
type=1;
}
Polygon(Vector a,Vector b){
draw.push(a);
draw.push(b);
length=2;
type=2;
}
Polygon(Vector a,Vector b,Vector c){
draw.push(a);
draw.push(b);
draw.push(c);
length=3;
type=3;
}
Polygon(Vector a,Vector b,Vector c,Vector d){
draw.push(a);
draw.push(b);
draw.push(c);
draw.push(d);
length=4;
type=4;
}
Polygon(Vector list[],int length2,int type2){
for(int i=0;i<length;i++)draw.push(list);
length=length2;
type=type2;
}
void Push(Vector vector){
draw.push(vector);
length+=1;
}
void Pop(){
draw.pop();
length-=1;
}
void Type(int tp){
type=tp;
}
Vector Top(){
Vector tmp;
tmp=draw.top();
return tmp;
}
};
Polygon mPolygon(Vector a){
Polygon tmp(a);
return tmp;
}
Polygon mPolygon(Vector a,Vector b){
Polygon tmp(a,b);
return tmp;
}
Polygon mPolygon(Vector a,Vector b,Vector c){
Polygon tmp(a,b,c);
return tmp;
}
Polygon mPolygon(Vector a,Vector b,Vector c,Vector d){
Polygon tmp(a,b,c,d);
return tmp;
}
Polygon mPolygon(Vector list[],int length,int type){
Polygon tmp(list,length,type);
return tmp;
}
void Init(int x,int y){
float ratio;
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,16);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,8);
screen=SDL_SetVideoMode(x,y,0,SDL_OPENGL|SDL_HWPALETTE| SDL_GL_DOUBLEBUFFER|SDL_HWSURFACE|SDL_HWACCEL);
glShadeModel(GL_SMOOTH);
glClearColor(0.0f,0.0f,0.0f,0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
if(y==0)y=1;
ratio=(float)x/(float)y;
glViewport(0,0,(GLsizei)x,(GLsizei)y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,ratio,0.1f,600.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void Quit(){
SDL_Quit();
}
void Delay(int time){
SDL_Delay(time);
}
void Clear(){
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
}
void Reset(){
glLoadIdentity();
}
void Translate(Vector vector){
glTranslatef(vector.x,vector.y,vector.z);
}
void Rotate(Vector vector,float val){
glRotatef(val,vector.x,vector.y,vector.z);
}
void Flip(){
SDL_GL_SwapBuffers();
}
void Draw(Polygon poly,Pattern col){
stack<Vector> apoly,acol;
int j=0;
switch(poly.type){
case 1:
glBegin(GL_POINTS);
break;
case 2:
glBegin(GL_LINES);
break;
case 3:
glBegin(GL_TRIANGLES);
break;
case 4:
glBegin(GL_QUADS);
break;
}
switch(col.procedure){
case 1:
for(int i=0;i<poly.length;i++){
acol.push(col.col.top());
glColor3f(acol.top().x,acol.top().y,acol.top().z);
if(!j>=col.length){
col.col.pop();
j++;
}
if(poly.draw.empty()){
apoly.push(poly.draw.top());
glVertex3f(apoly.top().x,apoly.top().y,apoly.top().z);
poly.draw.pop();
}
};
break;
}
glEnd();
while(!apoly.empty()){
poly.draw.push(apoly.top());
apoly.pop();
}
while(!acol.empty()){
col.col.push(acol.top());
acol.pop();
}
}
NewProject.h
#pragma once
#include "Core2.h"
using namespace std;
//SDL:
void Init(int x,int y);
void Quit();
void Delay(int time);
//OpenGL:
void Clear();
void Reset();
void Translate(Vector vector);
void Rotate(Vector vector,float val);
void Flip();
void Draw(Polygon poly,Pattern col);
Core2.h
#pragma once
#include <stack>
using namespace std;
struct Vector{
float x,y,z;
Vector();
Vector(float x,float y2,float z2);
Vector operator+(Vector v2);
Vector operator-(Vector v2);
Vector operator*(Vector v2);
Vector operator/(Vector v2);
void operator+=(Vector v2);
void operator=(Vector v2);
Vector operator+(float v2);
Vector operator-(float v2);
Vector operator*(float v2);
Vector operator/(float v2);
void operator+=(float v2);
void operator=(float v2);
};
Vector mVector(float x,float y,float z);
struct Polygon{
stack<Vector> draw;
int length,type;
Polygon();
Polygon(Vector a);
Polygon(Vector a,Vector b);
Polygon(Vector a,Vector b,Vector c);
Polygon(Vector a,Vector b,Vector c,Vector d);
Polygon(Vector list[],int length2,int type2);
void Push(Vector vector);
void Pop();
void Type(int tp);
Vector Top();
};
Polygon mPolygon(Vector a);
Polygon mPolygon(Vector a,Vector b);
Polygon mPolygon(Vector a,Vector b,Vector c);
Polygon mPolygon(Vector a,Vector b,Vector c,Vector d);
Polygon mPolygon(Vector list[],int length,int type);
struct Pattern{
stack<Vector> col;
int length,procedure;
Pattern();
Pattern(Vector c);
Pattern(Vector list[],int len,int proc);
void Push(Vector vector);
void Pop();
Vector Top();
void Procedure(int proc);
};
Test.cpp
#include "NewProject.h"
int main(){
Polygon poly(mVector(-1.0f,-1.0f,0.0f),mVector(1.0f,-1.0f,0.0f),mVector(1.0f,1.0f,0.0f),mVector(-1.0f,1.0f,0.0f));
Pattern col;
col.Procedure(1);
col.Push(mVector(1.0f,0.0f,1.0f));
col.Push(mVector(0.0f,0.0f,1.0f));
col.Push(mVector(0.0f,1.0f,0.0f));
col.Push(mVector(1.0f,0.0f,0.0f));
Init(500,500);
Clear();
Reset();
Translate(mVector(0.0f,0.0f,-5.0f));
Draw(poly,col);
Flip();
Delay(5000);
Quit();
return 0;
}
The error:
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o NewProject.o -c NewProject.cpp
g++ -o Test.o -c Test.cpp
Test.cpp:21:2: warning: no newline at end of file
ar rc libNewProject.a NewProject.o
ranlib libNewProject.a
g++ -o Test Test.o -L. -L/usr/lib -lNewProject -lGL -lGLU -lSDL
Test.o: In function `main':
Test.cpp:(.text+0x125): undefined reference to `Pattern::Pattern()'
Test.cpp:(.text+0x13b): undefined reference to `Pattern::Procedure(int)'
Test.cpp:(.text+0x187): undefined reference to `Pattern::Push(Vector)'
Test.cpp:(.text+0x1d3): undefined reference to `Pattern::Push(Vector)'
Test.cpp:(.text+0x21f): undefined reference to `Pattern::Push(Vector)'
Test.cpp:(.text+0x26b): undefined reference to `Pattern::Push(Vector)'
collect2: ld returned 1 exit status
scons: *** [Test] Error 1
scons: building terminated because of errors.