OpenEXR + OpenGL unhandled exception - c++

I've had quite a lot problems when trying to execute an example from OpenGL SuperBible 5th ed. from Chapter09/hdr_bloom.
Problems were caused from linking OpenEXR libs so I've build them manualy and replaced them with libs from authors.
Right now, I can manage to run the program but I get unhandled exception error when I try to load HDR image that Is used as a texture.
This is the piece of the code that is used to load HDR texture, if I comment it all out, program runs without problems but there's just no texture on my object.
bool LoadOpenEXRImage(char *fileName, GLint textureName, GLuint &texWidth, GLuint &texHeight)
{
// The OpenEXR uses exception handling to report errors or failures
// Do all work in a try block to catch any thrown exceptions.
try
{
Imf::Array2D<Imf::Rgba> pixels;
Imf::RgbaInputFile file(fileName); // UNHANDLED EXCEPTION
Imath::Box2i dw = file.dataWindow();
texWidth = dw.max.x - dw.min.x + 1;
texHeight = dw.max.y - dw.min.y + 1;
pixels.resizeErase(texHeight, texWidth);
file.setFrameBuffer(&pixels[0][0] - dw.min.x - dw.min.y * texWidth, 1, texWidth);
file.readPixels(dw.min.y, dw.max.y);
GLfloat* texels = (GLfloat*)malloc(texWidth * texHeight * 3 * sizeof(GLfloat));
GLfloat* pTex = texels;
// Copy OpenEXR into local buffer for loading into a texture
for (unsigned int v = 0; v < texHeight; v++)
{
for (unsigned int u = 0; u < texWidth; u++)
{
Imf::Rgba texel = pixels[texHeight - v - 1][u];
pTex[0] = texel.r;
pTex[1] = texel.g;
pTex[2] = texel.b;
pTex += 3;
}
}
// Bind texture, load image, set tex state
glBindTexture(GL_TEXTURE_2D, textureName);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, texWidth, texHeight, 0, GL_RGB, GL_FLOAT, texels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
free(texels);
}
catch (Iex::BaseExc & e)
{
std::cerr << e.what() << std::endl;
//
// Handle exception.
//
}
return true;
}
It is called like this:
LoadOpenEXRImage("window.exr", windowTexture, texWidth, texHeight);
Please notice my mark, which shows where exactly the unhandled exception happens.
If i try to run it, I get this error:
Unhandled exception at 0x77938E19 (ntdll.dll) in hdr_bloom.exe:
0xC0000005: Access violation writing location 0x00000014.
My debugger points to this piece of code:
virtual void __CLR_OR_THIS_CALL _Lock()
{ // lock file instead of stream buffer
if (_Myfile)
_CSTD _lock_file(_Myfile); // here
}
Which is part of the fstream
My declarations look like this:
#include <ImfRgbaFile.h> // OpenEXR headers
#include <ImfArray.h>
#ifdef _WIN32
#pragma comment (lib, "half.lib")
#pragma comment (lib, "Iex.lib")
#pragma comment (lib, "IlmImf.lib")
#pragma comment (lib, "IlmThread.lib")
#pragma comment (lib, "Imath.lib")
#pragma comment (lib, "zlib.lib")
#endif
#pragma warning( disable : 4244)
I've no idea if this matters but when I tried to run it for the first time I got SAFESEH errors about my zlib.lib so I turned SAFESEH off in Linker->Advanced.
And the project provided by the authors was created in VisualStudio2008 where I'm using newer version and I've converted it while opening.
Also, I'm using Windows 7 64-bit and Microsoft Visual Studio 2013 Ultimate.
If it's needed, let me know and I will post more detailed information, I've tried to keep it as short as possible.

I've finally found the issue although I'm not sure how it is happening.
To solve this I had to create a brand new project and just copy everything from the original project so my prediction is that somewhere during conversion of original project, some project properties changed and this caused some errors.
I found out that it's possible that such converted project may not how permission to write or read files in some directories and that's why I got unhandled exception from fstream.
So for future people with similar problems, instead of converting your project, create a brand new one and just copy what you need, in my case, I just had to copy Library and Include directories : ).

Related

Unable to upload bitmaps from most fonts loaded by Freetype to OpenGL as textures. However, other fonts work perfectly. (with image examples)

I'm facing this issue for months. Every font I load with freetype works fine, I can prove that to myself by writing the glyphs to a BMP file using the stb_write_bmp from the STB library. I can see all hundreds of glyph bitmaps written correctly in my folder.
OpenGL, on the other hand, is unable to load the textures from specific fonts, and I see no explainable reason as to why some load and others don't. I have done everything to try and solve it but it keeps happening. The textures simply don't load at all. I'm doing exactly the same procedure for every font, so I should be getting the same results.
Examples: (with maximum of 0.1 alpha for debugging invisible squares like the last ones)
Cantarell-Regular.ttf
CPMono_v07-Light.otf
SourceSansPro-Regular.ttf (bugged - no texture)
RobotoCondensed-Regular.ttf (bugged - no texture)
What do the loaded fonts have in common? It's not the extension, at least, since I can render cantarell's TTF files. All of them, even the ones that the texture don't load, are correctly written as BMP if i send them to the STB function. So why are the last ones not loaded by the GL? This makes no sense to me... there's no consistency except that the ones that don't load, never load, and the ones that load, always load. But I see nothing that could have different effects on different fonts, and this is confusing me a lot. I am also returning the errors to an int on every FT function and it's all clear by their side.
This is my renderer's constructor, where everything relevant to the text rendering and texture uploading is setup:
if (error = FT_Init_FreeType(&ftlib))
{
std::cout << "Freetype failed to initialize (exit " << error << ')'
<< std::endl;
}
else
{
std::cout << "Freetype initialized";
}
if (error = FT_New_Face(ftlib, fontFile, 0, &face))
{
std::cout << "but could not load font " << face->family_name
<< " (exit " << error << ')' << std::endl;
}
else
{
std::cout << " and loaded font " << face->family_name << std::endl;
FT_Set_Pixel_Sizes(face, 0, height);
/// Determine total length of texture atlas
FT_UInt cindex = 0;
for (
FT_ULong c = FT_Get_First_Char(face, &cindex);
cindex != 0;
c = FT_Get_Next_Char(face, c, &cindex)
) {
if (error = FT_Load_Glyph(face, cindex, FT_LOAD_BITMAP_METRICS_ONLY))
{
std::cout << "Freetype: Could not load glyph "
"(exit " << error << "[1])"
<< std::endl;
continue;
}
else
{
atlasLength += face->glyph->bitmap.width;
if (totalRows < face->glyph->bitmap.rows) {
totalRows = face->glyph->bitmap.rows;
};
}
}
bindShaders();
/// Setup VAO and texture object.
newVertexArray();
bindVertexArray(vertexArray[0]);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &atlas);
glBindTexture(GL_TEXTURE_2D, atlas);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RED,
atlasLength, totalRows,
0, GL_RED, GL_UNSIGNED_BYTE, 0
);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
GLint offset = 0;
cindex = 0;
/// Start indexing textures
for (
FT_ULong c = FT_Get_First_Char(face, &cindex);
cindex != 0;
c = FT_Get_Next_Char(face, c, &cindex))
{
if (error = FT_Load_Glyph(face, cindex, FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT))
{
std::cout << "Freetype could not load glyph "
"(exit " << error << "[2])" << "\n"
;
continue;
}
else
{
FT_GlyphSlot glyph = face->glyph;
glTexSubImage2D(
GL_TEXTURE_2D, 0, offset, 0,
glyph->bitmap.width, glyph->bitmap.rows,
GL_RED, GL_UNSIGNED_BYTE, glyph->bitmap.buffer
);
Glyph character =
{
static_cast<Float>(offset),
static_cast<Float>(offset) + glyph->bitmap.width,
glm::u16vec2(glyph->bitmap.width, glyph->bitmap.rows),
glm::u16vec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
glm::u16vec2(face->glyph->advance.x, face->glyph->advance.y),
};
characters.insert(std::make_pair(c, character));
}
offset += face->glyph->bitmap.width;
}
}
glBindVertexArray(0);
bindShaders(0);
Am I doing something wrong? As far as I can see there's nothing that could go wrong here.
Edit:
I have found that the font height is playing a part here. For some reason, if I send a value of 12px to FT_Set_Pixel_Sizes, all fonts open. Increasing the height makes Source Sans eventually stop working at some point (I haven't marked exactly at what size it stopped working but somewhere around 20px), and at 42px Roboto stops working too. I don't know why though, since the bitmaps are ok in all these cases. At least, this is a bit less mistifying now.
I don’t know if it gonna help, but there is one problem with your code. You’re ignoring the FT_Bitmap.pitch field. The RAM layout of the bitmap depends substantially on that value, yet there’s no way to supply the value to OpenGL. There’s GL_UNPACK_ROW_LENGTH setting but that value is pixels, not bytes.
Try to copy these bitmaps to another buffer with stride equal to glyph width * sizeof(pixel), and then pass that temporary buffer to glTexSubImage2D. If you’re on Windows call MFCopyImage, otherwise do it manually by calling memcpy() in a loop.
Don’t forget the pitch can be negative, which means the FT bitmap is stored with bottom-to-top row order.
Also, check FT_Bitmap.pixel_mode field is FT_PIXEL_MODE_GRAY, that’s the only value compatible with your GL texture.

Pointer "this" of a class turns into null when calling a method of that class C++

I know that this question has been asked before but didnt see a proper solution to my problem, my problem is that when i create a pointer of a class (PAGTexture) everything is normal but then, that pointer is passed to another class as variable and in that new class (PAGRevolutionObject) i call a method from PAGTexture and then it throws an exception. Debugging i realized that it actually enter in that method but "this" pointer is null "0x00000000 ".
This is my cpp of PAGTexture:
#include "PAGTexture.h"
PAGTexture::PAGTexture()
{}
PAGTexture::~PAGTexture()
{
}
void PAGTexture::loadTexture(char * path_img, GLuint min_filter, GLuint mag_filter)
{
int imgWidth, imgHeight;
unsigned char *image;
image = SOIL_load_image(path_img,
&imgWidth,
&imgHeight,
0,
SOIL_LOAD_RGBA);
if (imgWidth == 0) {
std::cout << "Failed to load image." << std::endl;
}
GLuint id_img;
glGenTextures(1, &id_img);
glBindTexture(GL_TEXTURE_2D, id_img);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imgWidth, imgHeight,
0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
ep = id_img;
id_imgs.push_back(id_img);
SOIL_free_image_data(image);
}
void PAGTexture::applyTexture(GLuint id, int pos)
{
glActiveTexture(id);
glBindTexture(GL_TEXTURE_2D, id_imgs.at(pos));
}
It turns into a null pointer when "applyTexture" is called because it tries to get the id from id_imgs.at(pos) and this one is null.
And this is the part where i called "applyTexture":
GLuint t = 33984;
if (id_revol.size() != 0) {
for (int i = 0; i < id_revol.size(); i++) {
shader_used->setUniform("TexSamplerColor", i);
textures->applyTexture(t + i, id_revol.at(i));
}
}
Notice that textures is not null pointer because i can access to "applyTexture" from there.
And this is an image of what i got debugging :
Image Debugging the process
I also tried to set a data breakpoint to know which part of my code is making that pointer corrupted following this "tutorial" but i cant set that breakpoint for my vs version (VS2015) .
To be honest, i think my problem is that i'm overwritting memory from another class( my proyect is pretty big ) but even so i wanted to ask to see if there is something that i'm missing.
By the way i'm using Visual Studio 2015 in debug mode (not release).
Thanks in advance for any answer.
EDIT1:
As requested here is where i defined PAGTexture:
PAGTexture *texturesPack = new PAGTexture();
texturesPack->loadTexture("Textures/check.png", GL_LINEAR, GL_LINEAR);
texturesPack->loadTexture("Textures/HeadSpider.png", GL_LINEAR, GL_LINEAR);
texturesPack->loadTexture("Textures/wood.jpg", GL_LINEAR, GL_LINEAR);
objeto2->drawLowerBodySpiderAndHead(texturesPack);
FINAL EDIT:
Thanks everybody to answer, my problem was that i was binding that pointer in a inline function and it seems that you cant do that (still dunno why), anyway i have learned some points that i think it could be important so thanks again :D
The assumption: "textures is not null pointer because i can access to "applyTexture" from there." is wrong. applyTexture is not a function pointer, it's a class method.
The compiler actually converts your object notation call into:
PAGTexture::applyTexture(textures, t + i, id_revol.at(i));
passing nullptr doesn't bother the compiler like at all. But when entering the method, this==nullptr and it crashes when you access a member.
It's different with data members (would probably have crashed at once), hence your confusion.
To play it safe, you could do things like:
void PAGTexture::loadTexture(char * path_img, GLuint min_filter, GLuint mag_filter)
{
assert(this!=nullptr);
that will crash with a failed assertion if method is called with a null pointer (note: only works if optimizations are turned off, else the compiler assumes that this cannot be nullptr when optimizing even with -O1)

Error C2664: 'auxDIBImageLoadW' : cannot convert parameter 1 from 'LPSTR' to 'LPCWSTR'

I was just modifying the code after reinstalling windows and VS 2012 Ultimate. The code (shown below) works perfectly fine before, but when I try to run the code right now, it gives following errors:
Error 1 error C2664: 'auxDIBImageLoadW' : cannot convert parameter 1 from 'LPSTR' to 'LPCWSTR'
Code:
void CreateTexture(GLuint textureArray[], LPSTR strFileName, int textureID)
{
AUX_RGBImageRec *pBitmap = NULL;
if (!strFileName) // Return from the function if no file name was passed in
return;
pBitmap = auxDIBImageLoad(strFileName); //<-Error in this line // Load the bitmap and store the data
if (pBitmap == NULL) // If we can't load the file, quit!
exit(0);
// Generate a texture with the associative texture ID stored in the array
glGenTextures(1, &textureArray[textureID]);
// This sets the alignment requirements for the start of each pixel row in memory.
// glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
// Bind the texture to the texture arrays index and init the texture
glBindTexture(GL_TEXTURE_2D, textureArray[textureID]);
// Build Mipmaps (builds different versions of the picture for distances - looks better)
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pBitmap->sizeX, pBitmap->sizeY, GL_RGB, GL_UNSIGNED_BYTE, pBitmap->data);
// Lastly, we need to tell OpenGL the quality of our texture map. GL_LINEAR is the smoothest.
// GL_NEAREST is faster than GL_LINEAR, but looks blochy and pixelated. Good for slower computers though.
// Read more about the MIN and MAG filters at the bottom of main.cpp
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_NEAREST);
// glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
// Now we need to free the bitmap data that we loaded since openGL stored it as a texture
if (pBitmap) // If we loaded the bitmap
{
if (pBitmap->data) // If there is texture data
{
free(pBitmap->data); // Free the texture data, we don't need it anymore
}
free(pBitmap); // Free the bitmap structure
}
}
I tried this Link, This one too and also Tried this one too. but still getting error.
This function is used after initialization as:
LPCWSTR k =L"grass.bmp";
CreateTexture(g_Texture, "building1.bmp", 0);
CreateTexture(g_Texture, "clock.bmp", 0);
//list goes on
Can you help me out?
Change "LPSTR strFileName" to "LPCWSTR strFileName", "building1.bmp" to L"building1.bmp and "clock.bmp" to L"clock.bmp".
Always be careful because LPSTR is ASCII and LPCWSTR is Unicode. So if the function needs a Unicode variable (like this: L"String here") you can't give it a ASCII string.
The solutions are either:
Change your function prototype to take wide strings:
void CreateTexture(GLuint textureArray[], LPWSTR strFileName, int textureID)
//...
LPCWSTR k =L"grass.bmp";
CreateTexture(g_Texture, L"building1.bmp", 0);
CreateTexture(g_Texture, L"clock.bmp", 0);
or
Don't change your function prototype, but call the A version of the API function:
pBitmap = auxDIBImageLoadA(strFileName);
Recommended: Stick to wide strings and use the correct string types.

Unhandled Exception using glGenBuffer on Release mode only - QT

I'm having some trouble while compiling my project on Windows 7 using Qt 4.8 on Release mode. Everything works fine on Debug, but on Release I get an Unhandled Exception: 0xC0000005: Access violation.
I narrowed it down to the line where this happens, which is when I generate my Pixel Buffers.
My first guess would be wrong DLLs loading, but I checked the executable with Dependency Walker and every DLL loaded is correct.
Here goes some of my code:
class CameraView : public QGLWidget, protected QGLFunctions;
void CameraView::initializeGL()
{
initializeGLFunctions(this->context());
glGenBuffers(1, &pbo_); //<<<<< This is where I get the unhandled exception on Release mode
glBindBuffer(QGLBuffer::PixelUnpackBuffer, pbo_);
glBufferData(QGLBuffer::PixelUnpackBuffer, 3 * sizeof(BYTE) * image_width_ * image_height_, NULL, GL_STREAM_DRAW);
...
}
Again, this works great on debug. Why would this only happen on Release?
I got it.
Seems like this issue is related to this one:
https://forum.qt.io/topic/12492/qt-4-8-qglfunctions-functions-crash-in-release-build
and there's a bug report that may be related also:
https://bugreports.qt.io/browse/QTBUG-5729
Perhaps the initializeGLFunctions() method is not getting all function pointers for the GL extension functions, I don't really know why but this seems to be it.
The solution for me was to stop using Qt's GL extensions and start using glew.
So, here's what worked for me:
#include <QtGui/QtGui>
#include <gl/glew.h>
#include <QtOpenGL/QGLWidget>
class CameraView : public QGLWidget;
void CameraView::initializeGL()
{
//initializeGLFunctions(this->context());
GLenum init = glewInit();
// Create buffers
glGenBuffers(1, &pbo_);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_);
glBufferData(GL_PIXEL_UNPACK_BUFFER, 3 * sizeof(BYTE) * image_width_ * image_height_, NULL, GL_STREAM_DRAW);
// Set matrixes
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrtho(0, this->width(), 0, this->height(), 0, 1);
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
}
Be sure that glew.h is included before any QTOpenGL headers or else you'll get a compilation error.

OpenGL calls segfault when called from OpenMP thread

Let me start by trying to specify what I want to do:
Given a grey scale image, I want to create 256 layers (assuming 8bit images), where each layer is the image thresholded with a grey scale i -- which is also the i'th layer (so, i=0:255). For all of these layers I want to compute various other things which are not very relevant to my problem, but this should explain the structure of my code.
The problem is that I need to execute the code very often, so I want to speed things up as much as possible, using a short amount of time (so, simple speedup tricks only). Therefore I figured I could use the OpenMP library, as I have a quad core, and everything is CPU-based at the moment.
This brings me to the following code, which executes fine (at least, it looks fine :) ):
#pragma omp parallel for private(i,out,tmp,cc)
for(i=0; i< numLayers; i++){
cc=new ConnectedComponents(255);
out = (unsigned int *) malloc(in->dimX()* in->dimY()*sizeof(int));
tmp = (*in).dupe();
tmp->threshold((float) i);
if(!tmp){ printf("Could not allocate enough memory\n"); exit(-1); }
cc->connected(tmp->data(),out,tmp->dimX(),tmp->dimY(),std::equal_to<unsigned int>(), true);
free(out);
delete tmp;
delete cc;
}
ConnectedComponents is just some library which implements the 2-pass floodfill, just there for illustration, it is not really part of the problem.
This code finishes fine with 2,3,4,8 threads (didn't test any other number).
So, now the weird part. I wanted to add some visual feedback, helping me to debug. The object tmp contains a method called saveAsTexture(), which basically does all the work for me, and returns the texture ID. This function works fine single threaded, and also works fine with 2 threads. However, as soon as I go beyond 2 threads, the method causes a segmentation fault.
Even with #pragma omp critical around it (just in case saveAsTexture() is not thread-safe), or executing it only once, it still crashes. This is the code I have added to the previous loop:
if(i==100){
#pragma omp critical
{
tmp->saveToTexture();
}
}
which is only executed once, since i is the iterator, and it is a critical section... Still, the code ALWAYS segfaults at the first openGL call (bruteforce tests with printf(), fflush(stdout)).
So, just to make sure I am not leaving out relevant information, here is the saveAsTexture function:
template <class T> GLuint FIELD<T>::saveToTexture() {
unsigned char *buf = (unsigned char*)malloc(dimX()*dimY()*3*sizeof(unsigned char));
if(!buf){ printf("Could not allocate memory\n"); exit(-1); }
float m,M,avg;
minmax(m,M,avg);
const float* d = data();
int j=0;
for(int i=dimY()-1; i>=0; i--) {
for(const float *s=d+dimX()*i, *e=s+dimX(); s<e; s++) {
float r,g,b,v = ((*s)-m)/(M-m);
v = (v>0)?v:0;
if (v>M) { r=g=b=1; }
else { v = (v<1)?v:1; }
r=g=b=v;
buf[j++] = (unsigned char)(int)(255*r);
buf[j++] = (unsigned char)(int)(255*g);
buf[j++] = (unsigned char)(int)(255*b);
}
}
GLuint texid;
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glDisable(GL_TEXTURE_3D);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &texid);
printf("TextureID: %d\n", texid);
fflush(stdout);
glBindTexture(GL_TEXTURE_2D, texid);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, dimX(), dimY(), 0, GL_RGB, GL_UNSIGNED_BYTE, buf);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
free(buf);
return texid;
}
It is good to note here that T is ALWAYS a float in my program.
So, I do not understand why this program works fine when executed with 1 or 2 threads (executed ~25 times, 100% success), but segfaults when using more threads (executed ~25 times, 0% success). And ALWAYS at the first openGL call (e.g. if I remove glPixelStorei(), it segfaults at glDisable()).
Am I overlooking something really obvious, am I encountering a weird OpenMP bug, or... what is happening?
You can only make OpenGL calls from one thread at a time, and the thread has to have the current context active.
An OpenGL context can only be used by one thread at a time (limitation imposed by wglMakeCurrent/glxMakeCurrent).
However, you said you're using layers. I think you can use different contexts for different layers, with the WGL_ARB_create_context extension (I think there's one for linux too) and setting the WGL_CONTEXT_LAYER_PLANE_ARB parameter. Then you could have a different context per thread, and things should work out.
Thank you very much for all the answers! Now I know why it fails I have decided to simply store everything in a big 3D texture (because this was an even easier solution), and just send all the data to the GPU at once. That works fine in this case.