Thread: LNK2019 unresolved external symbol

  1. #1
    Registered User
    Join Date
    Dec 2006
    Posts
    2

    LNK2019 unresolved external symbol

    Hi,

    I'm doing a small extension for an penGL/Cg school-exercise, but now I'm stuck. My problem is C++ related, so I guess this is the right place to post my problem.

    The following 2 errors occur, whenever I try to call the iTBNmatrix function:

    "CgExercise error LNK2019: unresolved external symbol "void __cdecl invTBNmatrix(class CVector const *,class CVector2 const *,class CVector *)" (?invTBNmatrix@@YAXPBVCVector@@PBVCVector2@@PAV1@@ Z) referenced in function "void __cdecl drawPlane(void)" (?drawPlane@@YAXXZ)"

    "CgExercise fatal error LNK1120: 1 unresolved externals"


    Code:
    #pragma warning (disable: 4786)
    
    #ifdef _MSC_VER
    #include <GL/glew.h>
    #else
    #include <GL/gl.h>
    #endif
    
    #include <Graphics/TrackBall.h>
    #include <Graphics/DisplayText.h>
    #include <GL/glut.h>
    
    #include <Cg/cg.h>
    #include <Cg/cgGL.h>
    
    using namespace std;
    using namespace Graphics;
    using namespace CGLA;
    
    TrackBall *ball;
    DisplayText displaytext;
    
    int old_state = GLUT_UP;
    
    CGcontext context;
    CGprogram vertexProgram, fragmentProgram;
    CGprofile vertexProfile, fragmentProfile;
    
    static void handleCgError();
    static void LoadCgPrograms();
    static void ChooseProfiles();
    
    #ifndef CWD
    # define CWD ""
    #endif
    
    bool two_mouse = true;
    
    // additions //////////////////////////////////////////////////////////////////////////////////////////////////
    
    // OglExt.lib is used to allow easy implementation 
    // of the glMultiTexCoordARB functions
    #pragma comment (lib, "OglExt.lib")
    
    // used for loading and storing .tga textures
    #include "TGAImg.h"
    
    // had problems with CGLA when constructing
    // the TBN matrix, so used this alternative
    #include "3DMath_Lean.h"
    
    // the coordinates for the plane (2 triangles of 3 vertices each)
    CVector plane[2][3] = { {CVector(-75.0f, -75.0f, 0.0f), CVector(75.0f, -75.0f, 0.0f),  CVector(75.0f, 75.0f, 0.0f)}, 
    						{CVector(-75.0f, 75.0f, 0.0f),  CVector(-75.0f, -75.0f, 0.0f), CVector(75.0f, -75.0f, 0.0f)} };
    
    // texture coordinates for the 2 triangles
    CVector2 texCoords[2][3] = { {CVector2(1.0f, 1.0f), CVector2(0.0f, 1.0f), CVector2(0.0f, 0.0)},
    							 {CVector2(1.0f, 0.0f), CVector2(1.0f, 1.0f), CVector2(0.0f, 1.0)} };
    
    // the textures
    GLuint texture, normalMap;
    
    // the inverse TBN matrices
    CVector invTBN[2][3];
    
    // function prototypes
    void drawPlane(void);
    void invTBNmatrix(const CVector*, const CVector2*, CVector*);
    GLuint LoadTexture(char *TexName);
    
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    void initBall(float max_value) {
    	Vec3f v(0,0,0);
    	ball = new TrackBall(v, 200, 500, 750, 750);
    }
    
    void initGL(void) {
    	// initialize textures	
    	texture = LoadTexture("apeBase.tga");
    	normalMap = LoadTexture("apeNormal.tga");
    
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    	glFrustum(-10.0,10.0,-10.0,10.0,15,50000.0);
    	glMatrixMode(GL_MODELVIEW);
    	glLoadIdentity();
    	glTranslatef(0.,0.,-10.5);
    	glClearColor(0.0f, 0.0f, 0.0f, 0.f);
    	glEnable(GL_DEPTH_TEST);
    	glShadeModel(GL_SMOOTH);
    	ChooseProfiles();
    	LoadCgPrograms();
    }
    
    static void handleCgError() 
    {
    	fprintf(stderr, "Cg error: %s\n", cgGetErrorString(cgGetError()));
    	exit(1);
    }
    
    static void ChooseProfiles()
    {
    	// Make sure that the appropriate profiles are available on the
    	// user's system.
    	if (cgGLIsProfileSupported(CG_PROFILE_ARBVP1))
    		vertexProfile = CG_PROFILE_ARBVP1;
    	else {
    		// try VP30
    		if (cgGLIsProfileSupported(CG_PROFILE_VP30))
    			vertexProfile = CG_PROFILE_VP30;
    		else {
    			fprintf(stderr, "Neither arbvp1 or vp30 vertex profiles supported on this system.\n");
    			exit(1);
    		}
    	}
    
    	if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1))
    		fragmentProfile = CG_PROFILE_ARBFP1;
    	else {
    		// try FP30
    		if (cgGLIsProfileSupported(CG_PROFILE_FP30))
    			fragmentProfile = CG_PROFILE_FP30;
    		else {
    			fprintf(stderr, "Neither arbfp1 or fp30 fragment profiles supported on this system.\n");
    			exit(1);
    		}
    	}
    }
    
    static void LoadCgPrograms()
    {
    	assert(cgIsContext(context));
    
    	// Load and compile the vertex program from demo_vert.cg; hold on to the
    	// handle to it that is returned.
    	vertexProgram = cgCreateProgramFromFile(context, CG_SOURCE, CWD "shader_vp.cg", vertexProfile, NULL, NULL);
    	if (!cgIsProgramCompiled(vertexProgram))
    		cgCompileProgram(vertexProgram);
    
    	// Enable the appropriate vertex profile and load the vertex program.
    	cgGLEnableProfile(vertexProfile);
    	cgGLLoadProgram(vertexProgram);
    
    	// And similarly set things up for the fragment program.
    	fragmentProgram = cgCreateProgramFromFile(context, CG_SOURCE, CWD "shader_fp.cg",
    		fragmentProfile, NULL, NULL);
    	if (!cgIsProgramCompiled(fragmentProgram))
    		cgCompileProgram(fragmentProgram);
    
    	cgGLEnableProfile(fragmentProfile);
    	cgGLLoadProgram(fragmentProgram);
    }
    
    void display() {
    	Vec3f eye;
    	Vec3f center(0,0,-1);
    	Vec3f up(0,0,1); 
    
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    	glLoadIdentity();
    	ball->get_view_param(eye, center, up);
    	ball->do_spin();
    	ball->set_gl_modelview();
    
    	// Now make sure that the vertex and fragment programs, loaded
    	// in LoadCgPrograms() are bound.
    	//cgGLEnableProfile(vertexProfile);
    	//cgGLEnableProfile(fragmentProfile);
    	cgGLBindProgram(vertexProgram);
    	cgGLBindProgram(fragmentProgram);
    
    	// Bind uniform parameters to vertex shader
    	cgGLSetStateMatrixParameter(cgGetNamedParameter(vertexProgram, "ModelViewProj"),
    		CG_GL_MODELVIEW_PROJECTION_MATRIX,
    		CG_GL_MATRIX_IDENTITY);
    	cgGLSetStateMatrixParameter(cgGetNamedParameter(vertexProgram, "ModelView"),
    		CG_GL_MODELVIEW_MATRIX,
    		CG_GL_MATRIX_IDENTITY);
    	cgGLSetStateMatrixParameter(cgGetNamedParameter(vertexProgram, "ModelViewIT"),
    		CG_GL_MODELVIEW_MATRIX,
    		CG_GL_MATRIX_INVERSE_TRANSPOSE);
    
    	// We can also go ahead and bind varying parameters to vertex shader
    	// that we just want to have the same value for all vertices.  The
    	// vertex shader could be modified so that these were uniform for
    	// better efficiency, but this gives us flexibility for the future.
    	float lightPos[3] = { 100, 100, 100 };
    	float lightColor[3] = { 1, 1, 1 };
    	float Kd[3] = { .6, .6, .6 }; 
    	float Ks[3] = { .9, .9, .9 };
    	float ior = 1.5;
    	float m = 0.1;
    
    	// Now bind uniform parameters to fragment shader
    	cgGLSetParameter3fv(cgGetNamedParameter(fragmentProgram, "lightPos"), lightPos);
    	cgGLSetParameter3fv(cgGetNamedParameter(fragmentProgram, "lightCol"), lightColor);
    	cgGLSetParameter3fv(cgGetNamedParameter(fragmentProgram, "specCol"), Ks);
    	cgGLSetParameter3fv(cgGetNamedParameter(fragmentProgram, "difCol"), Kd);
    	cgGLSetParameter3fv(cgGetNamedParameter(fragmentProgram, "eyePos"), eye.get());
    	cgGLSetParameter1f(cgGetNamedParameter(fragmentProgram, "ior"), ior);
    	cgGLSetParameter1f(cgGetNamedParameter(fragmentProgram, "m"), m);
    
    /*
    	// Enable and bind the rock texture
    	glActiveTextureARB(GL_TEXTURE0_ARB);
    	glEnable(GL_TEXTURE_2D);
    	glBindTexture(GL_TEXTURE_2D, texture);
    
    	// Enable and bind the normal map
    	glActiveTextureARB(GL_TEXTURE1_ARB);
    	glEnable(GL_TEXTURE_2D);
    	glBindTexture(GL_TEXTURE_2D, normalMap);
    */
    	drawPlane();	
    
    	cgGLDisableProfile(vertexProfile);
    	cgGLDisableProfile(fragmentProfile);
    /*
    	// Disable textures
    	glActiveTextureARB(GL_TEXTURE0_ARB);
    	glDisable(GL_TEXTURE_2D);
    	glActiveTextureARB(GL_TEXTURE1_ARB);
    	glDisable(GL_TEXTURE_2D);
    */
    	displaytext.draw();
    	glutSwapBuffers();
    }
    
    void mouse(int button, int state, int x, int y) {
    	if (old_state==GLUT_UP && state==GLUT_DOWN) {
    		if (button==GLUT_LEFT_BUTTON) 
    			ball->grab_ball(ROTATE_ACTION,Vec2i(x,y));
    		else if (button==GLUT_MIDDLE_BUTTON) 
    			ball->grab_ball(ZOOM_ACTION,Vec2i(x,y));
    		else if (button==GLUT_RIGHT_BUTTON) 
    			ball->grab_ball(PAN_ACTION,Vec2i(x,y));
    	}
    	if (old_state==GLUT_DOWN && state==GLUT_UP)
    		ball->release_ball();
    	old_state=state;
    }
    
    void motion(int x, int y) {
    	if (old_state==GLUT_DOWN)
    		ball->roll_ball(Vec2i(x,y));
    }
    
    void keyboard(unsigned char key, int x, int y) {	
    	switch(key) {
    		case '\033': exit(0); break;
    	}
    }
    
    void animate() {
    	glutPostRedisplay();
    }
    
    void drawPlane() {
    	glEnable(GL_TEXTURE_2D);
    	glColor3f(1.0f,1.0f,1.0f);
    	glBindTexture(GL_TEXTURE_2D, texture);
    
    	glBegin(GL_TRIANGLE_FAN);
    		glTexCoord2f(texCoords[0][0].x, texCoords[0][0].y);
    		glVertex3f(plane[0][0].x, plane[0][0].y, plane[0][0].z);
    
    		glTexCoord2f(texCoords[0][1].x, texCoords[0][1].y);
    		glVertex3f(plane[0][1].x, plane[0][1].y, plane[0][1].z);
    
    		glTexCoord2f(texCoords[0][2].x, texCoords[0][2].y);
    		glVertex3f(plane[0][2].x, plane[0][2].y, plane[0][2].z);
    
    		glTexCoord2f(texCoords[1][0].x, texCoords[1][0].y);
    		glVertex3f(plane[1][0].x, plane[1][0].y, plane[1][0].z);
    
    		glTexCoord2f(texCoords[1][1].x, texCoords[1][1].y);
    		glVertex3f(plane[1][1].x, plane[1][1].y, plane[1][1].z);
    
    		glTexCoord2f(texCoords[1][2].x, texCoords[1][2].y);
    		glVertex3f(plane[1][2].x, plane[1][2].y, plane[1][2].z);
    	glEnd();
    
    }
    
    GLuint LoadTexture(char *TexName) {
    	TGAImg Img;        // image loader
    	GLuint Texture;
     
    	// load our Texture
    	if(Img.Load(TexName)!=IMG_OK)
    		return -1;
     
    	glGenTextures(1,&Texture);            // allocate space for texture
    	glBindTexture(GL_TEXTURE_2D, Texture); // bind texture
     
    	// create the texture
        if(Img.GetBPP()==24)
        glTexImage2D(GL_TEXTURE_2D,0,3,Img.GetWidth(),Img.GetHeight(),0,
                     GL_RGB,GL_UNSIGNED_BYTE,Img.GetImg());
        else
    		return -1;
     
    	// specify filtering and edge actions
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    	
    	return Texture;
    } 
    
    void invTBNmatrix(const CVector *triangle, const CVector *tCoords, CVector *invTBN) {
    
    	// here the inverse TBN matrix is calculated
    	// the function follows the theory of the 
    	// report stricly.. no magic at all
    
    	// vertex point differences
    	CVector v2v1(triangle[1] - triangle[0]);
    	CVector v3v1(triangle[2] - triangle[0]);
    
    	// texcoords differences
    	float c2c1t = tCoords[1].x - tCoords[0].x;
    	float c2c1b = tCoords[1].y - tCoords[0].y;
    	float c3c1t = tCoords[2].x - tCoords[0].x;
    	float c3c1b = tCoords[2].y - tCoords[0].y;
    
    	// tanget, bitangent and normal
    	CVector T, B, N;	
    	float scale = 1/(c2c1t*c3c1b - c3c1t*c2c1b); 	
    
    	T = CVector( scale*(c3c1b*v2v1.x - c2c1b*v3v1.x),
    				 scale*(c3c1b*v2v1.y - c2c1b*v3v1.y),
    				 scale*(c3c1b*v2v1.z - c2c1b*v3v1.z) );
    
    	B = CVector( scale*(-c3c1t*v2v1.x - c2c1t*v3v1.x),
    			     scale*(-c3c1t*v2v1.y - c2c1t*v3v1.y),
    			     scale*(-c3c1t*v2v1.z - c2c1t*v3v1.z) );
    
    	N = T.CrossProduct(B);
    	
    	// start calculation of inverse TBN matrix
    	float scale2 = 1/((T.x*B.y*N.z - T.z*B.y*N.x) + (B.x*N.y*T.z - B.z*N.y*T.x) + (N.x*T.y*B.z - N.z*T.y*B.x));
    
    	// cross products for the inverse matrix
    	CVector BxN = B.CrossProduct(N);	
    	CVector NxT = N.CrossProduct(T);
    	CVector TxB = T.CrossProduct(B);
    
    	// finally construct the inverse TBN matrix
    	invTBN[0].x = BxN.x * scale2;
    	invTBN[0].y = BxN.y * scale2;
    	invTBN[0].z = BxN.z * scale2;
    	invTBN[0].Normalize();
    
    	invTBN[1].x = NxT.x * scale2;
    	invTBN[1].y = NxT.y * scale2;
    	invTBN[1].z = NxT.z * scale2;
    	invTBN[1].Normalize();
    
    	invTBN[2].x = TxB.x * scale2;
    	invTBN[2].y = TxB.y * scale2;
    	invTBN[2].z = TxB.z * scale2;
    	invTBN[2].Normalize();
    
    }
    
    int main(int argc, char** argv)
    {  
    	glutInit(&argc, argv);
    	glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA | GLUT_STENCIL);
    	glutInitWindowSize(700, 700);	
    	glutCreateWindow("CG Exercise + Bumpmapping");
    	glutDisplayFunc(display);
    	glutKeyboardFunc(keyboard);
    	glutIdleFunc(animate);
    	glutMouseFunc(mouse);
    	glutMotionFunc(motion);
    
    	cgSetErrorCallback(handleCgError);
    	context = cgCreateContext();
    	initGL();
    
     //THESE ARE THE TROUBLE MAKERS!!//
      ////////////////////////////////////////////////////
      //invTBNmatrix(plane[0], texCoords[0], invTBN[0]);//
      //invTBNmatrix(plane[1], texCoords[1], invTBN[1]);//
      ////////////////////////////////////////////////////	
    
    	displaytext.addFramerate();
    
    	initBall(50);
    
    #ifdef _MSC_VER
    	glewInit();
    #endif
    	glutMainLoop();
    
    	return 0;
    }
    I know it's rather messy, but I REALLY hope that someone can help my out.

    Thank you in advance
    /l e r c k e m a n

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Look at the second argument

    according to declaration and calling it should be CVector2
    but in the function definition it is stated as CVector

    So you call one function and provide body for another
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Registered User
    Join Date
    Dec 2006
    Posts
    2
    Thank you!!
    I think frustration has turned me blind to this trivial error. Glad you could point it out for me.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  2. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM
  3. Including lib in a lib
    By bibiteinfo in forum C++ Programming
    Replies: 0
    Last Post: 02-07-2006, 02:28 PM
  4. Stupid compiler errors
    By ChrisEacrett in forum C++ Programming
    Replies: 9
    Last Post: 11-30-2003, 05:44 PM
  5. debug to release modes
    By DavidP in forum Game Programming
    Replies: 5
    Last Post: 03-20-2003, 03:01 PM