Jump to content
  • Advertisement

ssorc3

Member
  • Content Count

    4
  • Joined

  • Last visited

Community Reputation

103 Neutral

About ssorc3

  • Rank
    Newbie
  1. ssorc3

    Unresolved External Symbols

    Thank you both of you! They now work. In answer to your question, Washu, as to why they were static, I was methods it to different classes when I created the new objects and I originally had to make it static to access it from main.cpp. Now that I've finished, they're no longer static. I just sort of went along with it when errors about non-static references came up and made the variables static.
  2. I know this is a common question among beginners of C++ but I have looked at other peoples threads and not found what I was looking for. I understand the unresolved external symbols error usually means missing libraries but these are my classes that it is not accepting. Here is the code and the errors(Sorry it's so messy, I'm in the process of converting it from single file to object orientated): main.cpp: #include <iostream> #include <gl\glew.h> #include <GL\freeglut.h> #include <vector> #include <algorithm> #include <string> #include <fStream> #include <cmath> #include <array> #include "ResourceLoader.h" #include "Shader.h" #include "Program.h" #define ARRAY_COUNT( array ) (sizeof( array ) / (sizeof( array[0] ) * (sizeof( array ) != sizeof(void*) || sizeof( array[0] ) <= sizeof(void*)))) void display(); void reshape(); void init(); void InitializeVertexBuffer(); struct glutWindow { int width; int height; char* title; float fov; float zNear; float zFar; }; glutWindow win; GLuint positionBufferObject; GLuint vao; Shader vertex("../Shaders/Vertex.vs"); Shader fragment("../Shaders/Fragment.fs"); Program program; const float vertexPositions[] { //102 lines of vertex positions I didn't think were necessary to include... }; int main(int argc, char** argv) { win.width = 800; win.height = 700; win.title = "OpenGL"; win.fov = 45; win.zNear = 1.0f; win.zFar = 500.0f; glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); glutInitWindowSize(win.width, win.height); glutCreateWindow("OpenGL"); glutDisplayFunc(display); glewInit(); init(); glutMainLoop(); return 0; } void init() { Shader* shaders[]{&vertex, &fragment}; program.setShaders(shaders); program.InitializeProgram(); InitializeVertexBuffer(); glGenVertexArrays(1, &vao); glBindVertexArray(vao); glEnable(GL_CULL_FACE); glFrontFace(GL_CW); glCullFace(GL_BACK); } void InitializeVertexBuffer() { glGenBuffers(1, &positionBufferObject); glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject); glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); } void display() { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); program.use(); program.setUniform2f("offset", 0.5f, 0.5f); size_t colorData = (1, 1, 1, 1); glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorData); glDrawArrays(GL_TRIANGLES, 0, 36); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glUseProgram(0); glutSwapBuffers(); glutPostRedisplay(); } Program.h: #ifndef _PROGRAM_H #define _PROGRAM_H #include <gl\glew.h> #include <GL\freeglut.h> #include <vector> #include <algorithm> #include <map> #include <cstdarg> #include "Shader.h" class Program { public: static void CreateProgram(Shader* shaders[]); void InitializeProgram(); static GLuint getUniformLocation(const GLchar* name); static void use(); void setShaders(Shader* shaders[]); void setUniform1f(std::string name, float value); void setUniform2f(std::string name, float val1, float val2); static Shader* shaders[3]; private: static GLuint program; static std::map<std::string, GLuint> uniforms; }; #endif Program.cpp: #include "Program.h" void Program::CreateProgram(Shader* shaders[]) { GLuint program = glCreateProgram(); for (size_t iLoop = 0; iLoop < sizeof(shaders) / sizeof(shaders[0]); iLoop++) glAttachShader(program, shaders[iLoop]->getShader()); glLinkProgram(program); GLint status; glGetProgramiv(program, GL_LINK_STATUS, &status); if (status == GL_FALSE) { GLint infoLogLength; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength); GLchar *strInfoLog = new GLchar[infoLogLength + 1]; glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog); fprintf(stderr, "Shader Linker failure: %s\n", strInfoLog); delete[] strInfoLog; } for (size_t iLoop = 0; iLoop < sizeof(shaders) / sizeof(shaders[0]); iLoop++) glDetachShader(program, shaders[iLoop]->getShader()); Program::program = program; } void Program::InitializeProgram() { Program::CreateProgram(Program::shaders); uniforms["offset"] = this->getUniformLocation("offset"); uniforms["frustumScale"] = this->getUniformLocation("frustumScale"); uniforms["zNear"] = this->getUniformLocation("zNear"); uniforms["zFar"] = this->getUniformLocation("zFar"); this->use(); this->setUniform1f("frustumScale", 1.0f); this->setUniform1f("zNear", 1.0f); this->setUniform1f("zFar", 1.0f); glUseProgram(0); for (int i = 0; i < sizeof(shaders) / sizeof(shaders[0]); i++) { glDeleteShader(shaders[i]->getShader()); } } void Program::setUniform1f(std::string name, float value) { glUniform1f(uniforms[name], value); } void Program::setUniform2f(std::string name, float val1, float val2) { glUniform2f(uniforms[name], val1, val2); } GLuint Program::getUniformLocation(const GLchar* name) { return glGetUniformLocation(Program::program, name); } void Program::use() { glUseProgram(Program::program); } void Program::setShaders(Shader* shaders[]) { for (int i = 0; i < sizeof(shaders) / sizeof(shaders[0]); i++) { Program::shaders[i] = shaders[i]; } } Shader.h: #ifndef _SHADER_H #define _SHADER_H #include <string> #include <iostream> #include <sstream> #include <gl\glew.h> #include <GL\freeglut.h> #include "ResourceLoader.h" class Shader { public: Shader(const char* filePath); void loadShader(); void CreateShader(GLenum eShaderType); std::string getContent(); std::string getFilePath(); GLuint getShader(); private: const char* filePath; GLuint shader; std::string content; }; #endif Shader.cpp: #include "Shader.h" Shader::Shader(const char* filePath) { this->filePath = filePath; loadShader(); } void Shader::loadShader() { content = ResourceLoader::readFile(this->filePath); if (content == "") { std::cout << "Shader " << filePath << " could not be loaded." << std::endl; } } std::string Shader::getContent() { return this->content; } std::string Shader::getFilePath() { return this->filePath; } GLuint Shader::getShader() { return this->shader; } void Shader::CreateShader(GLenum eShaderType) { GLuint shader = glCreateShader(eShaderType); std::string strFileData = ResourceLoader::readFile(this->filePath); const char* cstrFileData = strFileData.c_str(); const GLint length = strFileData.length(); glShaderSource(shader, 1, &cstrFileData, &length); glCompileShader(shader); GLint status; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) { GLint infoLogLength; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); GLchar *strInfoLog = new GLchar[infoLogLength + 1]; glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog); const char *strShaderType = NULL; switch (eShaderType) { case GL_VERTEX_SHADER: strShaderType = "vertex"; break; case GL_GEOMETRY_SHADER: strShaderType = "geometry"; break; case GL_FRAGMENT_SHADER: strShaderType = "fragment"; break; } fprintf(stderr, "Compile failure in %s shader:\n%s\n", strShaderType, strInfoLog); delete[] strInfoLog; } this->shader = shader; } ResourceLoader.h: #ifndef _RESOURCE_LOADER_H #define _RESOURCE_LOADER_H #include <string> #include <fstream> #include <iostream> class ResourceLoader { public: static std::string readFile(const char* filePath); }; #endif ResourceLoader.cpp: #include "ResourceLoader.h" std::string ResourceLoader::readFile(const char *filePath) { std::string content; std::ifstream fileStream(filePath, std::ios::in); if (!fileStream.is_open()) { std::cerr << "Could not read file " << filePath << ". File does not exist." << std::endl; return ""; } std::string line = ""; while (!fileStream.eof()) { std::getline(fileStream, line); content.append(line + "\n"); } fileStream.close(); return content; } Errors: Error 1 error LNK2001: unresolved external symbol "public: static class Shader * * Program::shaders" (?shaders@Program@@2PAPAVShader@@A) c:\Users\Ben\documents\visual studio 2013\Projects\OpenGL Project\OpenGL Project\Program.obj OpenGL Project Error 2 error LNK2001: unresolved external symbol "private: static unsigned int Program::program" (?program@Program@@0IA) c:\Users\Ben\documents\visual studio 2013\Projects\OpenGL Project\OpenGL Project\Program.obj OpenGL Project Error 3 error LNK2001: unresolved external symbol "private: static class std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,unsigned int,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,unsigned int> > > Program::uniforms" (?uniforms@Program@@0V?$map@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@IU?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@I@std@@@2@@std@@A) c:\Users\Ben\documents\visual studio 2013\Projects\OpenGL Project\OpenGL Project\Program.obj OpenGL Project Error 4 error LNK1120: 3 unresolved externals c:\users\ben\documents\visual studio 2013\Projects\OpenGL Project\Debug\OpenGL Project.exe 1 1 OpenGL Project Thanks
  3. I knew I forgot something! Thank you. It now works fine.
  4. When I run this code: #include <iostream> #include <gl\glew.h> #include <GL\freeglut.h> #include <vector> #include <algorithm> #include <string> typedef struct { int width; int height; char* title; float fov; float zNear; float zFar; } glutWindow; glutWindow win; GLuint CreateShader(GLenum eShaderType, const std::string &strShaderFile) { GLuint shader = glCreateShader(eShaderType); const char *strFileData = strShaderFile.c_str(); glShaderSource(shader, 1, &strFileData, NULL); glCompileShader(shader); GLint status; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) { GLint infoLogLength; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); GLchar *strInfoLog = new GLchar[infoLogLength + 1]; glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog); const char *strShaderType = NULL; switch (eShaderType) { case GL_VERTEX_SHADER: strShaderType = "vertex"; break; case GL_GEOMETRY_SHADER: strShaderType = "geometry"; break; case GL_FRAGMENT_SHADER: strShaderType = "fragment"; break; } fprintf(stderr, "Compile failure in %s shader:\n%s\n", strShaderType, strInfoLog); delete[] strInfoLog; } return shader; } GLuint CreateProgram(const std::vector<GLuint> &shaderList) { GLuint program = glCreateProgram(); for (size_t iLoop = 0; iLoop < shaderList.size(); iLoop++) glAttachShader(program, shaderList[iLoop]); glLinkProgram(program); GLint status; glGetProgramiv(program, GL_LINK_STATUS, &status); if (status == GL_FALSE) { GLint infoLogLength; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength); GLchar *strInfoLog = new GLchar[infoLogLength + 1]; glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog); fprintf(stderr, "Linker failure: %s\n", strInfoLog); delete[] strInfoLog; } for (size_t iLoop = 0; iLoop < shaderList.size(); iLoop++) glDetachShader(program, shaderList[iLoop]); return program; } GLuint theProgram; const std::string strVertexShader( "#version 330\n" "layout(location = 0) in vec4 position;\n" "void main()\n" "{\n" " gl_Position = position;\n" "}\n" ); const std::string strFragmentShader( "#version 330\n" "out vec4 outputColor;\n" "void main()\n" "{\n" " outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n" "}\n" ); void InitializeProgram() { std::vector<GLuint> shaderList; shaderList.push_back(CreateShader(GL_VERTEX_SHADER, strVertexShader)); shaderList.push_back(CreateShader(GL_FRAGMENT_SHADER, strFragmentShader)); theProgram = CreateProgram(shaderList); std::for_each(shaderList.begin(), shaderList.end(), glDeleteShader); } const float vertexPositions[] = { 0.75f, 0.75f, 0.0f, 1.0f, 0.75f, -0.75f, 0.0f, 1.0f, -0.75f, -0.75f, 0.0f, 1.0f, }; GLuint positionBufferObject; GLuint vao; void InitializeVertexBuffer() { glGenBuffers(1, &positionBufferObject); glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject); glBufferData(GL_ARRAY_BUFFER, sizeof(vertexPositions), vertexPositions, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); } //Called after the window and OpenGL are initialized. Called exactly once, before the main loop. void init() { InitializeProgram(); InitializeVertexBuffer(); glGenVertexArrays(1, &vao); glBindVertexArray(vao); } //Called to update the display. //You should call glutSwapBuffers after all of your rendering to display what you rendered. //If you need continuous updates of the screen, call glutPostRedisplay() at the end of the function. void display() { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(theProgram); glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); glDrawArrays(GL_TRIANGLES, 0, 3); glDisableVertexAttribArray(0); glUseProgram(0); glutSwapBuffers(); } //Called whenever the window is resized. The new window size is given, in pixels. //This is an opportunity to call glViewport or glScissor to keep up with the change in size. void reshape(int w, int h) { glViewport(0, 0, (GLsizei)w, (GLsizei)h); } //Called whenever a key on the keyboard was pressed. //The key is given by the ''key'' parameter, which is in ASCII. //It's often a good idea to have the escape key (ASCII value 27) call glutLeaveMainLoop() to //exit the program. void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: glutLeaveMainLoop(); return; } } unsigned int defaults(unsigned int displayMode, int &width, int &height) { return displayMode; } int main(int argc, char** argv) { win.width = 640; win.height = 480; win.title = "OpenGL"; win.fov = 45; win.zNear = 1.0f; win.zFar = 500.0f; glutInit(&argc, argv); glutInitContextVersion(3, 1); glutInitContextFlags(GLUT_FORWARD_COMPATIBLE | GLUT_DEBUG); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(win.width, win.height); glutCreateWindow(win.title); glutDisplayFunc(display); glutKeyboardFunc(keyboard); init(); glutMainLoop(); return 0; } I get no build errors and it shows no runtime errors. It just shows the '(Program Name) has stopped working' dialogue and closes. However when I add: GLuint CreateShader(GLenum eShaderType, const std::string &strShaderFile) { GLuint shader = glCreateShader(eShaderType); std::cout << "Create Shader" << std::endl; ... It gives the error: 'Unhandled exception at 0x73AECB49 in OpenGL Project.exe: 0xC0000005: Access violation executing location 0x00000000.' I read that it could be to do with a lack of OGL context but I think that is created in glutInit() so I have no idea. I would be grateful if someone would help. Thanks in advance.
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!