为什么我的 OpenGL ES 纹理无法正确渲染?
我正在使用 OpenGL 来制作我想要制作的应用程序。我一直在学习 apress 的书《Begining iPhone Games Development》。
我遇到的问题是,作为网格类的子类的 texturedQuad 似乎无法正确渲染。 (尽管它在模拟器中有效。)四边形渲染为我在texturedQuad类中设置的纯色,并且似乎没有渲染纹理。
这是一个名为 MenuOptionObject.m 的类,它是我尝试渲染的实际对象,我觉得它与示例中使用的 spaceShip.m 文件类似。该文件确实有效,所以我不明白为什么当我使用几乎相同的“引擎”(如果你可以这样称呼它)时,它不会起作用。
我有一种感觉,我错过了一些明显的东西。我所做的例子是有效的。我还有一个名为texturedButton 的类,它可以工作并且也使用texturedQuad。
这是 mesh.m 代码:
#import "Mesh.h"
#import "MaterialController.h"
#import "TexturedQuad.h"
@implementation Mesh
@synthesize vertexCount,vertexSize,colorSize,renderStyle,vertexes,colors;
- (id)initWithVertexes:(CGFloat*)verts
vertexCount:(NSInteger)vertCount
vertexSize:(NSInteger)vertSize
renderStyle:(GLenum)style;
{
self = [super init];
if (self != nil)
{
self.vertexes = verts;
self.vertexCount = vertCount;
self.vertexSize = vertSize;
self.renderStyle = style;
}
return self;
}
// called once every frame
-(void)render
{
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);
// load arrays into the engine
glVertexPointer(vertexSize, GL_FLOAT, 0, vertexes);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(colorSize, GL_FLOAT, 0, colors);
glEnableClientState(GL_COLOR_ARRAY);
//render
glDrawArrays(renderStyle, 0, vertexCount);
}
+(CGRect)meshBounds:(Mesh*)mesh scale:(BBPoint)scale
{
if (mesh == nil) return CGRectZero;
// need to run through my vertexes and find my extremes
if (mesh.vertexCount < 2) return CGRectZero;
CGFloat xMin,yMin,xMax,yMax;
xMin = xMax = mesh.vertexes[0];
yMin = yMax = mesh.vertexes[1];
NSInteger index;
for (index = 0; index < mesh.vertexCount; index++) {
NSInteger position = index * mesh.vertexSize;
if (xMin > mesh.vertexes[position] * scale.x) xMin = mesh.vertexes[position] * scale.x;
if (xMax < mesh.vertexes[position] * scale.x) xMax = mesh.vertexes[position] * scale.x;
if (yMin > mesh.vertexes[position + 1] * scale.y) yMin = mesh.vertexes[position + 1] * scale.y;
if (yMax < mesh.vertexes[position + 1] * scale.y) yMax = mesh.vertexes[position + 1] * scale.y;
}
CGRect meshBounds = CGRectMake(xMin, yMin, xMax - xMin, yMax - yMin);
if (CGRectGetWidth(meshBounds) < 1.0) meshBounds.size.width = 1.0;
if (CGRectGetHeight(meshBounds) < 1.0) meshBounds.size.height = 1.0;
return meshBounds;
}
- (void) dealloc
{
[super dealloc];
}
@end
这是 texturedQuad.m 代码:
#import "TexturedQuad.h"
static CGFloat TexturedQuadVertexes[8] =
{
-0.5,-0.5, 0.5,-0.5,
-0.5,0.5, 0.5,0.5
};
static CGFloat TexturedQuadColorValues[16] =
{
1.0,1.0,1.0,1.0,
1.0,1.0,1.0,1.0,
1.0,1.0,1.0,1.0,
1.0,1.0,1.0,1.0
};
@implementation TexturedQuad
@synthesize uvCoordinates,materialKey;
- (id) init
{
self = [super initWithVertexes:TexturedQuadVertexes vertexCount:4 vertexSize:2 renderStyle:GL_TRIANGLE_STRIP];
if (self != nil) {
// 4 vertexes
uvCoordinates = (CGFloat *) malloc(8 * sizeof(CGFloat));
colors = TexturedQuadColorValues;
colorSize = 4;
}
return self;
}
// called once every frame
-(void)render
{
glVertexPointer(vertexSize, GL_FLOAT, 0, vertexes);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(colorSize, GL_FLOAT, 0, colors);
glEnableClientState(GL_COLOR_ARRAY);
if (materialKey != nil) {
[[MaterialController sharedController] bindMaterial:materialKey];
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, uvCoordinates);
}
//render
glDrawArrays(renderStyle, 0, vertexCount);
}
- (void) dealloc
{
free(uvCoordinates);
[super dealloc];
}
@end
最后是 MenuOptionObject.m:
#import "MenuOptionObject.h"
#import "MaterialController.h"
#import "MenuSceneController.h"
@implementation MenuOptionObject
@synthesize bounds, circleBouncePoint;
-(id)initWithQuad:(NSString *)quad
{
self = [super init];
if (self != nil)
{
self.mesh = [[MaterialController sharedController] quadFromAtlasKey:quad];
}
return self;
}
// called once when the object is first created.
-(void)awake
{
self.scale = BBPointMake(28.0, 28.0, 1.0);
self.sceneController = (SceneController *)[MenuSceneController sharedController];
}
-(void)update
{
[super update];
//[self sideCollisionUpdates];
//[self circleCollisionUpdates];
}
-(void)dealloc
{
[sceneController release];
[super dealloc];
}
@end
Im using OpenGL for an app that im trying to make. I've been learning from the apress book Beggining iPhone Games Development.
The problem I have is that a texturedQuad which is a subclass of my mesh class doesn't seem to be rendering properly. (Although it works in the simulator.) The quad renders as just a plain colors that I have set in the texturedQuad class and doesn't seem to be rendering the texture.
This is in a class that is called MenuOptionObject.m which is the actual object that I'm trying to render which I feel is similar to the spaceShip.m file used in the examples. That file did work so I dont get why this wont when I'm using virtually the same 'engine' if you could call it that.
I have a feeling I'm missing something blatent. The examples I worked on worked. I also have a class called texturedButton that does work and also uses the texturedQuad.
Heres the mesh.m code:
#import "Mesh.h"
#import "MaterialController.h"
#import "TexturedQuad.h"
@implementation Mesh
@synthesize vertexCount,vertexSize,colorSize,renderStyle,vertexes,colors;
- (id)initWithVertexes:(CGFloat*)verts
vertexCount:(NSInteger)vertCount
vertexSize:(NSInteger)vertSize
renderStyle:(GLenum)style;
{
self = [super init];
if (self != nil)
{
self.vertexes = verts;
self.vertexCount = vertCount;
self.vertexSize = vertSize;
self.renderStyle = style;
}
return self;
}
// called once every frame
-(void)render
{
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);
// load arrays into the engine
glVertexPointer(vertexSize, GL_FLOAT, 0, vertexes);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(colorSize, GL_FLOAT, 0, colors);
glEnableClientState(GL_COLOR_ARRAY);
//render
glDrawArrays(renderStyle, 0, vertexCount);
}
+(CGRect)meshBounds:(Mesh*)mesh scale:(BBPoint)scale
{
if (mesh == nil) return CGRectZero;
// need to run through my vertexes and find my extremes
if (mesh.vertexCount < 2) return CGRectZero;
CGFloat xMin,yMin,xMax,yMax;
xMin = xMax = mesh.vertexes[0];
yMin = yMax = mesh.vertexes[1];
NSInteger index;
for (index = 0; index < mesh.vertexCount; index++) {
NSInteger position = index * mesh.vertexSize;
if (xMin > mesh.vertexes[position] * scale.x) xMin = mesh.vertexes[position] * scale.x;
if (xMax < mesh.vertexes[position] * scale.x) xMax = mesh.vertexes[position] * scale.x;
if (yMin > mesh.vertexes[position + 1] * scale.y) yMin = mesh.vertexes[position + 1] * scale.y;
if (yMax < mesh.vertexes[position + 1] * scale.y) yMax = mesh.vertexes[position + 1] * scale.y;
}
CGRect meshBounds = CGRectMake(xMin, yMin, xMax - xMin, yMax - yMin);
if (CGRectGetWidth(meshBounds) < 1.0) meshBounds.size.width = 1.0;
if (CGRectGetHeight(meshBounds) < 1.0) meshBounds.size.height = 1.0;
return meshBounds;
}
- (void) dealloc
{
[super dealloc];
}
@end
Heres the texturedQuad.m code:
#import "TexturedQuad.h"
static CGFloat TexturedQuadVertexes[8] =
{
-0.5,-0.5, 0.5,-0.5,
-0.5,0.5, 0.5,0.5
};
static CGFloat TexturedQuadColorValues[16] =
{
1.0,1.0,1.0,1.0,
1.0,1.0,1.0,1.0,
1.0,1.0,1.0,1.0,
1.0,1.0,1.0,1.0
};
@implementation TexturedQuad
@synthesize uvCoordinates,materialKey;
- (id) init
{
self = [super initWithVertexes:TexturedQuadVertexes vertexCount:4 vertexSize:2 renderStyle:GL_TRIANGLE_STRIP];
if (self != nil) {
// 4 vertexes
uvCoordinates = (CGFloat *) malloc(8 * sizeof(CGFloat));
colors = TexturedQuadColorValues;
colorSize = 4;
}
return self;
}
// called once every frame
-(void)render
{
glVertexPointer(vertexSize, GL_FLOAT, 0, vertexes);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(colorSize, GL_FLOAT, 0, colors);
glEnableClientState(GL_COLOR_ARRAY);
if (materialKey != nil) {
[[MaterialController sharedController] bindMaterial:materialKey];
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, uvCoordinates);
}
//render
glDrawArrays(renderStyle, 0, vertexCount);
}
- (void) dealloc
{
free(uvCoordinates);
[super dealloc];
}
@end
And lastly for the MenuOptionObject.m:
#import "MenuOptionObject.h"
#import "MaterialController.h"
#import "MenuSceneController.h"
@implementation MenuOptionObject
@synthesize bounds, circleBouncePoint;
-(id)initWithQuad:(NSString *)quad
{
self = [super init];
if (self != nil)
{
self.mesh = [[MaterialController sharedController] quadFromAtlasKey:quad];
}
return self;
}
// called once when the object is first created.
-(void)awake
{
self.scale = BBPointMake(28.0, 28.0, 1.0);
self.sceneController = (SceneController *)[MenuSceneController sharedController];
}
-(void)update
{
[super update];
//[self sideCollisionUpdates];
//[self circleCollisionUpdates];
}
-(void)dealloc
{
[sceneController release];
[super dealloc];
}
@end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您是否记得在渲染纹理几何体之前调用
glEnable(GL_TEXTURE_2D)
?Did you remember calling
glEnable(GL_TEXTURE_2D)
before rendering the textured geometry?答案是,尽管我的纹理在侧面的文件管理器和代码中都被称为 menuAtlas,但它不起作用,因此将两者更改为 mA 有效。我不明白为什么,但我怀疑这与缓存有关。
Answer turned out to be the even though my texture was called menuAtlas both in the file manager at the side and in the code it wouldn't work so changing both to mA worked. I don't understand why but I have a suspicion that it involves something to do with caching.