Opengl es opengl:如何避免纹理缩放

Opengl es opengl:如何避免纹理缩放,opengl-es,Opengl Es,如何应用始终保持其原始比例的重复纹理(纹理中的1个像素=屏幕上的1个像素),而不考虑应用的顶点数据 我意识到这不是最常见的任务,但是否可以轻松设置opengl来完成这项任务,或者是否需要对顶点数据应用某种符合其原始外观的遮罩 编辑:在我的特殊情况下,我试图用相同的像素模式绘制不同大小的二维椭圆。椭圆是由三角形扇形组成的,我很难在上面画出任何重复的纹理。我希望有一些opengl配置组合可以轻松完成这项工作。另外,现在我意识到有一点很重要,那就是我在iphone上使用的是opengles,所以GLU

如何应用始终保持其原始比例的重复纹理(纹理中的1个像素=屏幕上的1个像素),而不考虑应用的顶点数据

我意识到这不是最常见的任务,但是否可以轻松设置opengl来完成这项任务,或者是否需要对顶点数据应用某种符合其原始外观的遮罩


编辑:在我的特殊情况下,我试图用相同的像素模式绘制不同大小的二维椭圆。椭圆是由三角形扇形组成的,我很难在上面画出任何重复的纹理。我希望有一些opengl配置组合可以轻松完成这项工作。另外,现在我意识到有一点很重要,那就是我在iphone上使用的是opengles,所以GLU不可用。

我不是很确定,但请尝试以下方法:

拿你的模型矩阵,透视矩阵之类的东西来说。 通过将它们相乘,以适当的顺序将它们混合在一起。 以矩阵的倒数为例。 将其乘以纹理矩阵(可能是单位矩阵)。
将其设置为纹理矩阵。

创建有问题的3D对象,而不显示它。

您可以使用gluProject(获取表示对象边缘的像素)获取对象的边界作为像素位置。然后,您可以使用gluUnProject将中间像素映射到对象的坐标。

然后,开始绘制,在同一对象上映射自定义(动态)纹理并显示它。

不知道为什么要这样做,但这应该是一个很好的起点。

编辑:

我所说的“自定义”是指,如果对象的边界(在一维中)为-3.0到1.0,并且第一个像素行为-3.0到-2.0,则纹理贴图将指示25%的自定义纹理贴图位于该点上,并使用要显示的像素的颜色创建所有这些贴图。

在仔细考虑之后,我意识到您可以在投影屏幕坐标的顶部绘制纹理(使用2D绘图工具)。

我认为这让你的想法的要点得到了理解。我认为,如果“对象”靠近并移开,如果纹理似乎没有上下缩放,那么在交互式3D演示中,它不会很好地工作。但你没有说你实际上在做什么。

编辑2:

OpenGL二维投影:


小心
小心使用函数名,例如opengles 1.1有glOrthox和glOrthof。请确保检查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()
这将允许您在OpenGL中绘制二维图形(比使用三维投影简单得多)。要混合使用这两种图形,例如,先在三维中绘制,然后在二维中绘制,请单击第二个链接。

这里有一个关于二维绘图的优秀教程:


以下是混合这两种方法的基本知识:


我希望这就是你想要的。我从你的帖子中得到一个隐秘的怀疑,你在将纹理映射到三角形点以使其显示为“直线”时遇到了困难。你可能想查看NeHe上的基本纹理映射:

例如,gltexcoord2f根据映射到下一个绘制顶点的纹理的宽度和高度的百分比指定纹理内的点(0.0-1.0)。使用三角形扇形,您可以通过一些数学连接来计算使用顶点指定的整个对象的宽度和高度的百分比。

例如,一个带有纹理贴图的球体(地球的墨卡托投影)最好通过计算纬度线作为基本三角形扇形顶点值的基础来映射,因为它简化了纹理坐标的计算。使多边形近似于简单的几何图形可以让您使用三角法更轻松地计算纹理坐标。

我希望这会有所帮助。

He在这里,我将不再继续你必须修改的桌面示例。这是一个OpenGLES示例,它可以进行正确的3D纹理映射。你可以使用我上面所说的和这个示例来进行2D纹理映射。


我认为下面的代码片段就是您所说的。但是,如果没有
restrape()
中的hack,它会因
GL\u最近的
和非均匀的视口大小而闪烁得非常糟糕。任何洞察都将不胜感激

不过它使用纹理坐标生成,所以我不确定在OpenGL ES 1.1前端应该告诉你什么。一个解决方案中的PowerVR代表,但不是很明确

#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;
}
#包括
#包括
#包括
静态GLuint-texName;
void init(void)
{
glClearColor(0,0,0,0);
//创建随机纹理
常量int texWidth=8;
const int texHeight=8;
GLubyte-tex[texHeight][texWidth][4];
对于(int i=0;i#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;
}