【问题标题】:GLFW, GLEW and "my class" issueGLFW、GLEW 和“我的班级”问题
【发布时间】:2013-02-03 16:11:50
【问题描述】:

我在我的项目中使用GLFW(静态链接库-glfw.lib)和GLEW,但现在我遇到了问题:
我写了一个最简单的GLFW 程序(glfwInit()glfwOpenWindow(),...,glewInit()),除了打开一个黑色窗口,调用glewInit() 和只包含glfwSwapBuffers() 的主循环,然后它什么都不做运行确定。但是当我为加载着色器添加一个类(cshader.hcshader.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 扩展,但问题仍然存在...

【问题讨论】:

  • 一些源代码会很好。几年前,我不得不将当时有缺陷的水晶球送去维修,但再也没有拿回来,因为缺陷仍然存在;)
  • @datenwolf:感谢您的快速回复,我刚刚更新了代码,那么,您是glew还是glfw作者?
  • 这真的很好奇。您的课程看起来不错,没有继承可能引发怪异的东西。 glfwOpenWindow 中的某些内容会绊倒无效的指针。只是一个建议:GLFW 是开源的,那么您如何自己编译它,使用调试符号,这样您就可以在您的系统上单步执行该程序,因为我无法重现它(我现在处于Linux 盒子)。
  • @datenwolf:也感谢您的关注和建议,我仍然不知道为什么如果 cshader.cpp 被排除在项目之外,那么它运行良好没有任何问题:-(
  • 将这些粘贴箱的内容编辑到问题本身中。 Pastebins 会死,所以不会。

标签: opengl glew glfw


【解决方案1】:

我遇到了同样的问题,但它现在可以通过解决以下警告来解决。 How to prevent macro redefinition 我希望它对你有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 1970-01-01
    • 2023-03-08
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多