- bugfixes to avoid segfault when user has no sound card or openal cannot init

- more fallback handling for non power of two textures
This commit is contained in:
Mark Vejvoda 2011-05-18 17:54:46 +00:00
parent 93767d8ed8
commit ae47b47bc8
3 changed files with 92 additions and 38 deletions

View File

@ -51,8 +51,13 @@ void checkGlExtension(const char *extensionName);
void inline _assertGl(const char *file, int line, GLenum *forceErrorNumber = NULL) { void inline _assertGl(const char *file, int line, GLenum *forceErrorNumber = NULL) {
GLenum error = (forceErrorNumber != NULL ? *forceErrorNumber : glGetError()); GLenum error = (forceErrorNumber != NULL ? *forceErrorNumber : glGetError());
if(error != GL_NO_ERROR) { if(error != GL_NO_ERROR) {
const char *errorString= reinterpret_cast<const char*>(gluErrorString(error)); //if(error != GL_INVALID_ENUM) {
throw runtime_error("OpenGL error #" + intToStr(error) + " : " + string(errorString) + " at file: " + string(file) + ", line " + intToStr(line)); const char *errorString= reinterpret_cast<const char*>(gluErrorString(error));
char szBuf[4096]="";
sprintf(szBuf,"OpenGL error #%d [0x%X] : [%s] at file: [%s], line: %d",error,error,errorString,file,line);
//throw runtime_error("OpenGL error #" + intToStr(error) + " : " + string(errorString) + " at file: " + string(file) + ", line " + intToStr(line));
throw runtime_error(szBuf);
//}
} }
} }

View File

@ -17,7 +17,7 @@
#include <algorithm> #include <algorithm>
#include "util.h" #include "util.h"
#ifdef WIN32 #ifdef WIN32
#include "glext.h" #include "glext.h"
#endif #endif
#include "leak_dumper.h" #include "leak_dumper.h"
@ -32,7 +32,24 @@ using namespace std;
#define GL_RENDERBUFFER_EXT 0x8D41 #define GL_RENDERBUFFER_EXT 0x8D41
#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 #define GL_DEPTH_ATTACHMENT_EXT 0x8D00
#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 #define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
typedef void (APIENTRY * PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint* framebuffers); typedef void (APIENTRY * PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); typedef void (APIENTRY * PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); typedef GLenum (APIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); typedef void (APIENTRY * PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint* framebuffers); typedef void (APIENTRY * PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint* renderbuffers); typedef void (APIENTRY * PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); typedef void (APIENTRY * PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRY * PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRY * PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); typedef void (APIENTRY * PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint* renderbuffers); typedef void (APIENTRY * PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); typedef void (APIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); typedef void (APIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params); typedef GLboolean (APIENTRY * PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); typedef GLboolean (APIENTRY * PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); typedef void (APIENTRY * PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
typedef void (APIENTRY * PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint* framebuffers);
typedef void (APIENTRY * PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer);
typedef void (APIENTRY * PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer);
typedef GLenum (APIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target);
typedef void (APIENTRY * PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint* framebuffers);
typedef void (APIENTRY * PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint* renderbuffers);
typedef void (APIENTRY * PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
typedef void (APIENTRY * PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
typedef void (APIENTRY * PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
typedef void (APIENTRY * PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
typedef void (APIENTRY * PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint* renderbuffers);
typedef void (APIENTRY * PFNGLGENERATEMIPMAPEXTPROC) (GLenum target);
typedef void (APIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params);
typedef void (APIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint* params);
typedef GLboolean (APIENTRY * PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer);
typedef GLboolean (APIENTRY * PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer);
typedef void (APIENTRY * PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT = NULL; PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT = NULL;
PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT = NULL; PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT = NULL;
@ -67,31 +84,31 @@ static void setupGLExtensionMethods() {
//glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)SDL_GL_GetProcAddress("glDeleteFramebuffersEXT"); //glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)SDL_GL_GetProcAddress("glDeleteFramebuffersEXT");
//glCheckFramebufferStatusEXT= (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT"); //glCheckFramebufferStatusEXT= (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT");
if(isGlExtensionSupported("GL_EXT_framebuffer_object")) { if(isGlExtensionSupported("GL_EXT_framebuffer_object")) {
//glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC)wglGetProcAddress("glIsRenderbufferEXT"); //glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC)wglGetProcAddress("glIsRenderbufferEXT");
glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)wglGetProcAddress("glBindRenderbufferEXT"); glBindRenderbufferEXT = (PFNGLBINDRENDERBUFFEREXTPROC)wglGetProcAddress("glBindRenderbufferEXT");
glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)wglGetProcAddress("glDeleteRenderbuffersEXT"); glDeleteRenderbuffersEXT = (PFNGLDELETERENDERBUFFERSEXTPROC)wglGetProcAddress("glDeleteRenderbuffersEXT");
glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)wglGetProcAddress("glGenRenderbuffersEXT"); glGenRenderbuffersEXT = (PFNGLGENRENDERBUFFERSEXTPROC)wglGetProcAddress("glGenRenderbuffersEXT");
glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)wglGetProcAddress("glRenderbufferStorageEXT"); glRenderbufferStorageEXT = (PFNGLRENDERBUFFERSTORAGEEXTPROC)wglGetProcAddress("glRenderbufferStorageEXT");
//glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)wglGetProcAddress("glGetRenderbufferParameterivEXT"); //glGetRenderbufferParameterivEXT = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)wglGetProcAddress("glGetRenderbufferParameterivEXT");
//glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC)wglGetProcAddress("glIsFramebufferEXT"); //glIsFramebufferEXT = (PFNGLISFRAMEBUFFEREXTPROC)wglGetProcAddress("glIsFramebufferEXT");
glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)wglGetProcAddress("glBindFramebufferEXT"); glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)wglGetProcAddress("glBindFramebufferEXT");
glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)wglGetProcAddress("glDeleteFramebuffersEXT"); glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)wglGetProcAddress("glDeleteFramebuffersEXT");
glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)wglGetProcAddress("glGenFramebuffersEXT"); glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)wglGetProcAddress("glGenFramebuffersEXT");
glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)wglGetProcAddress("glCheckFramebufferStatusEXT"); glCheckFramebufferStatusEXT = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)wglGetProcAddress("glCheckFramebufferStatusEXT");
//glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)wglGetProcAddress("glFramebufferTexture1DEXT"); //glFramebufferTexture1DEXT = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)wglGetProcAddress("glFramebufferTexture1DEXT");
glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)wglGetProcAddress("glFramebufferTexture2DEXT"); glFramebufferTexture2DEXT = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)wglGetProcAddress("glFramebufferTexture2DEXT");
//glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)wglGetProcAddress("glFramebufferTexture3DEXT"); //glFramebufferTexture3DEXT = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)wglGetProcAddress("glFramebufferTexture3DEXT");
glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)wglGetProcAddress("glFramebufferRenderbufferEXT"); glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)wglGetProcAddress("glFramebufferRenderbufferEXT");
//glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)wglGetProcAddress("glGetFramebufferAttachmentParameterivEXT"); //glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)wglGetProcAddress("glGetFramebufferAttachmentParameterivEXT");
//glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)wglGetProcAddress("glGenerateMipmapEXT"); //glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)wglGetProcAddress("glGenerateMipmapEXT");
if(!glBindRenderbufferEXT || !glDeleteRenderbuffersEXT || !glGenRenderbuffersEXT || if(!glBindRenderbufferEXT || !glDeleteRenderbuffersEXT || !glGenRenderbuffersEXT ||
!glRenderbufferStorageEXT || !glBindFramebufferEXT || !glDeleteFramebuffersEXT || !glRenderbufferStorageEXT || !glBindFramebufferEXT || !glDeleteFramebuffersEXT ||
!glGenFramebuffersEXT || !glCheckFramebufferStatusEXT || !glFramebufferTexture2DEXT || !glGenFramebuffersEXT || !glCheckFramebufferStatusEXT || !glFramebufferTexture2DEXT ||
!glFramebufferRenderbufferEXT) { !glFramebufferRenderbufferEXT) {
glGenFramebuffersEXT = NULL; glGenFramebuffersEXT = NULL;
} }
} }
} }
@ -808,10 +825,14 @@ void Texture2DGl::init(Filter filter, int maxAnisotropy) {
glGenTextures(1, &handle); glGenTextures(1, &handle);
glBindTexture(GL_TEXTURE_2D, handle); glBindTexture(GL_TEXTURE_2D, handle);
assertGl();
//wrap params //wrap params
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap);
assertGl();
//maxAnisotropy //maxAnisotropy
if(isGlExtensionSupported("GL_EXT_texture_filter_anisotropic")) { if(isGlExtensionSupported("GL_EXT_texture_filter_anisotropic")) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy);
@ -895,6 +916,8 @@ void Texture2DGl::init(Filter filter, int maxAnisotropy) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
assertGl();
if ( !(count_bits_set(pixmap.getW()) == 1 && count_bits_set(pixmap.getH()) == 1) && if ( !(count_bits_set(pixmap.getW()) == 1 && count_bits_set(pixmap.getH()) == 1) &&
TextureGl::enableATIHacks == true) { TextureGl::enableATIHacks == true) {
// && (!GLEW_ARB_texture_non_power_of_two || (globalRendering->atiHacks && nearest)) ) { // && (!GLEW_ARB_texture_non_power_of_two || (globalRendering->atiHacks && nearest)) ) {
@ -932,6 +955,20 @@ void Texture2DGl::init(Filter filter, int maxAnisotropy) {
} }
} }
} }
else if(error != GL_NO_ERROR) {
glTexImage2D(GL_TEXTURE_2D, 0, glInternalFormat, pot(pixmap.getW()),
pot(pixmap.getH()), 0, glFormat, GL_UNSIGNED_BYTE, NULL);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixmap.getW(), pixmap.getH(),
glFormat, GL_UNSIGNED_BYTE, pixels);
GLint error3= glGetError();
if(error3 == GL_NO_ERROR) {
error = GL_NO_ERROR;
}
}
// //
//throw runtime_error("TEST!"); //throw runtime_error("TEST!");

View File

@ -347,10 +347,17 @@ SoundPlayerOpenAL::~SoundPlayerOpenAL() {
void SoundPlayerOpenAL::printOpenALInfo() void SoundPlayerOpenAL::printOpenALInfo()
{ {
printf("OpenAL Vendor: %s\n",alGetString(AL_VENDOR));
printf("OpenAL Version: %s\n",alGetString(AL_VERSION));
printf("OpenAL Renderer: %s\n",alGetString(AL_RENDERER));
printf("OpenAL Extensions: %s\n",alGetString(AL_RENDERER));
/*
std::cout << "OpenAL Vendor: " << alGetString(AL_VENDOR) << "\n" std::cout << "OpenAL Vendor: " << alGetString(AL_VENDOR) << "\n"
<< "OpenAL Version: " << alGetString(AL_VERSION) << "\n" << "OpenAL Version: " << alGetString(AL_VERSION) << "\n"
<< "OpenAL Renderer: " << alGetString(AL_RENDERER) << "\n" << "OpenAL Renderer: " << alGetString(AL_RENDERER) << "\n"
<< "OpenAl Extensions: " << alGetString(AL_RENDERER) << "\n"; << "OpenAl Extensions: " << alGetString(AL_RENDERER) << "\n";
*/
} }
bool SoundPlayerOpenAL::init(const SoundPlayerParams* params) { bool SoundPlayerOpenAL::init(const SoundPlayerParams* params) {
@ -370,7 +377,7 @@ bool SoundPlayerOpenAL::init(const SoundPlayerParams* params) {
char *deviceName = getenv("MEGAGLEST_SOUND_DEVICE"); char *deviceName = getenv("MEGAGLEST_SOUND_DEVICE");
device = alcOpenDevice(deviceName); device = alcOpenDevice(deviceName);
if(device == 0) { if(device == 0) {
printOpenALInfo(); //printOpenALInfo();
throw std::runtime_error("Couldn't open audio device."); throw std::runtime_error("Couldn't open audio device.");
} }
@ -611,20 +618,25 @@ StreamSoundSource* SoundPlayerOpenAL::findStreamSoundSource() {
void SoundPlayerOpenAL::checkAlcError(string message) { void SoundPlayerOpenAL::checkAlcError(string message) {
int err = alcGetError(device); int err = alcGetError(device);
if(err != ALC_NO_ERROR) { if(err != ALC_NO_ERROR) {
std::stringstream msg; char szBuf[4096]="";
msg << message.c_str() << alcGetString(device, err); sprintf(szBuf,"%s [%s]",message.c_str(),alcGetString(device, err));
printf("openalc error [%s]\n",message.c_str());
throw std::runtime_error(msg.str()); //std::stringstream msg;
//msg << message.c_str() << alcGetString(device, err);
printf("openalc error [%s]\n",szBuf);
throw std::runtime_error(szBuf);
} }
} }
void SoundPlayerOpenAL::checkAlError(string message) { void SoundPlayerOpenAL::checkAlError(string message) {
int err = alGetError(); int err = alGetError();
if(err != AL_NO_ERROR) { if(err != AL_NO_ERROR) {
std::stringstream msg; char szBuf[4096]="";
msg << message.c_str() << alGetString(err); sprintf(szBuf,"%s [%s]",message.c_str(),alGetString(err));
printf("openal error [%s]\n",message.c_str()); //std::stringstream msg;
throw std::runtime_error(msg.str()); //msg << message.c_str() << alGetString(err);
printf("openal error [%s]\n",szBuf);
throw std::runtime_error(szBuf);
} }
} }