带有 SDL 和 GLEW 的 OpenGL,错误:48
Posted
技术标签:
【中文标题】带有 SDL 和 GLEW 的 OpenGL,错误:48【英文标题】:OpenGL with SDL and GLEW, error:48 【发布时间】:2016-01-04 23:08:16 【问题描述】:我开始按照这个教程制作一个小的 OpenGL 程序:
https://www.youtube.com/watch?v=I4az5VDpxVw&index=14&list=PLSPw4ASQYyymu3PfG9gxywSPghnSMiOAW
在我学习教程 11 之前一切正常。从那时起,它确实构建得很好,但是当我想运行编译后的程序时,它只是输出
error: 48
在控制台中并立即关闭。
所以我做了一些研究,但我没有发现其他人有这个问题,我发现的只是:
msdn.microsoft.com/en-us/library/aa232611(v=vs.60).aspx
我什至不确定这是否与我的问题有关。
奇怪的是,这从来没有发生过,这个问题第一次出现,当我来到播放列表中的教程 11 时,添加了 picoPNG 并编写了代码来为我加载 png 文件。在添加 picoPNG 时,我也遇到了一些错误,提示“尚未声明 size_t”,但我通过添加该行修复了该问题
#include <stddef.h>
在 picoPNG.cpp 的顶部。
我在 Windows 10 上使用 Eclipse CDT 8.8.0 和 MinGW w32 20150801、glew 1.13.0(我用 MinGW 编译了源代码)和 SDL2 2.0.4。
我用 MinGW 编译 GLEW 的命令是:
gcc -DGLEW_NO_GLU -O2 -Wall -W -Iinclude -DGLEW_BUILD -o src/glew.o -c src/glew.c
gcc -shared -Wl,-soname,libglew32.dll -Wl,--out-implib,lib/libglew32.dll.a -o lib/glew32.dll src/glew.o -L/mingw/lib -lglu32 -lopengl32 -lgdi32 -luser32 -lkernel32
ar cr lib/libglew32.a src/glew.o
gcc -DGLEW_NO_GLU -DGLEW_MX -O2 -Wall -W -Iinclude -DGLEW_BUILD -o src/glew.mx.o -c src/glew.c
gcc -shared -Wl,-soname,libglew32mx.dll -Wl,--out-implib,lib/libglew32mx.dll.a -o lib/glew32mx.dll src/glew.mx.o -L/mingw/lib -lglu32 -lopengl32 -lgdi32 -luser32 -lkernel32
ar cr lib/libglew32mx.a src/glew.mx.o
(我使用位于 glew-1.13.0 文件夹中的批处理文件执行此操作)
我实际上遵循了教程播放列表,我在上面放置了教程 12 的链接,这就是我再次构建程序并在它一切正常之后第一次启动它的地方。
为什么会这样?该输出背后的问题可能是什么?
编辑:这是我所有的代码
main.cpp
#include <iostream>
#include <SDL.h>
#include <glew.h>
#include <MainGame.h>
using namespace std;
int main(int argc, char* argv[])
MainGame mainGame;
mainGame.Run("Game Engine");
return 0;
GLSLProgram.h
#ifndef CLASSES_GLSLPROGRAM_H_
#define CLASSES_GLSLPROGRAM_H_
#include <string>
#include <glew.h>
class GLSLProgram
public:
GLSLProgram();
virtual ~GLSLProgram();
void CompileShaders(const std::string& filePath);
void AddAttribute(const std::string& attributeName);
void LinkShaders();
void UseProgram();
void UnUseProgram();
GLint GetUniformLocation(const std::string& uniformName);
private:
GLuint m_programID;
GLuint m_vertexShaderID;
GLuint m_fragmentShaderID;
int m_numAttributes;
void GetShader(const std::string& filePath, const std::string& shaderType, GLuint& shaderID);
;
#endif /* CLASSES_GLSLPROGRAM_H_ */
GLSLProgram.cpp
#include <GLSLProgram.h>
#include <fstream>
#include <vector>
#include "..\Headers\JPKErrors.hpp"
GLSLProgram::GLSLProgram() :
m_programID(0),
m_vertexShaderID(0),
m_fragmentShaderID(0),
m_numAttributes(0)
GLSLProgram::~GLSLProgram()
if(m_vertexShaderID != 0)
glDeleteShader(m_vertexShaderID);
if(m_fragmentShaderID != 0)
glDeleteShader(m_fragmentShaderID);
if(m_programID != 0)
glDeleteProgram(m_programID);
void GLSLProgram::CompileShaders(const std::string& filePath)
m_programID = glCreateProgram();
m_vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
if(m_vertexShaderID == 0)
jpk::FatalError("Vertex shader could not be created!");
m_fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
if(m_fragmentShaderID == 0)
jpk::FatalError("Fragment Shader could not be created!");
GetShader(filePath + ".vsh", "Vertex", m_vertexShaderID);
GetShader(filePath + ".fsh", "Fragment", m_fragmentShaderID);
void GLSLProgram::AddAttribute(const std::string& attributeName)
glBindAttribLocation(m_programID, m_numAttributes++, attributeName.c_str());
void GLSLProgram::LinkShaders()
glAttachShader(m_programID, m_vertexShaderID);
glAttachShader(m_programID, m_fragmentShaderID);
glLinkProgram(m_programID);
GLint isLinked = 0;
glGetProgramiv(m_programID, GL_LINK_STATUS, (int*)&isLinked);
glDetachShader(m_programID, m_vertexShaderID);
glDetachShader(m_programID, m_fragmentShaderID);
if(isLinked == GL_FALSE)
GLint maxLength = 0;
glGetProgramiv(m_programID, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<char> errorLog(maxLength);
glGetProgramInfoLog(m_programID, maxLength, &maxLength, &errorLog[0]);
printf("%s\n", &errorLog[0]);
jpk::FatalError("Shader program failed to link!\nDetails:");
void GLSLProgram::GetShader(const std::string& filePath, const std::string& shaderType, GLuint& shaderID)
std::ifstream shaderFile(filePath);
if(shaderFile.fail())
jpk::FatalError(shaderType + " shader file " + filePath + " could not be opened!", false, true, filePath);
std::string fileContents("");
std::string line;
while(getline(shaderFile, line))
fileContents += line + "\n";
shaderFile.close();
const char* charFileContents = fileContents.c_str();
glShaderSource(shaderID, 1, &charFileContents, nullptr);
glCompileShader(shaderID);
GLint success = 0;
glGetShaderiv(shaderID, GL_COMPILE_STATUS, &success);
if(success == GL_FALSE)
GLint maxLength = 0;
glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<char> errorLog(maxLength);
glGetShaderInfoLog(shaderID, maxLength, &maxLength, &errorLog[0]);
printf("%s\n", &errorLog[0]);
jpk::FatalError(shaderType + " shader file " + filePath + " failed to compile!\nDetails:");
void GLSLProgram::UseProgram()
glUseProgram(m_programID);
for(int i=0; i < m_numAttributes ;i++)
glEnableVertexAttribArray(i);
void GLSLProgram::UnUseProgram()
glUseProgram(0);
for(int i=0; i < m_numAttributes ;i++)
glDisableVertexAttribArray(i);
GLint GLSLProgram::GetUniformLocation(const std::string& uniformName)
GLint location = glGetUniformLocation(m_programID, uniformName.c_str());
if(location == (GLint)GL_INVALID_INDEX)
jpk::FatalError("Uniform \"" + uniformName + "\" was not found in shaders!");
return location;
ImageLoader.h
#ifndef IMAGELOADER_H
#define IMAGELOADER_H
#include "..\Headers\GLTexture.hpp"
#include <string>
class ImageLoader
public:
static GLTexture LoadPNG(const std::string& filePath);
;
#endif /* IMAGELOADER_H */
ImageLoader.cpp
#include <ImageLoader.h>
#include "..\Headers\picoPNG.hpp"
#include "..\Headers\JPKErrors.hpp"
#include "IOManager.h"
#include <iostream>
GLTexture ImageLoader::LoadPNG(const std::string& filePath)
GLTexture texture = ;
std::vector<unsigned char> out, in;
unsigned long width, height;
if(!IOManager::ReadFileToBuffer(filePath, in))
jpk::FatalError("Failed to load .png file \"" + filePath + "\" to buffer!");
int errorCode = decodePNG(out, width, height, &in[0], in.size());
if(errorCode != 0)
jpk::FatalError("Could not decode the .png file \"" + filePath + "\" with error code: " + std::to_string(errorCode));
glGenTextures(1, &texture.ID);
glBindTexture(GL_TEXTURE_2D, texture.ID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.width, texture.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &out[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
texture.width = width;
texture.height = height;
return texture;
IOManager.h
#ifndef IOMANAGER_H
#define IOMANAGER_H
#include <vector>
#include <string>
class IOManager
public:
static bool ReadFileToBuffer(const std::string& filePath, std::vector<unsigned char>& buffer);
;
#endif /* IOMANAGER_H */
IOManager.cpp
#include <IOManager.h>
#include <fstream>
bool IOManager::ReadFileToBuffer(const std::string& filePath, std::vector<unsigned char>& buffer)
std::ifstream file(filePath, std::ios::binary);
if(file.fail())
perror(filePath.c_str());
return false;
file.seekg(0, std::ios::end);
int fileSize = file.tellg();
file.seekg(0, std::ios::beg);
buffer.resize(fileSize);
file.read((char*)&buffer[0], fileSize);
file.close();
return true;
MainGame.h
#ifndef MAINGAME_H
#define MAINGAME_H
#include <SDL.h>
#include "Sprite.h"
#include "GLSLProgram.h"
#include "..\Headers\GLTexture.hpp"
class MainGame
public:
MainGame();
MainGame(int width, int height);
virtual ~MainGame();
void Run(const char* windowTitle);
private:
enum class GameState PLAY, EXIT;
SDL_Window* m_window;
int m_windowWidth;
int m_windowHeight;
float m_time;
Sprite m_sprite;
GLSLProgram m_colorProgram;
GLTexture m_playerTexture;
void InitSystems(const char* windowTitle);
void GameLoop();
void ProcessInput();
void DrawGame();
void InitShaders();
GameState m_currentGameState;
;
#endif /* MAINGAME_H_ */
MainGame.cpp
#include "MainGame.h"
#include <iostream>
#include <string>
#include <glew.h>
#include <conio.h>
#include "..\Headers\JPKErrors.hpp"
#include <ImageLoader.h>
MainGame::MainGame() :
m_window(nullptr),
m_windowWidth(800),
m_windowHeight(600),
m_time(0),
m_currentGameState(GameState::PLAY)
MainGame::MainGame(int width, int height) :
m_window(nullptr),
m_windowWidth(width),
m_windowHeight(height),
m_time(0),
m_currentGameState(GameState::PLAY)
MainGame::~MainGame()
m_window = nullptr;
SDL_Quit();
void MainGame::Run(const char* windowTitle)
InitSystems(windowTitle);
GameLoop();
void MainGame::InitSystems(const char* windowTitle)
SDL_Init(SDL_INIT_EVERYTHING);
m_window = SDL_CreateWindow(windowTitle, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, m_windowWidth, m_windowHeight, SDL_WINDOW_OPENGL);
if(m_window == nullptr)
jpk::FatalError("SDL Window could not be created!", true);
SDL_GLContext glContext = SDL_GL_CreateContext(m_window);
if(glContext == nullptr)
jpk::FatalError("SDL GL Context could not be created out of m_window!", true);
GLenum error = glewInit();
if(error != GLEW_OK)
jpk::FatalError("CLEW could not be initialized!");
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
m_sprite.Init(-0.75, -0.75, 1.5, 1.5);
m_playerTexture = ImageLoader::LoadPNG("./Files/Images/JimmyJumpPack/PNG/CharacterRight_Standing.png");
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
InitShaders();
void MainGame::ProcessInput()
SDL_Event sdlEvent;
while(SDL_PollEvent(&sdlEvent))
switch(sdlEvent.type)
case SDL_QUIT: m_currentGameState = GameState::EXIT; break;
case SDL_MOUSEMOTION:
std::cout << sdlEvent.motion.x << " " << sdlEvent.motion.y << std::endl;
void MainGame::GameLoop()
while(m_currentGameState != GameState::EXIT)
try
ProcessInput();
m_time += 0.01;
DrawGame();
catch(jpk::FatalErrorException& e)
m_currentGameState = GameState::EXIT;
void MainGame::DrawGame()
glClearDepth(1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_colorProgram.UseProgram();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_playerTexture.ID);
GLint textureLocation = m_colorProgram.GetUniformLocation("textureSampler");
glUniform1i(textureLocation, 0);
m_sprite.Draw();
glBindTexture(GL_TEXTURE_2D, 0);
m_colorProgram.UnUseProgram();
SDL_GL_SwapWindow(m_window);
void MainGame::InitShaders()
m_colorProgram.CompileShaders("./Files/Shaders/textureShader");
m_colorProgram.AddAttribute("vertexPosition");
m_colorProgram.AddAttribute("vertexColor");
m_colorProgram.AddAttribute("vertexUV");
m_colorProgram.LinkShaders();
Sprite.h
#ifndef SPRITE_H_
#define SPRITE_H_
#include <glew.h>
class Sprite
public:
Sprite();
virtual ~Sprite();
void Init(float x, float y, float width, float height);
void Draw();
private:
float m_x;
float m_y;
float m_width;
float m_height;
GLuint m_vertexBufferObjectID;
;
#endif /* SPRITE_H_ */
Sprite.cpp
#include "Sprite.h"
#include "../Headers/JPKVertex.hpp"
#include <cstddef>
Sprite::Sprite() :
m_x(0),
m_y(0),
m_width(0),
m_height(0)
m_vertexBufferObjectID = 0;
Sprite::~Sprite()
if(m_vertexBufferObjectID != 0)
glDeleteBuffers(1, &m_vertexBufferObjectID);
void Sprite::Init(float x, float y, float width, float height)
m_x = x;
m_y = y;
m_width = width;
m_height = height;
if(m_vertexBufferObjectID == 0)
glGenBuffers(1, &m_vertexBufferObjectID);
jpk::Vertex vertexData[6];
vertexData[0].SetPosition(x+width, y+height);
vertexData[0].SetUV(1.0f, 1.0f);
vertexData[1].SetPosition(x, y+height);
vertexData[1].SetUV(0.0f, 1.0f);
vertexData[2].SetPosition(x, y);
vertexData[2].SetUV(0.0f, 0.0f);
vertexData[3].SetPosition(x, y);
vertexData[3].SetUV(0.0f, 0.0f);
vertexData[4].SetPosition(x+width, y);
vertexData[4].SetUV(1.0f, 0.0f);
vertexData[5].SetPosition(x+width, y+height);
vertexData[5].SetUV(1.0f, 1.0f);
for(int i=0; i < 6 ;i++)
vertexData[i].SetColor(255, 0, 255, 255);
vertexData[1].SetColor(0, 0, 255, 255);
vertexData[4].SetColor(0, 255, 0, 255);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferObjectID);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
void Sprite::Draw()
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferObjectID);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(jpk::Vertex), (void*)offsetof(jpk::Vertex, position));
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(jpk::Vertex), (void*)offsetof(jpk::Vertex, color));
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(jpk::Vertex), (void*)offsetof(jpk::Vertex, uv));
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
GLTexture.hpp
#ifndef GLTEXTURE_HPP
#define GLTEXTURE_HPP
#include <glew.h>
struct GLTexture
GLuint ID;
int width;
int height;
;
#endif /* GLTEXTURE_HPP */
JPKErrors.hpp
#ifndef JPKERRORS_HPP
#define JPKERRORS_HPP
#include <string>
#include "JPKExceptions.hpp"
namespace jpk
void FatalError(const std::string& errorString, bool isSDLRelated = false, bool usePError = false, const std::string& file = " ");
#endif //JPKERRORS_HPP
JPKErrors.cpp
#include "JPKErrors.hpp"
#include <iostream>
#include <conio.h>
#include <SDL.h>
#include <missingmingw\mingw.thread.h>
namespace jpk
extern void FatalError(const std::string& errorString, bool isSDLRelated, bool usePError, const std::string& file)
std::cerr << "Fatal Error: " << errorString << std::endl;
if(isSDLRelated)
std::cerr << "SDL Error: " << SDL_GetError();
if(usePError && file != " ")
std::cout << "Error Details: ";
perror(file.c_str());
std::cout << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
std::cout << "This application will now close..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(3));
throw FatalErrorException();
JPKExceptions.hpp
namespace jpk
class FatalErrorException;
JPKVertex.hpp
#ifndef JPKVERTEX_H
#define JPKVERTEX_H
#include <glew.h>
namespace jpk
struct VertexPosition
float x;
float y;
;
struct VertexColor
GLubyte r;
GLubyte g;
GLubyte b;
GLubyte a;
;
struct VertexUV
float u;
float v;
;
struct Vertex
VertexPosition position;
VertexColor color;
VertexUV uv;
void SetColor(GLubyte r, GLubyte g, GLubyte b, GLubyte a)
color.r = r;
color.g = g;
color.b = b;
color.a = a;
void SetPosition(float x, float y)
position.x = x;
position.y = y;
void SetUV(float u, float v)
uv.u = u;
uv.v = v;
;
#endif /* JPKVERTEX_H */
picoPNG.hpp
#ifndef PICOPNG_HPP
#define PICOPNG_HPP
#include <vector>
#include <stddef.h>
extern int decodePNG(std::vector<unsigned char>& out_image, unsigned long& image_width, unsigned long& image_height, const unsigned char* in_png, size_t in_size, bool convert_to_rgba32 = true);
#endif /* PICOPNG_HPP */
而且 picoPNG.cpp 太大而无法放入此处,因此,这里是我下载 picoPNG 的链接:
http://lodev.org/lodepng/
我自己也做了一些调试,添加了一行
std::cout << "Test" << std::endl;
在所有其他代码之前的 int main() 顶部。即使那没有被放到控制台中,只是我上面描述的错误消息。
【问题讨论】:
您好,欢迎来到 ***。请直接在您的问题中添加一些代码,以促进问题的解决。否则你会被否决。 你试过在调试器中运行它吗? @Mr_Pouet 是的,当然,但它的代码相当多 @AdrianKrupa 出于某种奇怪的原因,Eclipse CDT 中的内置调试器不起作用,所以我必须自己进行调试。但我这样做了,正如我现在在问题中所描述的那样。 【参考方案1】:你好像用过ImageLoader::LoadPNG("./Files/Images/JimmyJumpPack/PNG/CharacterRight_Standing.png");
尝试使用对我有用的完整文件路径。
(loadPNG("C:\\Users\\...\\filename.png");
)
如果您查看picopng.cpp,您会发现为什么会出现错误:第 259 行的 48:
if(size == 0 || in == 0) error = 48; return; //the given data is empty
所以它肯定没有找到文件。
【讨论】:
【参考方案2】:picoPNG.cpp
中有一个main
函数!这将与您自己的main
函数发生冲突。所以打开picoPNG.cpp
并注释掉它的main
函数。
【讨论】:
以上是关于带有 SDL 和 GLEW 的 OpenGL,错误:48的主要内容,如果未能解决你的问题,请参考以下文章