如何使用多纹理作为一个纹理?

时间:2013-04-10 09:05:31

标签: ios opengl-es

我想使用胶水(函数如下)来绘制球体,它只支持单个纹理。 我必须在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);
               }
            }

/ /

1 个答案:

答案 0 :(得分:1)

首先回答这个问题,如果您使用的是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中看到地球的应用程序的原理大致相同。它会在运行时检查您正在查看的行星的哪个部分以及详细信息,通常会向服务器发送请求,以便在需要时接收详细图像并创建要显示的详细纹理。