gpt4 book ai didi

ios - 如何将多重纹理用作一种纹理?

转载 作者:行者123 更新时间:2023-11-29 04:00:28 24 4
gpt4 key购买 nike

我想使用glues(函数如下)来绘制球体,它只支持单个纹理。我必须在iphone4上使用大纹理(8096X4096)。我将大纹理分成几个小纹理(512X512)。如何使用多重纹理将这些小纹理组合成一个大纹理传递给 gluSphere 使用???

提前致谢!

   //glues draw sphere function
GLAPI void APIENTRY gluSphere(GLUquadric* qobj, GLfloat radius, GLint slices, GLint stacks)
{
GLint i, j;
GLfloat sinCache1a[CACHE_SIZE];
GLfloat cosCache1a[CACHE_SIZE];
GLfloat sinCache2a[CACHE_SIZE];
GLfloat cosCache2a[CACHE_SIZE];
GLfloat sinCache3a[CACHE_SIZE];
GLfloat cosCache3a[CACHE_SIZE];
GLfloat sinCache1b[CACHE_SIZE];
GLfloat cosCache1b[CACHE_SIZE];
GLfloat sinCache2b[CACHE_SIZE];
GLfloat cosCache2b[CACHE_SIZE];
GLfloat sinCache3b[CACHE_SIZE];
GLfloat cosCache3b[CACHE_SIZE];
GLfloat angle;
GLfloat zLow, zHigh;
GLfloat sintemp1 = 0.0, sintemp2 = 0.0, sintemp3 = 0.0, sintemp4 = 0.0;
GLfloat costemp1 = 0.0, costemp2 = 0.0, costemp3 = 0.0, costemp4 = 0.0;
GLfloat vertices[(CACHE_SIZE+1)*2][3];
GLfloat texcoords[(CACHE_SIZE+1)*2][2];
GLfloat normals[(CACHE_SIZE+1)*2][3];
GLboolean needCache2, needCache3;
GLint start, finish;
GLboolean texcoord_enabled;
GLboolean normal_enabled;
GLboolean vertex_enabled;
GLboolean color_enabled;

if (slices>=CACHE_SIZE)
{
slices=CACHE_SIZE-1;
}

if (stacks>=CACHE_SIZE)
{
stacks=CACHE_SIZE-1;
}

if (slices<2 || stacks<1 || radius<0.0)
{
gluQuadricError(qobj, GLU_INVALID_VALUE);
return;
}

/* Cache is the vertex locations cache */
/* Cache2 is the various normals at the vertices themselves */
/* Cache3 is the various normals for the faces */
needCache2=needCache3=GL_FALSE;

if (qobj->normals==GLU_SMOOTH)
{
needCache2=GL_TRUE;
}

if (qobj->normals==GLU_FLAT)
{
if (qobj->drawStyle!=GLU_POINT)
{
needCache3=GL_TRUE;
}
if (qobj->drawStyle==GLU_LINE)
{
needCache2=GL_TRUE;
}
}

for (i=0; i<slices; i++)
{
angle=2.0f*PI*i/slices;
sinCache1a[i]=(GLfloat)sin(angle);
cosCache1a[i]=(GLfloat)cos(angle);
if (needCache2)
{
sinCache2a[i] = sinCache1a[i];
cosCache2a[i] = cosCache1a[i];
}
}

for (j=0; j<=stacks; j++)
{
angle=PI*j/stacks;
if (needCache2)
{
if (qobj->orientation==GLU_OUTSIDE)
{
sinCache2b[j]=(GLfloat)sin(angle);
cosCache2b[j]=(GLfloat)cos(angle);
}
else
{
sinCache2b[j]=(GLfloat)-sin(angle);
cosCache2b[j]=(GLfloat)-cos(angle);
}
}

sinCache1b[j]=(GLfloat)(radius*sin(angle));
cosCache1b[j]=(GLfloat)(radius*cos(angle));
}

/* Make sure it comes to a point */
sinCache1b[0]=0;
sinCache1b[stacks]=0;

if (needCache3)
{
for (i=0; i<slices; i++)
{
angle=2.0f*PI*(i-0.5f)/slices;
sinCache3a[i]=(GLfloat)sin(angle);
cosCache3a[i]=(GLfloat)cos(angle);
}
for (j=0; j<=stacks; j++)
{
angle=PI*(j-0.5f)/stacks;
if (qobj->orientation==GLU_OUTSIDE)
{
sinCache3b[j]=(GLfloat)sin(angle);
cosCache3b[j]=(GLfloat)cos(angle);
}
else
{
sinCache3b[j]=(GLfloat)-sin(angle);
cosCache3b[j]=(GLfloat)-cos(angle);
}
}
}

sinCache1a[slices]=sinCache1a[0];
cosCache1a[slices]=cosCache1a[0];
if (needCache2)
{
sinCache2a[slices]=sinCache2a[0];
cosCache2a[slices]=cosCache2a[0];
}
if (needCache3)
{
sinCache3a[slices]=sinCache3a[0];
cosCache3a[slices]=cosCache3a[0];
}

/* Store status of enabled arrays */
texcoord_enabled=GL_FALSE; //glIsEnabled(GL_TEXTURE_COORD_ARRAY);
normal_enabled=GL_FALSE; //glIsEnabled(GL_NORMAL_ARRAY);
vertex_enabled=GL_FALSE; //glIsEnabled(GL_VERTEX_ARRAY);
color_enabled=GL_FALSE; //glIsEnabled(GL_COLOR_ARRAY);

/* Enable arrays */
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
if (qobj->textureCoords)
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
}
else
{
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
if (qobj->normals!=GLU_NONE)
{
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, normals);
}
else
{
glDisableClientState(GL_NORMAL_ARRAY);
}
glDisableClientState(GL_COLOR_ARRAY);

switch (qobj->drawStyle)
{
case GLU_FILL:
if (!(qobj->textureCoords))
{
start=1;
finish=stacks-1;

/* Low end first (j == 0 iteration) */
sintemp2=sinCache1b[1];
zHigh=cosCache1b[1];

switch(qobj->normals)
{
case GLU_FLAT:
sintemp3=sinCache3b[1];
costemp3=cosCache3b[1];
normals[0][0]=sinCache3a[0]*sinCache3b[0];
normals[0][1]=cosCache3a[0]*sinCache3b[0];
normals[0][2]=cosCache3b[0];
break;
case GLU_SMOOTH:
sintemp3=sinCache2b[1];
costemp3=cosCache2b[1];
normals[0][0]=sinCache2a[0]*sinCache2b[0];
normals[0][1]=cosCache2a[0]*sinCache2b[0];
normals[0][2]=cosCache2b[0];
break;
default:
break;
}

vertices[0][0]=0.0f;
vertices[0][1]=0.0f;
vertices[0][2]=radius;

if (qobj->orientation==GLU_OUTSIDE)
{
for (i=slices; i>=0; i--)
{
switch(qobj->normals)
{
case GLU_SMOOTH:
normals[slices-i+1][0]=sinCache2a[i]*sintemp3;
normals[slices-i+1][1]=cosCache2a[i]*sintemp3;
normals[slices-i+1][2]=costemp3;
break;
case GLU_FLAT:
if (i!=slices)
{
normals[slices-i+1][0]=sinCache3a[i+1]*sintemp3;
normals[slices-i+1][1]=cosCache3a[i+1]*sintemp3;
normals[slices-i+1][2]=costemp3;
}
else
{
/* We must add any normal here */
normals[slices-i+1][0]=sinCache3a[i]*sintemp3;
normals[slices-i+1][1]=cosCache3a[i]*sintemp3;
normals[slices-i+1][2]=costemp3;
}
break;
case GLU_NONE:
default:
break;
}
vertices[slices-i+1][0]=sintemp2*sinCache1a[i];
vertices[slices-i+1][1]=sintemp2*cosCache1a[i];
vertices[slices-i+1][2]=zHigh;
}
}
else
{
for (i=0; i<=slices; i++)
{
switch(qobj->normals)
{
case GLU_SMOOTH:
normals[i+1][0]=sinCache2a[i]*sintemp3;
normals[i+1][1]=cosCache2a[i]*sintemp3;
normals[i+1][2]=costemp3;
break;
case GLU_FLAT:
normals[i+1][0]=sinCache3a[i]*sintemp3;
normals[i+1][1]=cosCache3a[i]*sintemp3;
normals[i+1][2]=costemp3;
break;
case GLU_NONE:
default:
break;
}
vertices[i+1][0]=sintemp2*sinCache1a[i];
vertices[i+1][1]=sintemp2*cosCache1a[i];
vertices[i+1][2]=zHigh;
}
}
glDrawArrays(GL_TRIANGLE_FAN, 0, (slices+2));

/* High end next (j==stacks-1 iteration) */
sintemp2=sinCache1b[stacks-1];
zHigh=cosCache1b[stacks-1];
switch(qobj->normals)
{
case GLU_FLAT:
sintemp3=sinCache3b[stacks];
costemp3=cosCache3b[stacks];
normals[0][0]=sinCache3a[stacks]*sinCache3b[stacks];
normals[0][1]=cosCache3a[stacks]*sinCache3b[stacks];
normals[0][2]=cosCache3b[stacks];
break;
case GLU_SMOOTH:
sintemp3=sinCache2b[stacks-1];
costemp3=cosCache2b[stacks-1];
normals[0][0]=sinCache2a[stacks]*sinCache2b[stacks];
normals[0][1]=cosCache2a[stacks]*sinCache2b[stacks];
normals[0][2]=cosCache2b[stacks];
break;
default:
break;
}

vertices[0][0]=0.0f;
vertices[0][1]=0.0f;
vertices[0][2]=-radius;

if (qobj->orientation==GLU_OUTSIDE)
{
for (i=0; i<=slices; i++)
{
switch(qobj->normals)
{
case GLU_SMOOTH:
normals[i+1][0]=sinCache2a[i]*sintemp3;
normals[i+1][1]=cosCache2a[i]*sintemp3;
normals[i+1][2]=costemp3;
break;
case GLU_FLAT:
normals[i+1][0]=sinCache3a[i]*sintemp3;
normals[i+1][1]=cosCache3a[i]*sintemp3;
normals[i+1][2]=costemp3;
break;
case GLU_NONE:
default:
break;
}
vertices[i+1][0]=sintemp2*sinCache1a[i];
vertices[i+1][1]=sintemp2*cosCache1a[i];
vertices[i+1][2]=zHigh;
}
}
else
{
for (i=slices; i>=0; i--)
{
switch(qobj->normals)
{
case GLU_SMOOTH:
normals[slices-i+1][0]=sinCache2a[i]*sintemp3;
normals[slices-i+1][1]=cosCache2a[i]*sintemp3;
normals[slices-i+1][2]=costemp3;
break;
case GLU_FLAT:
if (i!=slices)
{
normals[slices-i+1][0]=sinCache3a[i+1]*sintemp3;
normals[slices-i+1][1]=cosCache3a[i+1]*sintemp3;
normals[slices-i+1][2]=costemp3;
}
else
{
normals[slices-i+1][0]=sinCache3a[i]*sintemp3;
normals[slices-i+1][1]=cosCache3a[i]*sintemp3;
normals[slices-i+1][2]=costemp3;
}
break;
case GLU_NONE:
default:
break;
}
vertices[slices-i+1][0]=sintemp2*sinCache1a[i];
vertices[slices-i+1][1]=sintemp2*cosCache1a[i];
vertices[slices-i+1][2]=zHigh;
}
}
glDrawArrays(GL_TRIANGLE_FAN, 0, (slices+2));
}
else
{
start=0;
finish=stacks;
}

for (j=start; j<finish; j++)
{
zLow=cosCache1b[j];
zHigh=cosCache1b[j+1];
sintemp1=sinCache1b[j];
sintemp2=sinCache1b[j+1];
switch(qobj->normals)
{
case GLU_FLAT:
sintemp4=sinCache3b[j+1];
costemp4=cosCache3b[j+1];
break;
case GLU_SMOOTH:
if (qobj->orientation==GLU_OUTSIDE)
{
sintemp3=sinCache2b[j+1];
costemp3=cosCache2b[j+1];
sintemp4=sinCache2b[j];
costemp4=cosCache2b[j];
}
else
{
sintemp3=sinCache2b[j];
costemp3=cosCache2b[j];
sintemp4=sinCache2b[j+1];
costemp4=cosCache2b[j+1];
}
break;
default:
break;
}
for (i=0; i<=slices; i++)
{
switch(qobj->normals)
{
case GLU_SMOOTH:
normals[i*2][0]=sinCache2a[i]*sintemp3;
normals[i*2][1]=cosCache2a[i]*sintemp3;
normals[i*2][2]=costemp3;
break;
case GLU_FLAT:
normals[i*2][0]=sinCache3a[i]*sintemp4;
normals[i*2][1]=cosCache3a[i]*sintemp4;
normals[i*2][2]=costemp4;
break;
case GLU_NONE:
default:
break;
}
if (qobj->orientation==GLU_OUTSIDE)
{
if (qobj->textureCoords)
{
texcoords[i*2][0]=1-(GLfloat)i/slices;
texcoords[i*2][1]=1-(GLfloat)(j+1)/stacks;
}
vertices[i*2][0]=sintemp2*sinCache1a[i];
vertices[i*2][1]=sintemp2*cosCache1a[i];
vertices[i*2][2]=zHigh;
}
else
{
if (qobj->textureCoords)
{
texcoords[i*2][0]=1-(GLfloat)i/slices;
texcoords[i*2][1]=1-(GLfloat)j/stacks;
}
vertices[i*2][0]=sintemp1*sinCache1a[i];
vertices[i*2][1]=sintemp1*cosCache1a[i];
vertices[i*2][2]=zLow;
}
switch(qobj->normals)
{
case GLU_SMOOTH:
normals[i*2+1][0]=sinCache2a[i]*sintemp4;
normals[i*2+1][1]=cosCache2a[i]*sintemp4;
normals[i*2+1][2]=costemp4;
break;
case GLU_FLAT:
normals[i*2+1][0]=sinCache3a[i]*sintemp4;
normals[i*2+1][1]=cosCache3a[i]*sintemp4;
normals[i*2+1][2]=costemp4;
break;
case GLU_NONE:
default:
break;
}
if (qobj->orientation==GLU_OUTSIDE)
{
if (qobj->textureCoords)
{
texcoords[i*2+1][0]=1-(GLfloat)i/slices;
texcoords[i*2+1][1]=1-(GLfloat)j/stacks;
}
vertices[i*2+1][0]=sintemp1*sinCache1a[i];
vertices[i*2+1][1]=sintemp1*cosCache1a[i];
vertices[i*2+1][2]=zLow;
}
else
{
if (qobj->textureCoords)
{
texcoords[i*2+1][0]=1-(GLfloat)i/slices;
texcoords[i*2+1][1]=1-(GLfloat)(j+1)/stacks;
}
vertices[i*2+1][0]=sintemp2*sinCache1a[i];
vertices[i*2+1][1]=sintemp2*cosCache1a[i];
vertices[i*2+1][2]=zHigh;
}
}
glDrawArrays(GL_TRIANGLE_STRIP, 0, (slices+1)*2);
}
break;
case GLU_POINT:
for (j=0; j<=stacks; j++)
{
sintemp1=sinCache1b[j];
costemp1=cosCache1b[j];
switch(qobj->normals)
{
case GLU_FLAT:
case GLU_SMOOTH:
sintemp2=sinCache2b[j];
costemp2=cosCache2b[j];
break;
default:
break;
}

for (i=0; i<slices; i++)
{
switch(qobj->normals)
{
case GLU_FLAT:
case GLU_SMOOTH:
normals[i][0]=sinCache2a[i]*sintemp2;
normals[i][1]=cosCache2a[i]*sintemp2;
normals[i][2]=costemp2;
break;
case GLU_NONE:
default:
break;
}
zLow=j*radius/stacks;
if (qobj->textureCoords)
{
texcoords[i][0]=1-(GLfloat)i/slices;
texcoords[i][1]=1-(GLfloat)j/stacks;
}
vertices[i][0]=sintemp1*sinCache1a[i];
vertices[i][1]=sintemp1*cosCache1a[i];
vertices[i][2]=costemp1;
}
glDrawArrays(GL_POINTS, 0, slices);
}
break;
case GLU_LINE:
case GLU_SILHOUETTE:
for (j=1; j<stacks; j++)
{
sintemp1=sinCache1b[j];
costemp1=cosCache1b[j];
switch(qobj->normals)
{
case GLU_FLAT:
case GLU_SMOOTH:
sintemp2=sinCache2b[j];
costemp2=cosCache2b[j];
break;
default:
break;
}

for (i=0; i<=slices; i++)
{
switch(qobj->normals)
{
case GLU_FLAT:
normals[i][0]=sinCache3a[i]*sintemp2;
normals[i][1]=cosCache3a[i]*sintemp2;
normals[i][2]=costemp2;
break;
case GLU_SMOOTH:
normals[i][0]=sinCache2a[i]*sintemp2;
normals[i][1]=cosCache2a[i]*sintemp2;
normals[i][2]=costemp2;
break;
case GLU_NONE:
default:
break;
}
if (qobj->textureCoords)
{
texcoords[i][0]=1-(GLfloat)i/slices;
texcoords[i][1]=1-(GLfloat)j/stacks;
}
vertices[i][0]=sintemp1*sinCache1a[i];
vertices[i][1]=sintemp1*cosCache1a[i];
vertices[i][2]=costemp1;
}
glDrawArrays(GL_LINE_STRIP, 0, slices+1);
}

for (i=0; i<slices; i++)
{
sintemp1=sinCache1a[i];
costemp1=cosCache1a[i];
switch(qobj->normals)
{
case GLU_FLAT:
case GLU_SMOOTH:
sintemp2=sinCache2a[i];
costemp2=cosCache2a[i];
break;
default:
break;
}

for (j=0; j<=stacks; j++)
{
switch(qobj->normals)
{
case GLU_FLAT:
normals[j][0]=sintemp2*sinCache3b[j];
normals[j][1]=costemp2*sinCache3b[j];
normals[j][2]=cosCache3b[j];
break;
case GLU_SMOOTH:
normals[j][0]=sintemp2*sinCache2b[j];
normals[j][1]=costemp2*sinCache2b[j];
normals[j][2]=cosCache2b[j];
break;
case GLU_NONE:
default:
break;
}

if (qobj->textureCoords)
{
texcoords[j][0]=1-(GLfloat)i/slices;
texcoords[j][1]=1-(GLfloat)j/stacks;
}
vertices[j][0]=sintemp1*sinCache1b[j];
vertices[j][1]=costemp1*sinCache1b[j];
vertices[j][2]=cosCache1b[j];
}
glDrawArrays(GL_LINE_STRIP, 0, stacks+1);
}
break;
default:
break;
}

/* Disable or re-enable arrays */
if (vertex_enabled)
{
/* Re-enable vertex array */
glEnableClientState(GL_VERTEX_ARRAY);
}
else
{
glDisableClientState(GL_VERTEX_ARRAY);
}

if (texcoord_enabled)
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
else
{
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

if (normal_enabled)
{
glEnableClientState(GL_NORMAL_ARRAY);
}
else
{
glDisableClientState(GL_NORMAL_ARRAY);
}

if (color_enabled)
{
glEnableClientState(GL_COLOR_ARRAY);
}
else
{
glDisableClientState(GL_COLOR_ARRAY);
}
}

/结束/

最佳答案

首先回答这个问题,如果你使用 ES2,你可以尝试加载所有 16x8 纹理,但我想说其中 32 个纹理目前在 iOS 上是最大的(从事件纹理的枚举来看)。如果您成功获得了所有纹理,则需要根据片段着色器中的纹理坐标计算要使用的纹理:

int verticalTextureCount, horizontalTextureCount; //input tile count
float texCoordX, texCoordY; //input texture coordinates
int textureX = (int)(texCoordX*horizontalTextureCount); //texture to use
int textureY = (int)(texCoordY*verticalTextureCount); //texture to use
texCoordX -= (1.0/horizontalTextureCount)*textureX; //decreas offset
texCoordY -= (1.0/verticalTextureCount)*textureY; //decreas offset
texCoordX *= horizontalTextureCount; //rescale
texCoordY *= verticalTextureCount; //rescale

此时,您可以使用textureX和textureY编写verticalTextureCount*horizo​​ntalTextureCount“if语句”来确定要使用的纹理和texCoors来获取纹理元素。或多或少就是这样。

其次,对于讨论,不,不要这样做。如果纹理太大,那就太大了。如果我敢猜测,我会说您正在尝试制作一个具有某种行星的应用程序,您希望在该行星上具有一些极端的缩放功能,并且为此您需要一些详细的纹理。如果是这种情况或类似的情况,请创建多个用作纹理的图像,例如:有 1 个图像,上面放置了整个球体,4 个图像,每个图像上有四分之一的球体,16 个图像......以及所有这些图像大小相同,如 2048*2048。

现在是最好的部分,您需要一个动态系统来根据您的需要加载和卸载图像。如果球体缩小,您只需要 1 个完整图像并像以前一样进行绘制。如果放大很多,您需要检查什么级别的纹理最合适,并检查球体的哪些部分是可见的,以便您可以仅加载所需的纹理并仅绘制球体的可见部分。这不是一件容易的事,但它与许多可以 3D 看到我们的星球的应用程序的原理大致相同。它在运行时检查您正在查看地球的哪个部分以及哪些细节,通常会向服务器发送请求以在需要时接收详细图像,并创建要显示的详细纹理。

关于ios - 如何将多重纹理用作一种纹理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15921501/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com