【问题标题】:Mesh creation in openGL iphone sdk在 openGL iphone sdk 中创建网格
【发布时间】:2011-08-16 05:48:44
【问题描述】:

我使用这个source code 作为我的基础并尝试根据我的要求更改代码。我已包含以下代码以在图像上创建网格。

-(void)populateMesh{

verticalDivisions = kVerticalDivisions;
horizontalDivisions = kHorisontalDivisions; 
unsigned int verticesArrsize = (kVerticalDivisions * ((2 + kHorisontalDivisions * 2) * 3));
unsigned int textureCoordsArraySize = kVerticalDivisions * ((2 + kHorisontalDivisions * 2) * 2);
verticesArr = (GLfloat *)malloc(verticesArrsize * sizeof(GLfloat));
textureCoordsArr = (GLfloat*)malloc(textureCoordsArraySize * sizeof(GLfloat));
if (verticesArr == NULL) {
    NSLog(@"verticesArr = NULL!");
}   
float height = kWindowHeight/verticalDivisions;
float width = kWindowWidth/horizontalDivisions;
int i,j, count;
count = 0;
for (j=0; j<verticalDivisions; j++) {
    for (i=0; i<=horizontalDivisions; i++, count+=6) { //2 vertices each time...
        float currX = i * width;
        float currY = j * height;
        verticesArr[count] = currX;
        verticesArr[count+1] = currY + height;
        verticesArr[count+2] = 0.0f;            
        verticesArr[count+3] = currX;
        verticesArr[count+4] = currY;
        verticesArr[count+5] = 0.0f;
    } 
}
float xIncrease = 1.0f/horizontalDivisions;
float yIncrease = 1.0f/verticalDivisions;   
int x,y;
//int elements;
count = 0;  
for (y=0; y<verticalDivisions; y++) {
    for (x=0; x<horizontalDivisions+1; x++, count+=4) {
        float currX = x *xIncrease; 
        float currY = y * yIncrease;
        textureCoordsArr[count] = (float)currX;
        textureCoordsArr[count+1] = (float)currY + yIncrease;
        textureCoordsArr[count+2] = (float)currX;
        textureCoordsArr[count+3] = (float)currY;
    }
}
//  int cnt;
//  int cnt = 0;
    NSLog(@"expected %i vertices, and %i vertices were done",(verticalDivisions * ((2 + horizontalDivisions*2 ) * 2) ) , count );
}

以下是drawView代码。

- (void)drawView:(GLView*)view;
{
static GLfloat rot = 0.0;
glBindTexture(GL_TEXTURE_2D, texture[0]);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

glEnableClientState(GL_VERTEX_ARRAY);
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, textureCoordsArr);
glVertexPointer(3, GL_FLOAT, 0, verticesArr);
glPushMatrix();{
    int i;
    for (i=0; i<verticalDivisions; i++) {
        glDrawArrays(GL_TRIANGLE_STRIP, i*(horizontalDivisions*2+2), horizontalDivisions*2+2);
    }
}glPopMatrix();
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);
}

在设置视图中,我在函数末尾调用了 [self populateMesh];。 我的问题是更改代码后,屏幕上出现了一个空白而不是黑色的视图。谁能弄清楚我在哪里做错了。我是 openGL 的新手,并试图通过网格来操纵图像。请尽快帮忙。提前致谢。

以下是设置视图代码。

-(void)setupView:(GLView*)view {    

 const GLfloat zNear = 0.01, zFar = 1000.0, fieldOfView = 45.0; 
 GLfloat size;   
 glEnable(GL_DEPTH_TEST);
 glMatrixMode(GL_PROJECTION);
 size = zNear *  tanf(DEGREES_TO_RADIANS(fieldOfView) / 2.0);
 CGRect rect =  view.bounds; 
 glFrustumf(-size, size, -size / (rect.size.width /  rect.size.height), size /    (rect.size.width / rect.size.height),  zNear, zFar); 
 glViewport(0, 0, rect.size.width, rect.size.height);  
 glMatrixMode(GL_MODELVIEW);  
 glEnable(GL_TEXTURE_2D);
 glEnable(GL_BLEND);
 glBlendFunc(GL_ONE, GL_SRC_COLOR);
 glGenTextures(1, &texture[0]);
 glBindTexture(GL_TEXTURE_2D, texture[0]);
 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
 NSString *path = [[NSBundle mainBundle] pathForResource:@"texture" ofType:@"png"]; 
 NSData *texData = [[NSData alloc] initWithContentsOfFile:path];
 UIImage *image = [[UIImage alloc] initWithData:texData];
 if (image == nil)
 NSLog(@"Do real error checking here");     
 GLuint width =  CGImageGetWidth(image.CGImage);
 GLuint height = CGImageGetHeight(image.CGImage);
 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
 void *imageData = malloc( height * width * 4 );
 CGContextRef context = CGBitmapContextCreate( imageData, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );

 CGContextTranslateCTM (context, 0, height);

 CGContextScaleCTM (context, 1.0, -1.0);

 CGColorSpaceRelease( colorSpace );

 CGContextClearRect( context, CGRectMake( 0, 0, width, height ) );

 CGContextDrawImage( context, CGRectMake( 0, 0, width, height ),image.CGImage );

 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);

 CGContextRelease(context);

 free(imageData);
 [image release];
 [texData release];
 [self populateMesh]; 
}

编辑这是我得到的输出。虽然预期是常规网格......

【问题讨论】:

  • 您是否正确设置了模型和投影视图矩阵?您能否提供带有矩阵初始设置的代码?
  • 确保图片的像素大小可以表示为 2 的幂。例如 512x512
  • 我已包含设置视图代码。在实现 populateMesh 函数之前,我能够显示图像...

标签: iphone image-processing opengl-es


【解决方案1】:

猜测网格是用 zNear 值切除的。尝试将 z 值更改为 -2。

verticesArr[count+2] = -2.0f; 
verticesArr[count+5] = -2.0f;

默认情况下,相机位于原点,指向负 z 轴,向上矢量为 (0, 1, 0)。

请注意,您的网格不在视锥体(金字塔)中。查看OpenGL红皮书:

http://glprogramming.com/red/chapter03.html

【讨论】:

  • 感谢您的回复...在编辑您的更改并评论 glFrustumf() 语句后,我得到了上面的视图。它与我以前所拥有的没有太大区别。还有其他问题……你能弄清楚吗?
【解决方案2】:

由于顶点的排序方式,网格不规则。您还确定 GL_TRIANGLE_STRIP 是所需的选项。也许,GL_TRIANGLES 就是你所需要的。

我建议使用索引数组更简单的解决方案。例如,在初始化代码中,按照正常顺序为您的网格制作顶点和纹理数组:

0 1 2
3 4 5
6 7 8

更新:

- (void) setup
{
  vertices = (GLfloat*)malloc(rows*colums*3*sizeof(GLfloat));
  texCoords = (GLfloat*)malloc(rows*columns*2*sizeof(GLfloat));
  indices = (GLubyte*)malloc((rows-1)*(columns-1)*6*sizeof(GLubyte));

  float xDelta = horizontalDivisions/columns;
  float yDelta = verticalDivisions/rows;

  for (int i=0;i<columns;i++) {
    for(int j=0;j<rows; j++) {
      int index = j*columns+i;
      vertices[3*index+0] = i*xDelta; //x
      vertices[3*index+1] = j*yDelta; //y
      vertices[3*index+2] = -10; //z

      texCoords[2*index+0] = i/(float)(columns-1); //x texture coordinate
      texCoords[2*index+1] = j/(float)(rows-1); //y tex coordinate
    }
  }

  for (int i=0;i<columns-1;i++) {
   for(int j=0;j<rows-1; j++) {

     indices[6*(j*columns+i)+0] = j*columns+i;
     indices[6*(j*columns+i)+1] = j*columns+i+1;
     indices[6*(j*columns+i)+2] = (j+1)*columns+i;

     indices[6*(j*columns+i)+3] = j*columns+i+1;
     indices[6*(j*columns+i)+4] = (j+1)*columns+i+1;
     indices[6*(j*columns+i)+5] = (j+1)*columns+i;
   }
 }
}

- (void) dealloc {
  free(vertices); free(texCoords); free(indices);
}

实际上,这个索引顺序意味着三角形呈现如下:

(013)(143)(124)(254)(346)(476)... and so on.

在渲染方法中使用以下行:

glVertexPointer(3, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glDrawElements(GL_TRIANGLES, 6*(columns-1)*(rows-1), GL_UNSIGNED_BYTE, indices);

希望这会有所帮助。

【讨论】:

  • 添加了微小的更新。不需要循环来绘制元素。更简单的解决方案。我没有测试代码,我是自己写的,所以它可能包含一些错误,但概念很清楚。
【解决方案3】:

This 是一个很棒的 3D 网格绘制教程。它应该有必要的代码来帮助你。我不确定您是在 3D 还是 2D 中工作,但即使是 2D,也应该很容易适应您的需求。希望对您有所帮助!

【讨论】:

    猜你喜欢
    • 2021-09-23
    • 1970-01-01
    • 2022-11-23
    • 2012-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-12
    • 1970-01-01
    相关资源
    最近更新 更多