opengl-es - descargar - opengl es 3.1 apk
opengl: cómo evitar el escalamiento de la textura (3)
No estoy muy seguro, pero prueba algo como esto:
Tome su matriz modelo, matriz de perspectiva, y cosas así. Machacalos juntos en el orden correcto multiplicándolos. Toma la inversa de la matriz. Multiplíquelo por su matriz de textura (que probablemente sea la matriz de identidad). Establezca eso como su matriz de textura.
¿Cómo aplico una textura repetitiva que siempre mantiene su escala original (1 píxel en la textura = 1 píxel en la pantalla), independientemente de los datos de vértice con los que se aplica?
Me doy cuenta de que esta no es la tarea más común, pero ¿es posible establecer fácilmente OpenGL para hacer esto, o tengo que aplicar algún tipo de máscara a los datos de los vértices que respete su apariencia original?
editar: en mi caso específico, estoy tratando de dibujar elipsis 2D de diferentes tamaños, con el mismo patrón de píxeles. Las elipsis están hechas de un abanico de triángulo, y estoy teniendo un momento difícil para dibujar una textura repetitiva de cualquier tipo sobre él. Esperaba que hubiera alguna combinación de configuración OpenGL para hacer esto fácilmente. Además, ahora me doy cuenta de que es importante mencionar que estoy usando opengles, para el iPhone, por lo que GLU no está disponible.
Creo que el siguiente fragmento de código es de lo que estás hablando. Sin embargo, sin el truco en la reshape()
brilla bastante mal con GL_NEAREST
y tamaños de ventana no GL_NEAREST
. Cualquier idea sería apreciada.
Sin embargo, utiliza la generación de coordenadas de textura, por lo que no estoy seguro de qué decir en el frente de OpenGL ES 1.1. Un representante de PowerVR insinuó una solución, pero no fue muy explícito.
#include <GL/glut.h>
#include <cstdlib>
#include <cmath>
static GLuint texName;
void init(void)
{
glClearColor(0,0,0,0);
// create random texture
const int texWidth = 8;
const int texHeight = 8;
GLubyte tex[texHeight][texWidth][4];
for(int i = 0; i < texHeight; i++)
{
for(int j = 0; j < texWidth; j++)
{
tex[i][j][0] = (GLubyte) rand()%255;
tex[i][j][1] = (GLubyte) rand()%255;
tex[i][j][2] = (GLubyte) rand()%255;
tex[i][j][3] = (GLubyte) 255;
}
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
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_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex);
// planes for texture coordinate generation
GLfloat xp[] = {1,0,0,0};
GLfloat yp[] = {0,1,0,0};
GLfloat zp[] = {0,0,1,0};
GLfloat wp[] = {0,0,0,1};
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_S, GL_EYE_PLANE, xp);
glTexGenfv(GL_T, GL_EYE_PLANE, yp);
glTexGenfv(GL_R, GL_EYE_PLANE, zp);
glTexGenfv(GL_Q, GL_EYE_PLANE, wp);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glEnable(GL_TEXTURE_GEN_Q);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_TEXTURE_2D);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// projection
glMatrixMode(GL_PROJECTION); glLoadIdentity();
int viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport);
gluPerspective(60.0, (GLdouble)viewport[2]/(GLdouble)viewport[3], 1.0, 100.0 );
// texture matrix trickery
int tw,th;
glMatrixMode(GL_TEXTURE); glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, texName);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tw);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &th);
glScaled( (viewport[2]/2)/(GLdouble)tw, (viewport[3]/2)/(GLdouble)th, 0 );
GLdouble proj[16];
glGetDoublev(GL_PROJECTION_MATRIX, proj); // grab projection matrix
glMultMatrixd(proj);
// view transform
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
glTranslatef(0,0,-2.5);
// render textured teapot
glPushMatrix();
const float ANGLE_SPEED = 60; // degrees/sec
float angle = ANGLE_SPEED * (glutGet(GLUT_ELAPSED_TIME) / 1000.0f);
glRotatef(angle*0.5f, 1, 0, 0);
glRotatef(angle, 0, 1, 0);
glRotatef(angle*0.7f, 0, 0, 1);
glScalef(-1,-1,-1); // teapot is wound backwards (GL_CW), so flip it
glutSolidTeapot(1);
glPopMatrix();
glutSwapBuffers();
}
void reshape(int w, int h)
{
// make width/height evenly divisible by 2
w -= (w%2);
h -= (h%2);
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
}
void keyboard (unsigned char key, int x, int y)
{
switch (key)
{
case 27: exit(0); break;
default: break;
}
}
void idle() { glutPostRedisplay(); }
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutInitWindowPosition(100, 100);
glutCreateWindow (argv[0]);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutIdleFunc(idle);
init();
glutMainLoop();
return 0;
}
EDITAR: Obtuve el método de la matriz de texturas solo calculado (debe ser OpenGL ES 1.1-able):
#include <GL/glut.h>
#include <cstdlib>
#include <cmath>
void glutTexturedCube(GLdouble size)
{
GLfloat texc[] = {
1,1, 0,1, 0,0, 1,0,
0,1, 0,0, 1,0, 1,1,
1,0, 1,1, 0,1, 0,0,
1,1, 0,1, 0,0, 1,0,
0,0, 1,0, 1,1, 0,1,
0,0, 1,0, 1,1, 0,1,
};
GLfloat norm[] = {
0,0,1, 0,0,1, 0,0,1, 0,0,1,
1,0,0, 1,0,0, 1,0,0, 1,0,0,
0,1,0, 0,1,0, 0,1,0, 0,1,0,
-1,0,0, -1,0,0, -1,0,0, -1,0,0,
0,-1,0, 0,-1,0, 0,-1,0, 0,-1,0,
0,0,-1, 0,0,-1, 0,0,-1, 0,0,-1,
};
GLfloat vert[] = {
1,1,1, -1,1,1, -1,-1,1, 1,-1,1,
1,1,1, 1,-1,1, 1,-1,-1, 1,1,-1,
1,1,1, 1,1,-1, -1,1,-1, -1,1,1,
-1,1,1, -1,1,-1, -1,-1,-1, -1,-1,1,
-1,-1,-1, 1,-1,-1, 1,-1,1, -1,-1,1,
1,-1,-1, -1,-1,-1, -1,1,-1, 1,1,-1,
};
GLuint idxs[] = {
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15,
16, 17, 18, 19,
20, 21, 22, 23,
};
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
// feed vertices in as texture coordinates
glTexCoordPointer(3, GL_FLOAT, 0, vert);
glNormalPointer(GL_FLOAT, 0, norm);
glVertexPointer(3, GL_FLOAT, 0, vert);
glPushMatrix();
glColor4f(1, 1, 1, 1);
glScaled(size, size, size);
glDrawElements(GL_QUADS, sizeof(idxs)/sizeof(idxs[0]), GL_UNSIGNED_INT, idxs);
glPopMatrix();
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
static GLuint texName;
void init(void)
{
glClearColor(0,0,0,0);
// create random texture
const int texWidth = 8;
const int texHeight = 8;
GLubyte tex[texHeight][texWidth][4];
for(int i = 0; i < texHeight; i++)
{
for(int j = 0; j < texWidth; j++)
{
tex[i][j][0] = (GLubyte) rand()%255;
tex[i][j][1] = (GLubyte) rand()%255;
tex[i][j][2] = (GLubyte) rand()%255;
tex[i][j][3] = (GLubyte) 255;
}
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_2D, texName);
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_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_TEXTURE_2D);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// projection
glMatrixMode(GL_PROJECTION); glLoadIdentity();
int viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport);
gluPerspective(60.0, (GLdouble)viewport[2]/(GLdouble)viewport[3], 1.0, 100.0 );
// view transform
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
glTranslatef(0,0,-3);
// render textured teapot
glPushMatrix();
const float ANGLE_SPEED = 10; // degrees/sec
float angle = ANGLE_SPEED * (glutGet(GLUT_ELAPSED_TIME) / 1000.0f);
glRotatef(angle*0.5f, 1, 0, 0);
glRotatef(angle, 0, 1, 0);
glRotatef(angle*0.7f, 0, 0, 1);
// texture matrix trickery
int tw,th;
glBindTexture(GL_TEXTURE_2D, texName);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tw);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &th);
GLint mmode = 0;
glGetIntegerv(GL_MATRIX_MODE, &mmode);
glMatrixMode(GL_TEXTURE); glLoadIdentity();
glScaled( (viewport[2]/2)/(GLdouble)tw, (viewport[3]/2)/(GLdouble)th, 0 );
GLdouble mat[16];
glGetDoublev(GL_PROJECTION_MATRIX, mat);
glMultMatrixd(mat);
glGetDoublev(GL_MODELVIEW_MATRIX, mat);
glMultMatrixd(mat);
glMatrixMode(mmode);
glutTexturedCube(1);
glPopMatrix();
glutSwapBuffers();
}
void reshape(int w, int h)
{
// make width/height evenly divisible by 2
w -= (w%2);
h -= (h%2);
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
}
void keyboard (unsigned char key, int x, int y)
{
switch (key)
{
case 27: exit(0); break;
default: break;
}
}
void idle() { glutPostRedisplay(); }
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(640, 480);
glutInitWindowPosition(100, 100);
glutCreateWindow (argv[0]);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutIdleFunc(idle);
init();
glutMainLoop();
return 0;
}
Crea el objeto 3D en cuestión, sin mostrarlo.
Puede obtener los límites del objeto como ubicaciones de píxeles utilizando gluProject (para obtener los píxeles que representan los bordes del objeto. Luego puede usar gluUnProject para asignar los píxeles intermedios a las coordenadas del objeto.
Luego, comienza su sorteo, y asigna una textura personalizada (sobre la marcha) sobre el mismo objeto y lo muestra.
No estoy seguro de por qué querría hacer esto, pero ese debería ser un buen punto de partida.
Editar:
Lo que quiero decir por costumbre, es si los límites de su objeto (en una dimensión,) son de -3.0 a 1.0, y la primera fila de píxeles es de -3.0 a -2.0, su mapa de texturas indicará que el 25% de su los mapas de textura personalizados sobre ese punto, y usted lo crea todo con el color del píxel que desea mostrar allí.
Después de pensar eso, me di cuenta de que solo podías dibujar una textura sobre la parte superior de las coordenadas proyectadas de la pantalla (usando las funciones de dibujo en 2D).
Creo que eso transmite la esencia de tu idea. No creo que funcione bien en una demostración 3D interactiva, si el "objeto" se acerca y se aleja, si la textura no parece escalar hacia arriba y hacia abajo. Pero no dijiste lo que en realidad estabas haciendo.
Editar 2:
OpenGL 2D Projection:
PRECAUCIÓN
Cuidado con los nombres de las funciones, por ejemplo, opengles 1.1 tiene glOrthox y glOrthof. Asegúrese de verificar lo que está disponible en su archivo de encabezado gl.h.
const XSize = 640, YSize = 480
glMatrixMode (GL_PROJECTION)
glLoadIdentity ()
glOrtho (0, XSize, YSize, 0, 0, 1)
glMatrixMode (GL_MODELVIEW)
glDisable(GL_DEPTH_TEST)
glClear(GL_COLOR_BUFFER_BIT)
// Now draw with 2i or 2f vertices instead of the normal vertex3f functions.
// And for ES, of course set up your data structures and call drawarrays ofr drawelements.
SwapBuffers()
Esto le permitirá dibujar formas 2D en OpenGL (mucho más simple que usar proyecciones en 3D.) Para mezclar los dos, por ejemplo, dibujar en 3D y luego en 2D, siga el segundo enlace.
Aquí hay un excelente tutorial sobre dibujo 2D:
http://basic4gl.wikispaces.com/2D+Drawing+in+OpenGL
Aquí está lo básico para mezclar los dos:
http://www.gamedev.net/community/forums/topic.asp?topic_id=96440
Espero que eso es lo que quieres. Tengo una sospecha furtiva de tu publicación de que tienes problemas para mapear tu textura a través de los puntos del triángulo para que aparezca "recta". Es posible que desee revisar la asignación de textura básica en NeHe:
http://www.gamedev.net/community/forums/topic.asp?topic_id=96440
Por ejemplo, gltexcoord2f especifica el punto (0.0-1.0) dentro de la textura en términos del porcentaje de ancho y alto de la textura que se correlaciona con el siguiente vértice dibujado. Con los ventiladores de triángulo, puede tener algunas connotaciones matemáticas para calcular qué% de ancho y alto del objeto general está especificando con el vértice.
Tomemos, por ejemplo, una esfera con un mapa de textura (una proyección de mercator de la tierra) se calcula mejor calculando las líneas de latitud como base para los valores de los vértices del ventilador del triángulo subyacente, ya que facilita el cálculo de las coordenadas de la textura. Hacer que sus polígonos se aproximen a formas geométricas simples le permite usar la trigonometría para calcular más fácilmente las coordenadas de la textura.
Espero que esto sea útil.
Hehere, dejaré de seguir con los ejemplos de escritorio que tienes que modificar. Aquí hay un ejemplo de OpenGLES que hace una correcta asignación de texturas 3D. Puedes usar lo que dije arriba, y este ejemplo, para hacer un mapeo de texturas 2D.
http://www.zeuscmd.com/tutorials/opengles/17-TextureMapping.php