sirve - texturas multiples opengl
Formatos internos de textura OpenGL 2 GL_RGB8I, GL_RGB32UI, etc. (1)
Cuando busco errores, obtengo [EDIT:] 1282 ("operación no válida"). Supongo que esto significa que OpenGL todavía está usando OpenGL 2 para glTexImage2D, por lo que la llamada está fallando.
Los errores de OpenGL no son tan complejos de entender. GL_INVALID_ENUM/VALUE
se lanzan cuando pasa algo enum o valor inesperado, no compatible o fuera de rango. Si pasa "17" como formato interno a glTexImage2D
, obtendrá GL_INVALID_ENUM
, porque 17 no es un número de enumeración válido para un formato interno. Si pasa 103,422 como ancho a glTexImage2D
, obtendrá GL_INVALID_VALUE
, porque 103,422 es casi seguro mayor que GL_MAX_TEXTURE_2D
.
GL_INVALID_OPERATION
siempre se usa para combinaciones de estados que GL_INVALID_OPERATION
. O bien hay algún estado de contexto previamente establecido que no se acopla con la función a la que llama, o dos o más parámetros combinados están causando un problema. Este último es el caso que tienes aquí.
Si su implementación no admite texturas enteras, obtendrá INVALID_ENUM
(porque el formato interno no es válido). Obtener INVALID_OPERATION
significa que algo más está mal.
A saber, esto:
glTexImage2D(GL_TEXTURE_2D,0,get_type(1), TEXTURE_SIZE,TEXTURE_SIZE, 0,get_type(2),data_type,data);
Su get_type(2)
devuelve GL_RGB
o GL_RGBA
en todos los casos. Sin embargo, al usar formatos de imagen integrales, debe usar un formato de transferencia de píxeles con _INTEGER
al final .
Entonces tu get_type(2)
necesita ser esto:
inline GLenum get_type(int which) { return (which==1)? GL_RGB16UI: GL_RGB_INTEGER; }
Y de manera similar para otros formatos de imagen integrales.
Estoy reescribiendo una gran parte de mi código de texturas. Me gustaría poder especificar ciertos formatos internos: GL_RGB8I, GL_RGB8UI, GL_RGB16I, GL_RGB16UI, GL_RGB32I y GL_RGB32UI. Estos tokens no existen en OpenGL 2.
Al especificar estos formatos internos como argumentos para glTexImage2D, la textura falla (la textura aparece como blanca). Cuando busco errores, obtengo [EDIT:] 1282 ("operación no válida"). Supongo que esto significa que OpenGL todavía está usando OpenGL 2 para glTexImage2D, por lo que la llamada está fallando. Obviamente, necesitará usar una versión más nueva para tener éxito. Los mensajes como GL_RGB, GL_RGBA y (curiosamente) GL_RGB32F, GL_RGBA32F funcionan como se esperaba.
Configuré para usar GLEW o GLee para extensiones. Puedo usar las llamadas a OpenGL 4 sin ningún problema en otros lugares (por ejemplo, glPatchParameteri, glBindFramebuffer, etc.), y las enumeraciones en cuestión ciertamente existen. Para completar, glGetString (GL_VERSION) devuelve "4.2.0". Mi pregunta: ¿puedo forzar a una de estas bibliotecas de extensión a usar la versión OpenGL 4.2? ¿Si es así, cómo?
EDITAR: El código es demasiado complicado para publicar, pero aquí hay un ejemplo simple y autónomo que utiliza GLee y que también demuestra el problema:
#include <GLee5_4/GLee.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <gl/glut.h>
//For Windows
#pragma comment(lib,"GLee.lib")
#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glu32.lib")
#pragma comment(lib,"glut32.lib")
#include <stdlib.h>
#include <stdio.h>
const int screen_size[2] = {512,512};
#define TEXTURE_SIZE 64
//Choose a selection. If you see black, then texturing is working. If you see red, then the quad isn''t drawing. If you see white, texturing has failed.
#define TYPE 1
void error_check(void) {
GLenum error_code = glGetError();
const GLubyte* error_string = gluErrorString(error_code);
(error_string==NULL) ? printf("%d = (unrecognized error--an extension error?)/n",error_code) : printf("%d = /"%s/"/n",error_code,error_string);
}
#if TYPE==1 //############ 8-BIT TESTS ############
inline GLenum get_type(int which) { return (which==1)? GL_RGB8: GL_RGB; } //works
#elif TYPE==2
inline GLenum get_type(int which) { return (which==1)? GL_RGBA8:GL_RGBA; } //works
#elif TYPE==3
inline GLenum get_type(int which) { return (which==1)? GL_RGB8UI: GL_RGB; } //doesn''t work (invalid op)
#elif TYPE==4
inline GLenum get_type(int which) { return (which==1)? GL_RGB8I: GL_RGB; } //doesn''t work (invalid op)
#elif TYPE==5
inline GLenum get_type(int which) { return (which==1)? GL_RGBA8UI:GL_RGBA; } //doesn''t work (invalid op)
#elif TYPE==6
inline GLenum get_type(int which) { return (which==1)? GL_RGBA8I:GL_RGBA; } //doesn''t work (invalid op)
#elif TYPE==7 //############ 16-BIT TESTS ############
inline GLenum get_type(int which) { return (which==1)? GL_RGB16: GL_RGB; } //works
#elif TYPE==8
inline GLenum get_type(int which) { return (which==1)? GL_RGBA16:GL_RGBA; } //works
#elif TYPE==9
inline GLenum get_type(int which) { return (which==1)? GL_RGB16UI: GL_RGB; } //doesn''t work (invalid op)
#elif TYPE==10
inline GLenum get_type(int which) { return (which==1)? GL_RGB16I: GL_RGB; } //doesn''t work (invalid op)
#elif TYPE==11
inline GLenum get_type(int which) { return (which==1)?GL_RGBA16UI:GL_RGBA; } //doesn''t work (invalid op)
#elif TYPE==12
inline GLenum get_type(int which) { return (which==1)? GL_RGBA16I:GL_RGBA; } //doesn''t work (invalid op)
#elif TYPE==13 //############ 32-BIT TESTS ############
inline GLenum get_type(int which) { return (which==1)? GL_RGB32: GL_RGB; } //token doesn''t exist
#elif TYPE==14
inline GLenum get_type(int which) { return (which==1)? GL_RGBA32:GL_RGBA; } //token doesn''t exist
#elif TYPE==15
inline GLenum get_type(int which) { return (which==1)? GL_RGB32UI: GL_RGB; } //doesn''t work (invalid op)
#elif TYPE==16
inline GLenum get_type(int which) { return (which==1)? GL_RGB32I: GL_RGB; } //doesn''t work (invalid op)
#elif TYPE==17
inline GLenum get_type(int which) { return (which==1)?GL_RGBA32UI:GL_RGBA; } //doesn''t work (invalid op)
#elif TYPE==18
inline GLenum get_type(int which) { return (which==1)? GL_RGBA32I:GL_RGBA; } //doesn''t work (invalid op)
#elif TYPE==19 //############ 32-BIT FLOAT ############
inline GLenum get_type(int which) { return (which==1)? GL_RGB32F: GL_RGB; } //works
#elif TYPE==20
inline GLenum get_type(int which) { return (which==1)? GL_RGBA32F:GL_RGBA; } //works
#endif
GLuint texture;
void create_texture(void) {
printf(" Status before texture setup: "); error_check();
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
printf(" Status after texture created: "); error_check();
GLenum data_type = GL_UNSIGNED_BYTE;
int data_length = TEXTURE_SIZE*TEXTURE_SIZE*4; //maximum number of channels, so it will work for everything
unsigned char* data = new unsigned char[data_length];
for (int i=0;i<data_length;++i) {
data[i] = (unsigned char)(0);
};
glTexImage2D(GL_TEXTURE_2D,0,get_type(1), TEXTURE_SIZE,TEXTURE_SIZE, 0,get_type(2),data_type,data);
printf(" Status after glTexImage2D: "); error_check();
delete [] data;
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
printf(" Status after texture filters defined: "); error_check();
}
void keyboard(unsigned char key, int x, int y) {
switch (key) {
case 27: //esc
exit(0);
break;
}
}
void draw(void) {
glClearColor(1.0,0.0,0.0,1.0); //in case the quad doesn''t draw
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glViewport(0,0,screen_size[0],screen_size[1]);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,screen_size[0],0,screen_size[1]);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex2f(0,0);
glTexCoord2f(2,0); glVertex2f(screen_size[0],0);
glTexCoord2f(2,2); glVertex2f(screen_size[0],screen_size[1]);
glTexCoord2f(0,2); glVertex2f(0,screen_size[1]);
glEnd();
glutSwapBuffers();
}
int main(int argc, char* argv[]) {
glutInit(&argc,argv);
glutInitWindowSize(screen_size[0],screen_size[1]);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
glutCreateWindow("Texture Types - Ian Mallett");
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
printf("Status after OpenGL setup: "); error_check();
create_texture();
printf("Status after texture setup: "); error_check();
glutDisplayFunc(draw);
glutIdleFunc(draw);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}