我在项目中使用GLFW
(静态链接库 - glfw.lib
)和GLEW
,但现在我遇到了问题:
我写了一个最简单的GLFW
程序(glfwInit()
,glfwOpenWindow()
,...,glewInit()
),除了打开黑色窗口外,什么都不做,调用glewInit()
和main循环只包含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
,那就没关系。
我的调用堆栈是:
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.h
和cshader.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扩展,但问题仍然存在......