我使用此source code作为我的基础,并尝试根据我的要求更改代码。我已经包含以下代码来在图像上创建网格。
- (无效)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];
}
编辑这是我作为一个输出得到的。虽然预计是常规网格......
答案 0 :(得分:3)
猜测网格被切除zNear值。尝试将z值更改为-2。
verticesArr[count+2] = -2.0f;
verticesArr[count+5] = -2.0f;
默认情况下,摄像机位于原点,指向负z轴,并具有向上的(0,1,0)。
请注意,您的网格不在视锥体(金字塔)中。在OpenGL红皮书中查看:
答案 1 :(得分:2)
由于顶点的排序方式,网格不规则。你还确定GL_TRIANGLE_STRIP是你想要的选择。也许,GL_TRIANGLES就是你所需要的。
我建议使用indices数组更简单的解决方案。例如,在初始化代码中,按正常顺序为网格创建顶点和纹理数组:
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);
}
实际上,这个索引顺序意味着tringle呈现如下:
(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);
希望这会有所帮助。
答案 2 :(得分:1)
This是一个关于在3D中绘制网格的精彩教程。它应该有必要的代码来帮助你。我不确定你是在使用3D还是2D,但即使它是2D,也应该很容易适应你的需求。希望有所帮助!