2013-02-03 31 views
0

我使用GLFW(静态链接库 - glfw.lib),并在我的项目GLEW,但现在我有一个问题:
我写一个简单的程序GLFWglfwInit()glfwOpenWindow(), ...,glewInit()),除了打开一个黑色的窗口,除了调用glewInit()和仅包含glfwSwapBuffers()的主循环之外什么也不做,然后运行Ok。但是当我为加载着色器添加一个类(cshader.h,cshader.cpp)(没有特殊的类,没有静态变量,没有静态方法,还没有创建任何实例,所以,我只拖放两个文件到Visual Studio工作空间窗口),然后重建,然后按F5,Visual Studio显示sfs.exe has triggered a breakpoint.消息并在msvcr110d.dll!_CrtIsValidHeapPointer(const void * pUserData) Line 2036 C++中断。但如果我更改为Release那么它很好。GLFW,GLEW和“我的课”的问题

我的调用堆栈是:

msvcr110d.dll!_CrtIsValidHeapPointer(const void * pUserData) Line 2036 C++ 
msvcr110d.dll!_free_dbg_nolock(void * pUserData, int nBlockUse) Line 1322 C++ 
msvcr110d.dll!_free_dbg(void * pUserData, int nBlockUse) Line 1265 C++ 
msvcr110d.dll!free(void * pUserData) Line 49 C++ 
sfs.exe!__glfwPlatformWaitEvents() Unknown 
sfs.exe!__glfwPlatformWaitEvents() Unknown 
sfs.exe!__glfwPlatformOpenWindow() Unknown 
sfs.exe!_glfwOpenWindow() Unknown 
sfs.exe!main(int argc, char * * argv) Line 54 C++ 

是的,我没有IDE这个问题,我还没有创建任何类实例的是,我的课只对负载着色器,链接程序,使用一些方法,释放着色器,设置制服。任何人都可以帮助我吗?

更新:cshader.hcshader.cpp是:

// cshader.h 
#ifndef __CShader_h__ 
#define __CShader_h__ 

#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <GL/gl.h> 

class CShader 
{ 
protected: 
    GLuint m_FragmentShader; 
    GLuint m_VertexShader; 
    GLuint m_Program; 

    bool readTextFile(const char *name, std::string& text); 
    GLuint createShader(const char *name, GLenum type); 

public: 
    CShader(); 
    CShader(const char *vertex, const char *fragment); 
    ~CShader(); 

    bool loadVertexShader(const char *vertex); 
    bool loadFragmentShader(const char *fragment); 
    bool link(); 
    void use(); 
    void end(); 
    GLint getUniformLocation(const char *name); 
    GLint getAttribLocation(const char *name); 
    void uni4x4Matrix(const char *name, float *matrix); 
    void uni1i(const char *name, GLuint value); 

    void enableAttrib(const char *name); 
    void enableAttrib(GLint attrib); 

    void disableAttrib(const char *name); 
    void disableAttrib(GLint attrib); 
}; 

#endif /* __CShader_h__ */ 


// cshader.cpp 
#include <gl/glew.h> 
#include "cshader.h" 

bool CShader::readTextFile(const char *name, std::string& text) { 
    std::ifstream in; 

    in.open(name, std::ios::in); 
    if (in.fail()) { 
    std::cout << "CShader::readTextFile(\"" << name << "\") false" << std::endl; 
    return false; 
    } 

    std::ostringstream data; 
    data << in.rdbuf(); 
    text = data.str(); 
    in.close(); 

    return true; 
} 

GLuint CShader::createShader(const char *name, GLenum type) { 
    std::string text, shader_type; 
    const char *source; 
    GLuint shader; 

    switch(type) { 
    case GL_VERTEX_SHADER: 
    shader_type = "GL_VERTEX_SHADER"; 
    break; 

    case GL_FRAGMENT_SHADER: 
    shader_type = "GL_FRAGMENT_SHADER"; 
    break; 

    default: 
    shader_type = "UNKNOW_SHADER"; 
    } 

    if (!readTextFile(name, text)) return 0; 
    source = text.c_str(); 

    shader = glCreateShader(type); 
    glShaderSource(shader, 1, &source, 0); 
    glCompileShader(shader); 

    GLint is_compiled; 
    glGetShaderiv(shader, GL_COMPILE_STATUS, &is_compiled); 
    if (GL_FALSE == is_compiled) { 
    std::cout << "CShader::createShader(): Compile " << shader_type << " (" << name << ") error:" << std::endl; 
    int errLen, errRet; 
    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &errLen); 

    char *errMsg = new char[errLen + 1]; 
    glGetShaderInfoLog(shader, errLen, &errRet, errMsg); 
    std::cout << errMsg << std::endl; 
    delete [] errMsg; 

    glDeleteShader(shader); 
    return 0; 
    } 

    return shader; 
} 

CShader::CShader() { 
    m_FragmentShader = 0; 
    m_VertexShader = 0; 
    m_Program = 0; 
} 

CShader::CShader(const char *vertex, const char *fragment) { 
    m_FragmentShader = 0; 
    m_VertexShader = 0; 
    m_Program = 0; 

    loadVertexShader(vertex); 
    loadFragmentShader(fragment); 
} 

CShader::~CShader() { 
    if (m_Program > 0) { 
    glDetachShader(m_Program, m_VertexShader); 
    glDetachShader(m_Program, m_FragmentShader); 
    glDeleteProgram(m_Program); 
    } 

    if (m_VertexShader > 0) glDeleteShader(m_VertexShader); 
    if (m_FragmentShader > 0) glDeleteShader(m_FragmentShader); 
} 

bool CShader::loadVertexShader(const char *vertex) { 
    if (m_VertexShader > 0) glDeleteShader(m_VertexShader); 

    m_VertexShader = createShader(vertex, GL_VERTEX_SHADER); 
    return (m_VertexShader > 0) ? (true) : (false); 
} 

bool CShader::loadFragmentShader(const char *fragment) { 
    if (m_FragmentShader > 0) glDeleteShader(m_FragmentShader); 

    m_FragmentShader = createShader(fragment, GL_FRAGMENT_SHADER); 
    return (m_FragmentShader > 0) ? (true) : (false); 
} 

bool CShader::link() { 
    if (m_VertexShader <= 0 || m_FragmentShader <= 0) return false; 
    if (m_Program > 0) { 
    std::cout << "Program have already linked!" << std::endl; 
    return false; 
    } 

    m_Program = glCreateProgram(); 
    glAttachShader(m_Program, m_VertexShader); 
    glAttachShader(m_Program, m_FragmentShader); 
    glLinkProgram(m_Program); 

    GLint is_Linked; 
    glGetProgramiv(m_Program, GL_LINK_STATUS, &is_Linked); 
    if (GL_FALSE == is_Linked) { 
    std::cout << "CShader::link() got error:" << std::endl; 

    int errLen, errRet; 
    glGetProgramiv(m_Program, GL_INFO_LOG_LENGTH, &errLen); 

    char * errMsg = new char[errLen + 1]; 
    glGetProgramInfoLog(m_Program, errLen, &errRet, errMsg); 
    std::cout << errMsg << std::endl; 
    delete [] errMsg; 

    glDetachShader(m_Program, m_VertexShader); 
    glDetachShader(m_Program, m_FragmentShader); 
    glDeleteProgram(m_Program); 
    m_Program = 0; 
    return false; 
    } 

    return true; 
} 

void CShader::use() { 
    if (m_Program <= 0) { 
    std::cout << "CShader::use(): Program not ready!" << std::endl; 
    return; 
    } 

    glUseProgram(m_Program); 
} 

void CShader::end() { 
    glUseProgram(0); 
} 

GLint CShader::getUniformLocation(const char *name) { 
    if (m_Program <= 0) return -1; 
    return glGetUniformLocation(m_Program, name); 
} 

GLint CShader::getAttribLocation(const char *name) { 
    if (m_Program <= 0) return -1; 
    return glGetAttribLocation(m_Program, name); 
} 

void CShader::uni4x4Matrix(const char *name, float *matrix) { 
    GLint matLoc = getUniformLocation(name); 
    if (matLoc >= 0) { 
    glUniformMatrix4fv(matLoc, 1, GL_FALSE, matrix); 
    } else { 
    std::cout << "CShader::uni4x4Matrix(): " << name << " uniform not found!" << std::endl; 
    } 
} 

void CShader::uni1i(const char *name, GLuint value) { 
    GLint matLoc = getUniformLocation(name); 
    if (matLoc >= 0) { 
    glUniform1i(matLoc, value); 
    } else { 
    std::cout << "CShader::uni1i(): " << name << " uniform not found!" << std::endl; 
    } 
} 

void CShader::enableAttrib(const char *name) { 
    GLint attribLoc = getAttribLocation(name); 
    if (attribLoc < 0) { 
    std::cout << "CShader::enableAttrib(): " << name << " attrib not found!" << std::endl; 
    } else { 
    enableAttrib(attribLoc); 
    } 
} 

void CShader::enableAttrib(GLint attrib) { 
    glEnableVertexAttribArray(attrib); 
} 

void CShader::disableAttrib(const char *name) { 
    GLint attribLoc = getAttribLocation(name); 
    if (attribLoc < 0) { 
    std::cout << "CShader::disableAttrib(): " << name << " attrib not found!" << std::endl; 
    } else { 
    disableAttrib(attribLoc); 
    } 
} 

void CShader::disableAttrib(GLint attrib) { 
    glDisableVertexAttribArray(attrib); 
} 

main.cpp

#include <iostream> 
#include <gl/glew.h> 
#include "cshader.h" 

#include <gl/glfw.h> 

#pragma comment(lib, "glfw.lib") 
#pragma comment(lib, "opengl32.lib") 
#pragma comment(lib, "glew32.lib") 

using namespace std; 


void GLFWCALL reshape(int w, int h) 
{ 
} 

void display() 
{ 

} 

bool init() 
{ 

    return true; 
} 

int main(int argc, char *argv[]) 
{ 
    if (glfwInit() != GL_TRUE) { 
     cout << "glfwInit() return false!" << endl; 
     cin.get(); 
     return -1; 
    } 

    glfwOpenWindowHint(GLFW_WINDOW_NO_RESIZE, GL_TRUE); 
    if(glfwOpenWindow(640, 480, 0, 0, 0, 0, 16, 1, GLFW_WINDOW) != GL_TRUE) { 
     cout << "Open window fail!" << endl; 
     glfwTerminate(); 
     return -1; 
    } 

    if (glewInit() != GLEW_OK) { 
     cout << "load opengl functions failed!" << endl; 
     glfwTerminate(); 
     return -1; 
    } 

    glfwSetWindowTitle("Shadow from scratch..."); 
    if (!init()) { 
     cout << "init() return false!" << endl; 
     glfwTerminate(); 
     return -1; 
    } 

    glfwSetWindowSizeCallback(&reshape); 
    reshape(640, 480); 

    bool running = true; 
    while (running) { 
     display(); 
     glfwSwapBuffers(); 

     running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam(GLFW_OPENED); 
    } 

    glfwTerminate(); 
    return 0; 
} 

更新2:我已经更改为glLoadGen加载OpenGL扩展,但还是这里的问题。 ..

+2

一些源代码会很好。几年前,我不得不寄回当时有缺陷的水晶球进行维修,但从未还原过,因为缺陷仍然存在;) – datenwolf

+0

@datenwolf:感谢您的快速回复,我刚刚更新了代码,那么,您是否是'glew '或'glfw'作者? –

+0

这真的很好奇。你的班级看起来不错,没有任何可能触发奇怪事情的事件。 glfwOpenWindow中的某些内容通过无效指针跳过。只是一个建议:GLFW是开源的,那么你如何自己编译它,并带有调试符号,这样你就可以在你的系统上单步执行程序,因为我无法重现它(我现在正在Linux框)。 – datenwolf

回答