Возникло много проблем с получением текстурных карт для работы в openGL ES (iphone).
Вот что я сделал:
- построил массив вершин
- построил массив граней, которые ссылаются на индексы массива вершин для каждой грани
- построил массив цветов, поэтому я могу быть уверен, что знаю, какая вершина куба какая.
Все это следующее Уроки Джеффа Ламарша . Получение объектов рендеринга и перемещения не является проблемой.
Теперь я пытаюсь заставить куб (на самом деле тайл, более узкий в Z, чем X или Y) прикрепить текстуру к двум противоположным граням (остальные могут появиться позже) Мне удалось получить одно лицо на работу, но я не получаю работоспособных результатов на любом другом лице.
Какой самый систематический способ текстурирования карты объекта в OpenGL ES, и может ли кто-нибудь увидеть, где ошибки в моем коде?
#import "GLViewController.h"
#import "ConstantsAndMacros.h"
#import "OpenGLCommon.h"
#import "Cube.h"
@implementation GLViewController
@synthesize initDone;
@synthesize tileArray;
@synthesize tileRows;
@synthesize tileCols;
@synthesize cubes;
@synthesize gridOffsetX;
@synthesize gridOffsetY;
@synthesize gridOffsetZ;
@synthesize tileSpacing;
- (void)drawView:(UIView *)theView
{
static GLfloat rot = 0.0;
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
// This is the same result as using Vertex3D, just faster to type and
// can be made const this way
static const Vertex3D vertices[]= {
{1.0f, -1.0f, 0.2f},
{1.0f, -1.0f, -0.2f},
{1.0f, 1.0f, -0.2f},
{1.0f, 1.0f, 0.2f},
{-1.0f, -1.0f, 0.2f},
{-1.0f, -1.0f, -0.2f},
{-1.0f, 1.0f, -0.2f},
{-1.0f, 1.0f, 0.2f}
};
static const Color3D colors[] = {
{1.0, 0.0, 0.0, 20.0},
{1.0, 1.0, 1.0, 20.0},
{1.0, 1.0, 1.0, 20.0},
{0.0, 0.0, 1.0, 20.0},
{0.0, 1.0, 0.0, 20.0},
{1.0, 1.0, 1.0, 20.0},
{1.0, 1.0, 1.0, 20.0},
{1.0, 1.0, 1.0, 20.0},
};
static const GLubyte cubeFaces[] = {
0, 1, 3,
2, 3, 1,
0, 3, 4,
3, 4, 7, // first main face
2, 1, 6, // second main face
1, 6, 5,
5, 6, 7,
5, 4, 7,
7, 6, 3,
6, 3, 2,
4, 0, 5,
1, 0, 5,
};
static const Vector3D normals[] = {
{0.200000, -0.400000, 0.000000},
{0.400000, -0.200000, -0.400000},
{0.333333, 0.333333, -0.333333},
{0.400000, 0.400000, -0.200000},
{-0.333333, -0.333333, 0.333333},
{-0.400000, -0.400000, -0.200000},
{-0.200000, 0.400000, -0.400000},
{-0.400000, 0.200000, 0.000000},
};
static const GLfloat texCoords[] = {
0.0, 0.0, // texture face
1.0, 1.0,
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
1.0, 0.0,
0.0, 0.0, // texture face
1.0, 1.0,
1.0, 0.0,
1.0, 0.0,
0.0, 1.0,
1.0, 1.0,
0.0, 0.0, // texture face
1.0, 1.0,
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
1.0, 0.0,
0.0, 0.0, // texture face
1.0, 1.0,
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
1.0, 0.0,
0.0, 0.0, // texture face
1.0, 1.0,
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
1.0, 0.0,
0.0, 0.0, //
1.0, 1.0,
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
1.0, 0.0,
};
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glLoadIdentity();
glClearColor(0.7, 0.7, 0.7, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glColorPointer(4, GL_FLOAT, 0, colors);
glNormalPointer(GL_FLOAT, 0, normals);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
NSMutableArray *tempRow;
Cube *tempCube;
for (int i = 1; i <= cubes.tileRows; i++)
{
tempRow = [cubes rowAtIndex:i-1];
for (int j = 1; j <= cubes.tileCols; j++)
{
tempCube = [tempRow objectAtIndex:j-1];
glLoadIdentity();
glTranslatef(gridOffsetX + (tileSpacing * (GLfloat)i), gridOffsetY + (tileSpacing * (GLfloat)j), gridOffsetZ);
glRotatef(rot, 1.0, 0.0, 0);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, cubeFaces);
}
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
static NSTimeInterval lastDrawTime;
if (lastDrawTime)
{
NSTimeInterval timeSinceLastDraw = [NSDate timeIntervalSinceReferenceDate] - lastDrawTime;
rot+=30 * timeSinceLastDraw;
}
//NSLog(@"rot is %f", rot);
lastDrawTime = [NSDate timeIntervalSinceReferenceDate];
}
-(void)setupView:(GLView*)view
{
initDone = NO;
tileRows = 5;
tileCols = 7;
gridOffsetX = 5.2f;
gridOffsetY = 6.9f;
gridOffsetZ = -14.0;
tileSpacing = -2.15f;
cubes = [[Cubes alloc] initWithRowCount:tileRows colCount: tileCols ];
const GLfloat zNear = 0.01, zFar = 1000.0, fieldOfView = 50.0;
GLfloat size;
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 2.0);
CGRect rect = view.bounds;
// glOrthof(-5.0, // Left
// 5.0, // Right
// -5.0 / (rect.size.width / rect.size.height), // Bottom
// 5.0 / (rect.size.width / rect.size.height), // Top
// 0.01, // Near
// 10000.0); // Far
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_COLOR_MATERIAL);
// Enable lighting
glEnable(GL_LIGHTING);
// Turn the first light on
glEnable(GL_LIGHT0);
// Define the ambient component of the first light
const GLfloat light0Ambient[] = {0.5, 0.5, 0.5, 1.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, light0Ambient);
// Define the diffuse component of the first light
const GLfloat light0Diffuse[] = {0.7, 0.7, 0.7, 1.0};
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0Diffuse);
// Define the specular component and shininess of the first light
const GLfloat light0Specular[] = {0.7, 0.7, 0.7, 1.0};
const GLfloat light0Shininess = 0.4;
glLightfv(GL_LIGHT0, GL_SPECULAR, light0Specular);
// Define the position of the first light
const GLfloat light0Position[] = {0.0, 10.0, 10.0, 0.0};
glLightfv(GL_LIGHT0, GL_POSITION, light0Position);
// Define a direction vector for the light, this one points right down the Z axis
const GLfloat light0Direction[] = {0.0, 0.0, -1.0};
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light0Direction);
// Define a cutoff angle. This defines a 90° field of vision, since the cutoff
// is number of degrees to each side of an imaginary line drawn from the light's
// position along the vector supplied in GL_SPOT_DIRECTION above
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0);
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:@"a-tile-64" 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 );
CGColorSpaceRelease( colorSpace );
CGContextClearRect( context, CGRectMake( 0, 0, width, height ) );
CGContextTranslateCTM( context, 0, height - 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];
glLoadIdentity();
};
- (void)dealloc
{
[tileArray release];
[cubes release];
[super dealloc];
}
@end