Carsten Zarbock
Carsten Zarbock

Reputation: 131

OpenGL Redbook - LoadShaders broken?

i'm trying to build the first example of the "OpenGL Redbook". Well, is it just me, or is their 3rd party LoadShaders broken?

error LNK2001: unresolved external symbol _LoadShaders

No clue what to do...

Upvotes: 1

Views: 2009

Answers (3)

Saad Amin
Saad Amin

Reputation: 33

Sorry for the late reply, the way I solved the LNK2001 error was to have the files themselves to be part of my VS solution

Upvotes: 1

Stephen Foster
Stephen Foster

Reputation: 793

I also had the same issue you describe...

You can use this as a work around to load your shaders!

The parameters are different to the book but it will work, Just put the vertex and fragment shader code into text files where your main.cpp is, then instantiate a Shader object and call .LoadShader(vertexShaderFileName, fragmentShaderFileName);

Header:

#pragma once
#include <vgl.h>
#include <string>
using namespace std;

class Shader
{
public:
    Shader(void);
    ~Shader(void);

    GLuint LoadShader(const char* vertPath, const char* fragPath);
private:
    string ReadFile(const char* path);
};

CPP:

#include "Shader.h"
#include <iostream>
#include <fstream>
#include <vector>

Shader::Shader(void) {
}


Shader::~Shader(void) {
}

// read a file and return as a string
string Shader::ReadFile(const char* path) { 
    string content;
    ifstream fileStream(path, ios::in);

    if (!fileStream.is_open()) { 
        cerr << "File could not be opened" << endl;
        return "";
    }

    string line = "";
    while (!fileStream.eof()) { 
        getline(fileStream, line);
        content.append(line + "\n");
    }

    fileStream.close();
    return content;
}

GLuint Shader::LoadShader(const char* vertPath, const char* fragPath) { 
    //generate shader names
    GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
    GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);

    //get shader src
    string vertShaderStr = ReadFile(vertPath);
    string fragShaderStr = ReadFile(fragPath);

    const char* vertShaderSrc = vertShaderStr.c_str();
    const char* fragShaderSrc = fragShaderStr.c_str();

    GLint result = GL_FALSE;
    int logLength;

    //compile vertex shader
    glShaderSource(vertShader, 1, &vertShaderSrc, NULL);
    glCompileShader(vertShader);
    glGetShaderiv(vertShader, GL_COMPILE_STATUS, &result);
    glGetShaderiv(vertShader, GL_INFO_LOG_LENGTH, &logLength);
    vector<char> vertShaderError(logLength);
    glGetShaderInfoLog(vertShader, logLength, NULL, &vertShaderError[0]);
    cout << &vertShaderError[0] << endl;

    //compile fragment shader
    glShaderSource(fragShader, 1, &fragShaderSrc, NULL);
    glCompileShader(fragShader);
    glGetShaderiv(fragShader, GL_COMPILE_STATUS, &result);
    glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logLength);
    vector<char> fragShaderError(logLength);
    glGetShaderInfoLog(fragShader, logLength, NULL, &fragShaderError[0]);
    cout << &fragShaderError[0] << endl; 

    //link the program
    GLuint program = glCreateProgram();
    glAttachShader(program, vertShader);
    glAttachShader(program, fragShader);
    glLinkProgram(program);

    glGetProgramiv(program, GL_LINK_STATUS, &result);
    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
    vector<char> programError(logLength > 1 ? logLength : 1);
    glGetProgramInfoLog(program, logLength, NULL, &programError[0]);
    cout << &programError[0] << endl;

    glDeleteShader(vertShader);
    glDeleteShader(fragShader);

    return program;
}

Upvotes: 0

Pulseczar
Pulseczar

Reputation: 150

Add LoadShaders.cpp, located in oglpg-8th-edition/lib, to your project/compilation. Good luck getting past that, though. Once finally getting through compilation and linking, I have yet to get the example to work right. You'd think they'd include some instructions, rather than just "here's the code".

Upvotes: 2

Related Questions