为什么我的 OpenGL ES 纹理无法正确渲染?

发布于 2024-11-13 22:25:32 字数 4733 浏览 2 评论 0原文

我正在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

从来不烧饼 2024-11-20 22:25:32

您是否记得在渲染纹理几何体之前调用 glEnable(GL_TEXTURE_2D)

Did you remember calling glEnable(GL_TEXTURE_2D) before rendering the textured geometry?

离笑几人歌 2024-11-20 22:25:32

答案是,尽管我的纹理在侧面的文件管理器和代码中都被称为 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文