Iphone 如何在OpenGL ES中对立方体进行纹理映射?
在openGL ES(iphone)中使用纹理贴图有很多困难 以下是我所做的:Iphone 如何在OpenGL ES中对立方体进行纹理映射?,iphone,opengl-es,textures,Iphone,Opengl Es,Textures,在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
#导入“GLViewController.h”
#导入“ConstantsAndMacros.h”
#导入“OpenGLCommon.h”
#导入“Cube.h”
@视图控制器的实现
@合成尼替酮;
@合成替罗雷;
@合成罗非鱼;
@合成替利考;
@合成立方体;
@合成gridOffsetX;
@合成游离基;
@合成gridOffsetZ;
@合成替利司平;
-(无效)绘图视图:(UIView*)视图
{
静态GLROT=0.0;
glEnableClientState(GL_顶点_数组);
glEnableClientState(GL_颜色_阵列);
glEnableClientState(GL_普通_阵列);
glEnableClientState(GL_纹理_坐标_阵列);
//这与使用Vertex3D的结果相同,只是打字和打印速度更快
//可以用这种方法使其成为常数
静态常量Vertex3D顶点[]={
{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}
};
静态常量Color3D颜色[]={
{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},
};
静态常量GLubyte立方[]={
0, 1, 3,
2, 3, 1,
0, 3, 4,
3、4、7、//第一主面
2,1,6,//第二主面
1, 6, 5,
5, 6, 7,
5, 4, 7,
7, 6, 3,
6, 3, 2,
4, 0, 5,
1, 0, 5,
};
静态常量矢量3D法线[]={
{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},
};
静态常数GLfloat texCoords[]={
0.0,0.0,//纹理面
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,
1.0, 0.0,
1.0, 0.0,
0.0, 1.0,
1.0, 1.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,
0.0,0.0,//纹理面
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,
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_浮点,0,texCoords);
glLoadIdentity();
glClearColor(0.7,0.7,0.7,1.0);
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
glVertexPointer(3,GLU浮点,0,顶点);
glColorPointer(4,GL_浮点,0,颜色);
glNormalPointer(GL_FLOAT,0,法线);
glTexCoordPointer(2,GL_浮点,0,texCoords);
NSMutableArray*tempRow;
多维数据集*tempCube;
对于(int i=1;i我在学习OpenGL的时候一直在看这个问题,然后将转到OpenGL ES。因为没有人回答,我会告诉你我的想法,但是不要认为这是专家的意见。< /P>
要考虑的是,正如你所说的,你的顶点、颜色和普通数组包含8个“项目”,但是你的TexCOORD数组有36个“项目”。我很确定,当你使用<代码> GrDeleWrices >索引列表时,它使用这些索引从所有激活的数组中挑选项目。因此,你的TeXCOORD数组的最后28个项目将是NEV。如果要使用,它们将根据
cubeFaces
指定的索引进行挑选。在您链接的教程中,所有数组中有四个项目,这对对象的单个面非常有效
然而,使用3D对象的索引有点问题,因为尽管在立方体中重复使用了几个顶点,但它们用于不同三角形的纹理坐标不一定相同。事实上,它们的法线也不一定相同,因此在照亮obj时,这可能是代码的另一个问题ect
我不知道最好的解决方案是什么,这就是为什么我对这个问题的任何其他答案感兴趣…逐顶点绘制立方体是一个选项。我还想知道是否可以分别绘制立方体的每个面,并每次更改TexCoord数组。或者可能有更简单或标准的方法这种事情我还没有意识到!我还使用Jeff的教程启动了OpenGL ES
我建议简化您正在尝试的操作。例如:
- 忘掉常态吧
- 忘了颜色吧
- 忘了指数吧
- 创建将顶点绑定到其属性的结构
Jeff提供了一个有用的TextureVertexData3D结构来实现这一点
glVertexPointer(3, GL_FLOAT, sizeof(TexturedVertexData3D), &vertices[0]);
glTexCoordPointer(2, GL_FLOAT, sizeof(TexturedVertexData3D), &vertices[0].texCoords);
glDrawArrays(GL_TRIANGLES, 0, nVertices);