0

我正在使用GLFW(静态链接库 - glfw.lib)并GLEW在我的项目中,但现在我遇到了一个问题:
我编写了一个最简单的GLFW程序(glfwInit(), glfwOpenWindow(), ..., ),除了打开一个黑色窗口、调用和主循环glewInit()之外什么都不做glewInit()只有glfwSwapBuffers(),然后它运行正常。但是当我为加载着色器添加一个类(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这样就好了。

我的调用堆栈是:

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++

是的,我对这个问题一无所知,我还没有创建任何类实例,我的类只有加载着色器、链接程序、使用、释放着色器、设置统一的一些方法。谁能帮我这个?

更新:我的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 扩展,但问题仍然存在...

4

1 回答 1

0

我遇到了同样的问题,但它现在可以通过解决以下警告来工作。 如何防止宏重新定义 我希望它对你有用。

于 2013-04-04T04:42:30.200 回答