OK, I’ve narrowed it down to see that it simply crashes in glTexSubImage2D, whether I have given a pointer to the originally created texture object or not. I’ve also tested it on another vendors h/w, and there it does not crash, why I’m now starting to assume this is an ATI driver thing. Could be interesting to hear some results from people with earlier/later versions and/or different hardware, if it makes a difference. I used Cat 5.8.
Please note I ripped out all error checking, and even the check for compressed texture support, to keep the code size down a bit.
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include <GL/gl.h>
#include <glut.h>
#include <string.h>
#ifndef GL_COMPRESSED_RGB_ARB
#define GL_COMPRESSED_RGB_ARB 0x84ED
#endif
void upload_sub_rgb(const void* p)
{
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 1024);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1024, 768, GL_RGB, GL_UNSIGNED_BYTE, p);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
}
// not compressed. Would be silly if this didn't work, eh. :-)
void works1()
{
char* p = (char*)malloc(1024*768*3);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
upload_sub_rgb(p);
free(p);
}
// just to display a/the (slow & ugly) workaround
void works2()
{
char* p = (char*)malloc(1024*768*3);
char* p2 = (char*)malloc(1024*1024*3);
memcpy(p, p2, 1024*768*3);
glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_ARB, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, p2);
free(p2);
free(p);
}
// test to see if it also crashes when given an initial pointer, even if a dummy
void just_testing()
{
char* p = (char*)malloc(1024*768*3);
char* p2 = (char*)malloc(1024*1024*3);
glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_ARB, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, p2);
upload_sub_rgb(p);
free(p2);
free(p);
}
// This always crashes for me, in the glTexSubImage2D call
void crash()
{
char* p = (char*)malloc(1024*768*3);
glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_ARB, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
upload_sub_rgb(p);
free(p);
}
void test()
{
GLuint tex_names[4];
glGenTextures(3, tex_names);
printf("doing works1
");
glBindTexture(GL_TEXTURE_2D, tex_names[0]); works1();
printf("did works1
");
printf("doing works2
");
glBindTexture(GL_TEXTURE_2D, tex_names[1]); works2();
printf("did works2
");
printf("doing just_testing
");
glBindTexture(GL_TEXTURE_2D, tex_names[2]); just_testing();
printf("did just_testing
");
printf("doing ATI crasher
");
glBindTexture(GL_TEXTURE_2D, tex_names[3]); crash();
printf("doing ATI crasher
");
}
int main()
{
glutInitDisplayMode(GLUT_DOUBLE bitor GLUT_RGBA bitor GLUT_DEPTH);
glutInitWindowSize(320, 240);
glutInitWindowPosition(100, 50);
glutCreateWindow("Triangle Stripper Test");
test();
return 0;
}