Opengl es 如何使用OpenGL ES for iPhone development渲染3D对象(其中顶点和法线存储在头文件中)?

Opengl es 如何使用OpenGL ES for iPhone development渲染3D对象(其中顶点和法线存储在头文件中)?,opengl-es,3d,rendering,blender,Opengl Es,3d,Rendering,Blender,我使用blender创建了一个简单的3D立方体对象,并使用Jeff Lamarche的blender导出将其存储在头文件中,然后将其添加到我的项目中。然而,我有困难渲染它 头文件: //If not using MC3D, change 1 to 0 to add needed types #if 0 #import "MC3DTypes.h" #else struct texCoord { GLfloat u; GLfloat

我使用blender创建了一个简单的3D立方体对象,并使用Jeff Lamarche的blender导出将其存储在头文件中,然后将其添加到我的项目中。然而,我有困难渲染它

头文件:

//If not using MC3D, change 1 to 0 to add needed types
#if 0
    #import "MC3DTypes.h"
#else
    struct texCoord
    {
        GLfloat     u;
        GLfloat     v;
    };
    typedef struct texCoord texCoord;
    typedef texCoord* texCoordPtr;

    typedef struct vec2 vec2;
    typedef vec2* vec2Ptr;

    struct vec3
    {
        GLfloat x;
        GLfloat y;
        GLfloat z;
    };

    typedef struct vec3 vec3;
    typedef vec3* vec3Ptr;

    struct vec4
    {
        GLfloat x;
        GLfloat y;
        GLfloat z;
        GLfloat w;
        };

    typedef struct vec4 vec4;
    typedef vec4* vec4Ptr;

#endif

struct vertexData
{
    vec3        vertex;
    vec3        normal;
};
typedef struct vertexData vertexData;
typedef vertexData* vertexDataPtr;


static const vertexData MeshVertexData[] = {
    {/*v:*/{1.000000, -1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, -0.577349} },
    {/*v:*/{1.000000, -1.000000, 1.000000}, /*n:*/{0.577349, -0.577349, -0.577349} },
    {/*v:*/{-1.000000, -1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, -0.577349} },
    {/*v:*/{1.000000, 1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, 0.577349} },
    {/*v:*/{-1.000000, 1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, 0.577349} },
    {/*v:*/{0.999999, 1.000000, 1.000001}, /*n:*/{0.577349, -0.577349, 0.577349} },
    {/*v:*/{1.000000, -1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, -0.577349} },
    {/*v:*/{1.000000, 1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, 0.577349} },
    {/*v:*/{1.000000, -1.000000, 1.000000}, /*n:*/{0.577349, -0.577349, -0.577349} },
    {/*v:*/{1.000000, -1.000000, 1.000000}, /*n:*/{0.577349, -0.577349, -0.577349} },
    {/*v:*/{0.999999, 1.000000, 1.000001}, /*n:*/{0.577349, -0.577349, 0.577349} },
    {/*v:*/{-1.000000, -1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, -0.577349} },
    {/*v:*/{-1.000000, -1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, -0.577349} },
    {/*v:*/{-1.000000, 1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, 0.577349} },
    {/*v:*/{-1.000000, 1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, 0.577349} },
    {/*v:*/{1.000000, 1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, 0.577349} },
    {/*v:*/{1.000000, -1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, -0.577349} },
    {/*v:*/{-1.000000, 1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, 0.577349} },
    {/*v:*/{-1.000000, -1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, -0.577349} },
    {/*v:*/{1.000000, -1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, -0.577349} },
    {/*v:*/{-1.000000, -1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, -0.577349} },
    {/*v:*/{1.000000, 1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, 0.577349} },
    {/*v:*/{0.999999, 1.000000, 1.000001}, /*n:*/{0.577349, -0.577349, 0.577349} },
    {/*v:*/{1.000000, -1.000000, 1.000000}, /*n:*/{0.577349, -0.577349, -0.577349} },
    {/*v:*/{1.000000, -1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, -0.577349} },
    {/*v:*/{-1.000000, -1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, -0.577349} },
    {/*v:*/{-1.000000, 1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, 0.577349} },
    {/*v:*/{-1.000000, 1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, 0.577349} },
    {/*v:*/{-1.000000, 1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, 0.577349} },
    {/*v:*/{0.999999, 1.000000, 1.000001}, /*n:*/{0.577349, -0.577349, 0.577349} },
    {/*v:*/{-1.000000, -1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, -0.577349} },
    {/*v:*/{-1.000000, -1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, -0.577349} },
    {/*v:*/{-1.000000, 1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, 0.577349} },
    {/*v:*/{0.999999, 1.000000, 1.000001}, /*n:*/{0.577349, -0.577349, 0.577349} },
    {/*v:*/{-1.000000, 1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, 0.577349} },
    {/*v:*/{-1.000000, -1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, -0.577349} },
};

// Example OpenGL ES 1.1 Drawing Code:
// glEnableClientState(GL_VERTEX_ARRAY);
// glEnableClientState(GL_NORMAL_ARRAY);
// glVertexPointer(3, GL_FLOAT, sizeof(VertexData3D), &MeshVertexData[0].vertex);
// glNormalPointer(GL_FLOAT, sizeof(VertexData3D), &MeshVertexData[0].normal);
// glDrawArrays(GL_TRIANGLES, 0, kMeshNumberOfVertices);
// glDisableClientState(GL_VERTEX_ARRAY);
// glDisableClientState(GL_NORMAL_ARRAY);
下面是我正在使用的代码:

//
//  ES1Renderer.m
//  glTestingGround
//
//  Created by David Jacobs on 3/8/10.
//  Copyright Stanford University 2010. All rights reserved.
//

#import "ES1Renderer.h"
#import "banana.h"
#import "PVRTexture.h"
#import "cubefr.h"

#define BUFFER_OFFSET(x)((char *)NULL+(x))

@implementation ES1Renderer




// Create an ES 1.1 context
- (id) init
{
    if (self = [super init])
    {
        context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];

        if (!context || ![EAGLContext setCurrentContext:context])
        {
            [self release];
            return nil;
        }

        // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
        glGenFramebuffersOES(1, &defaultFramebuffer);
        glGenRenderbuffersOES(1, &colorRenderbuffer);
        glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
        glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
        glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);

        glEnable(GL_CULL_FACE);
        glEnable(GL_CCW);


        // ###################### Texture Demo #################################
        /*NSString * path = [[NSBundle mainBundle] pathForResource: @"banana" ofType:@"pvrtc"];
        texture = [[PVRTexture alloc] initWithContentsOfFile:path];

        glBindTexture(GL_TEXTURE_2D, texture.name);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/
        // #####################################################################
    }

    return self;
}



- (void) render
{
    // Replace the implementation of this method to do your own custom drawing


    // This application only creates a single context which is already set current at this point.
    // This call is redundant, but needed if dealing with multiple contexts.
    [EAGLContext setCurrentContext:context];    
    // This application only creates a single default framebuffer which is already bound at this point.
    // This call is redundant, but needed if dealing with multiple framebuffers.
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);

        //obj2opengl.pl banana.obj
    //To include the converted object all you have to do is

        // include generated arrays

    // ---------------------------------------------------------------
    // Determines the Normalized Device Coordinate -> Window Coordinate Transform
    // ---------------------------------------------------------------

    glViewport(0, 0, backingWidth, backingHeight);    

    // ---------------------------------------------------------------
    // Determines the Eye Coordinate -> Clip Coordinate Transform
    // ---------------------------------------------------------------

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();   
    glFrustumf(-2, 2, -3, 3, 5, 20);



    // ---------------------------------------------------------------
    // Determines the Object Coordinate -> Eye Coordinate Transform
    // ---------------------------------------------------------------
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity();

    glTranslatef(0, 0, -8);

    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // ####################### Geometry Demo #########################
/*
#define TETRA_FRONT   0.0,    0.0,    1.0
#define TETRA_RIGHT 0.943,    0.0, -0.333
#define TETRA_TOP  -0.471,  0.816, -0.333
#define TETRA_LEFT -0.471, -0.816, -0.333

#define v1 1.000000, -1.000000, -1.000000
#define v2 1.000000, -1.000000, 1.000000
#define v3 -1.000000, -1.000000, 1.000000
#define v4 -1.000000, -1.000000, -1.000000
#define v5 1.000000, 1.000000, -1.000000
#define v6 0.999999, 1.000000, 1.000001
#define v7 -1.000000, 1.000000, 1.000000
#define v8 -1.000000, 1.000000, -1.000000

    static const GLfloat tetraVertices[] = {
        TETRA_TOP,
        TETRA_RIGHT,
        TETRA_LEFT,
        TETRA_FRONT,
        TETRA_TOP,
        TETRA_RIGHT,        
    };
    static const GLfloat newVertices[] = {
        v1,
        v2,
        v3,
        v4,
        v5,
        v6,
        v7,
        v8
    };

#define RED      255,  0,  0,255
#define GREEN      0,255,  0,255
#define BLUE       0,  0,255,255
#define YELLOW   255,255,  0,255

    static const GLubyte tetraColors[] = {
        RED,
        GREEN,
        BLUE,
        YELLOW,
        RED,
        GREEN,      
    };
    static const GLubyte newColors[] = {
        RED,
        RED,
        RED,
        RED,
        RED,
        RED,
        RED,
        RED
    };

    static float t = 0.0;
    t += 1/30.f;
    //glVertexPointer(3, GL_FLOAT, 0, tetraVertices);
    glVertexPointer(3, GL_FLOAT, 0, newVertices);
    glEnableClientState(GL_VERTEX_ARRAY);
    glColorPointer(4, GL_UNSIGNED_BYTE, 0, newColors);
    //glColorPointer(4, GL_UNSIGNED_BYTE,0, tetraColors);
    glEnableClientState(GL_COLOR_ARRAY);



    glPushMatrix();
    glTranslatef(0, 0, -3);
    glRotatef(30*t, 0, 1, 0);
    glScalef(3, 3, 3);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);  
    glPopMatrix();


    glPushMatrix();
    glTranslatef(2, 2, 0);  
    glRotatef(-30*t, 1, 0, 0);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);  
    glPopMatrix();

    glPushMatrix();
    glTranslatef(2, -2, 0); 
    glRotatef(-60*t, 1, 0, 1);
    glScalef(2, 2, 2);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);  
    glPopMatrix();
     */

    //glDisableClientState(GL_VERTEX_ARRAY);
    //glDisableClientState(GL_NORMAL_ARRAY);

    // set input data to arrays
    //glVertexPointer(3, GL_FLOAT, 0, MeshVertexData);
    //glEnableClientState(GL_VERTEX_ARRAY);

    //glNormalPointer(GL_FLOAT, 0,indexes);
    //glEnableClientState(GL_NORMAL_ARRAY);

    //glTexCoordPointer(2, GL_FLOAT, 0, bananaTexCoords);
    //glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    //glEnable(GL_TEXTURE_2D);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glVertexPointer(3, GL_FLOAT, sizeof(MeshVertexData), &MeshVertexData[0].vertex);
    glNormalPointer(GL_FLOAT, sizeof(MeshVertexData), &MeshVertexData[0].normal);
   //glTexCoordPointer(2, GL_FLOAT, sizeof(TexturedVertexData3D), &VertexData[0].texCoord);


    static float t = 0.0;
    t += 1/30.f;

    glPushMatrix();
    glTranslatef(0, 0, 0);
    glRotatef(30*t, 0, 1, 0);
    glScalef(1, 1, 1);
    //glDrawArrays(GL_TRIANGLES, 0, vertex_count);
    glDrawArrays(GL_TRIANGLES, 0, sizeof(&MeshVertexData[0].vertex));
    glPopMatrix();

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glLoadIdentity();
    //glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    //glDisable(GL_TEXTURE_2D);

    // ###############################################################
    // Enable lighting

    // This application only creates a single color renderbuffer which is already bound at this point.
    // This call is redundant, but needed if dealing with multiple renderbuffers.
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer
{   
    // Allocate color buffer backing based on the current layer size
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
    [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:layer];
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);


    if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
    {
        NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
        return NO;
    }

    return YES;
}

- (void) dealloc
{
    // Tear down GL
    if (defaultFramebuffer)
    {
        glDeleteFramebuffersOES(1, &defaultFramebuffer);
        defaultFramebuffer = 0;
    }

    if (colorRenderbuffer)
    {
        glDeleteRenderbuffersOES(1, &colorRenderbuffer);
        colorRenderbuffer = 0;
    }

    // Tear down context
    if ([EAGLContext currentContext] == context)
        [EAGLContext setCurrentContext:nil];

    [context release];
    context = nil;

    [super dealloc];
}

@end
非常感谢您的帮助。此外,任何关于OpenGL ES的教程都会很好。
提前感谢

仅从Blender获取顶点和法线数据是不够的,您还需要投影和模型视图矩阵以及摄影机和灯光位置。更好的方法是导出到包含该文件的文件格式,如Collada或POD(如果希望保持简单)。PowerVR SDK包括从Blender导出的工具,甚至还有一个基本的游戏引擎,可以解析POD。您还可以通过这种方式获得纹理坐标和动画。在这里查看我的第一篇文章:

http://montgomery1.com/opengl/