我使用GLFW
(静态链接库 - glfw.lib
),并在我的项目GLEW
,但现在我有一个问题:
我写一个简单的程序GLFW
(glfwInit()
,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.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扩展,但还是这里的问题。 ..
一些源代码会很好。几年前,我不得不寄回当时有缺陷的水晶球进行维修,但从未还原过,因为缺陷仍然存在;) – datenwolf
@datenwolf:感谢您的快速回复,我刚刚更新了代码,那么,您是否是'glew '或'glfw'作者? –
这真的很好奇。你的班级看起来不错,没有任何可能触发奇怪事情的事件。 glfwOpenWindow中的某些内容通过无效指针跳过。只是一个建议:GLFW是开源的,那么你如何自己编译它,并带有调试符号,这样你就可以在你的系统上单步执行程序,因为我无法重现它(我现在正在Linux框)。 – datenwolf