1

私はOpenGLを初めて使用し、知識があまりありません。に3D効果を追加したいUIImageView。OpenGLを使用してこれを達成するにはどうすればよいですか?この画像に見られるようなことをしたい:ここに画像の説明を入力してください

私は検索し、OpenGLを使用してそれが可能であることを発見しました。私はOpenGLでこのリンクを参照しました。私は立方体を作成しました、そしていくつかの効果を得ました

glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0);

しかし、glDrawRangeElementsを使用すると、3Dキューブを作成できることがわかりましたが、同じものを実装する方法がわかりません。

編集

これが頂点とインデックスの配列を示す私のコードです

const Vertex Vertices [] = {

// Front
{{1, -1, 1}, {1, 0, 0, 1}, {1, 0}},
{{1, 1, 1}, {0, 1, 0, 1}, {1, 1}},
{{-1, 1, 1}, {0, 0, 1, 1}, {0, 1}},
{{-1, -1, 1}, {0, 0, 0, 1}, {0, 0}},

// Back
{{1, 1, -1}, {1, 0, 0, 1}, {0, 1}},
{{-1, -1, -1}, {0, 1, 0, 1}, {1, 0}},
{{1, -1, -1}, {0, 0, 1, 1}, {0, 0}},
{{-1, 1, -1}, {0, 0, 0, 1}, {1, 1}},

// Left
{{-1, -1, 1}, {1, 0, 0, 1}, {1, 0}}, 
{{-1, 1, 1}, {0, 1, 0, 1}, {1, 1}},
{{-1, 1, -1}, {0, 0, 1, 1}, {0, 1}},
{{-1, -1, -1}, {0, 0, 0, 1}, {0, 0}},

// Right
{{1, -1, -1}, {1, 0, 0, 1}, {1, 0}},
{{1, 1, -1}, {0, 1, 0, 1}, {1, 1}},
{{1, 1, 1}, {0, 0, 1, 1}, {0, 1}},
{{1, -1, 1}, {0, 0, 0, 1}, {0, 0}},

// Top
{{1, 1, 1}, {1, 0, 0, 1}, {1, 0}},
{{1, 1, -1}, {0, 1, 0, 1}, {1, 1}},
{{-1, 1, -1}, {0, 0, 1, 1}, {0, 1}},
{{-1, 1, 1}, {0, 0, 0, 1}, {0, 0}},

// Bottom
{{1, -1, -1}, {1, 0, 0, 1}, {1, 0}},
{{1, -1, 1}, {0, 1, 0, 1}, {1, 1}},
{{-1, -1, 1}, {0, 0, 1, 1}, {0, 1}}, 
{{-1, -1, -1}, {0, 0, 0, 1}, {0, 0}}

};

const GLubyte Indices [] = {

// Front
0, 1, 2,
2, 3, 0,

// Back
4, 6, 5,
4, 5, 7,

// Left
8, 9, 10,
10, 11, 8,

// Right
12, 13, 14,
14, 15, 12,

// Top
16, 17, 18,
18, 19, 16,

// Bottom
20, 21, 22,
22, 23, 20

};

だから私に提案してください。Core Graphicsでより良い作業を行うことが可能であれば、それでも問題ありません。

解決策を得るのを手伝ってください。前もって感謝します!

4

1 に答える 1

6

UIImage/etcを忘れてください。OpenGLを使用して立方体を3Dでレンダリングする場合は、OpenGLテクスチャを使用して立方体をテクスチャマッピングする必要があります。これはすべてOpenGLのかなり基本的なものです。1.テクスチャマッピングと2.キューブの描画についてのチュートリアルがWeb上にたくさんあるはずです。

必ず「OpenGLES1.1」、「OpenGL ES 2.0」、または「GLKit」を検索してください

編集 これを試してください:http ://www.raywenderlich.com/4404/opengl-es-2-0-for-iphone-tutorial-part-2-textures

編集2

OK、いくつかのソースコード。まず、次の頂点データ形式を使用します。

typedef struct tTextureCoords
{
    GLfloat s;
    GLfloat t;

}TextureCoords;

// 3D Float Vector for Position and Normals
typedef struct tVertex3D
{
    GLfloat x;
    GLfloat y;
    GLfloat z;

}Vertex3D;


// 4D Byte Vector for Colors 
typedef struct tColor4
{
    GLubyte r;      // [0...255]
    GLubyte g;      // [0...255]
    GLubyte b;      // [0...255]
    GLubyte a;      // [0...255]

}Color4;


// Vertex Data for 3D Objects
typedef struct tVertexData3D
{
    Vertex3D        position;
    Vertex3D        normal;
    TextureCoords   texCoords;
    Color4          color;

}VertexData3D;

次に、これは1つのキューブの頂点データです

static GLuint vertexBuffer = 0;
static GLuint indexBuffer  = 0;

static VertexData3D vertexArray[24] = 
{
    // .........................................................................
    // < LEFT > face (-X)

    {   
        // Vertex 0
        { -0.5f, +0.5f, -0.5f },            // Position
        { -1.0f,  0.0f,  0.0f },            // Normal   (-X)
        {   0.5f/512.0f,   0.5f/512.0f },   // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 1
        { -0.5f, -0.5f, -0.5f },            // Position
        { -1.0f,  0.0f,  0.0f },            // Normal   (-X)
        {   0.5f/512.0f, 127.5f/512.0f },   // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 2
        { -0.5f, +0.5f, +0.5f },            // Position
        { -1.0f,  0.0f,  0.0f },            // Normal   (-X)
        { 127.5f/512.0f,   0.5f/512.0f },   // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 3
        { -0.5f, -0.5f, +0.5f },            // Position
        { -1.0f,  0.0f,  0.0f },            // Normal   (-X)
        { 127.5f/512.0f, 127.5f/512.0f },   // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },


    // .........................................................................
    // < RIGHT > face (+X)

    {   
        // Vertex 4
        { +0.5f, +0.5f, +0.5f },            // Position
        { +1.0f,  0.0f,  0.0f },            // Normal   (+X)
        { 128.5f/512.0f, 0.5f/512.0f },     // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 5
        { +0.5f, -0.5f, +0.5f },            // Position
        { +1.0f,  0.0f,  0.0f },            // Normal   (+X)
        {  128.5f/512.0f, 127.5f/512.0f },  // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 6
        { +0.5f, +0.5f, -0.5f },            // Position
        { +1.0f,  0.0f,  0.0f },            // Normal   (+X)
        {  255.5f/512.0f,   0.5f/512.0f },  // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 7
        { +0.5f, -0.5f, -0.5f },            // Position
        { +1.0f,  0.0f,  0.0f },            // Normal   (+X)
        {  255.5f/512.0f, 127.5f/512.0f },  // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },


    // .........................................................................
    // < BOTTOM > face (-Y)

    {   
        // Vertex 8
        { -0.5f, -0.5f, +0.5f },            // Position
        {  0.0f, -1.0f,  0.0f },            // Normal   (-Y)
        {   0.5f/512.0f, 128.5f/512.0f },     // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 9
        { -0.5f, -0.5f, -0.5f },            // Position
        {  0.0f, -1.0f,  0.0f },            // Normal   (-Y)
        {   0.5f/512.0f, 255.5f/512.0f },     // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 10
        { +0.5f, -0.5f, +0.5f },            // Position
        {  0.0f, -1.0f,  0.0f },            // Normal   (-Y)
        {   127.5f/512.0f, 128.5f/512.0f },     // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 11
        { +0.5f, -0.5f, -0.5f },            // Position
        {  0.0f, -1.0f,  0.0f },            // Normal   (-Y)
        {   127.5f/512.0f, 255.5f/512.0f },     // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },


    // .........................................................................
    // < TOP > face (+Y)

    {   
        // Vertex 12
        { -0.5f, +0.5f, -0.5f },            // Position
        {  0.0f, +1.0f,  0.0f },            // Normal   (+Y)
        { 128.5f/512.0f, 128.5f/512.0f },   // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 13
        { -0.5f, +0.5f, +0.5f },            // Position
        {  0.0f, +1.0f,  0.0f },            // Normal   (+Y)
        { 128.5f/512.0f, 255.5f/512.0f },   // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 14
        { +0.5f, +0.5f, -0.5f },            // Position
        {  0.0f, +1.0f,  0.0f },            // Normal   (+Y)
        { 255.5f/512.0f, 128.5f/512.0f },   // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 15
        { +0.5f, +0.5f, +0.5f },            // Position
        {  0.0f, +1.0f,  0.0f },            // Normal   (-Y)
        { 255.5f/512.0f, 255.5f/512.0f },     // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    // .........................................................................
    // < BACK > face (-Z)

    {   
        // Vertex 16
        { -0.5f, -0.5f, -0.5f },            // Position
        {  0.0f,  0.0f, -1.0f },            // Normal   (-Z)
        { 127.5f/512.0f, 383.5f/512.0f },   // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 17
        { -0.5f, +0.5f, -0.5f },            // Position
        {  0.0f,  0.0f, -1.0f },            // Normal   (-Z)
        { 127.5f/512.0f, 256.5f/512.0f },   // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 18
        { +0.5f, -0.5f, -0.5f },            // Position
        {  0.0f,  0.0f, -1.0f },            // Normal   (-Z)
        {   0.5f/512.0f, 383.5f/512.0f },   // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 19
        { +0.5f, +0.5f, -0.5f },            // Position
        {  0.0f,  0.0f, -1.0f },            // Normal   (-Z)
        {   0.5f/512.0f, 256.5f/512.0f },   // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    // .........................................................................
    // < FRONT > face (+Z)

    {   
        // Vertex 20
        { -0.5f, +0.5f, +0.5f },            // Position
        {  0.0f,  0.0f, +1.0f },            // Normal   (+Z)
        { 128.5f/512.0f, 256.5f/512.0f },   // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 21
        { -0.5f, -0.5f, +0.5f },            // Position
        {  0.0f,  0.0f, +1.0f },            // Normal   (+Z)
        { 128.5f/512.0f, 383.5f/512.0f },   // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 22
        { +0.5f, +0.5f, +0.5f },            // Position
        {  0.0f,  0.0f, +1.0f },            // Normal   (+Z)
        { 255.5f/512.0f, 256.5f/512.0f },   // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    },

    {   
        // Vertex 23
        { +0.5f, -0.5f, +0.5f },            // Position
        {  0.0f,  0.0f, +1.0f },            // Normal   (+Z)
        { 255.5f/512.0f, 383.5f/512.0f },   // Texture
        { 0xFF, 0xFF, 0xFF, 0xFF}           // Color
    }
};

キューブサイズは1x1x1です。キューブを変換/スケーリング/回転するには、4x4モデルマトリックス(以下のシェーダープログラムのセットアップを参照)を提供する必要があります。データ形式は、floatのC配列です。設定方法はここでは範囲を超えており、インターネットで検索できます。

テクスチャ座標は、次のようなテクスチャを使用していることを前提としています:(各正方形は顔です)

ここに画像の説明を入力してください

...そしてこれはインデックスデータです:

static GLushort indexArray[] = 
{
    // Triangle Strip...

    12,             // ...
    13,             // ...
    14,             // Top Face                     // CCW
    15,             // Top Face                     // CW

    22,             // Degenerate   (14, 15, 22)    // (CCW)
    20,             // Degenarate   (15, 22, 20)    // (CW)
    23,             // Front Face   (22, 20, 23)    // CCW
    21,             // Front Face   (20, 23, 21)    // CW

     3,             // Degenerate   (20, 21,  3)    // (CCW)
    2,              // Degenerate   (21,  3,  2)    // (CW)
    1,              // Left Face    ( 3,  2,  1)    // CCW
    0,              // Left Face    ( 2,  1,  0)    // CW

    16,             // Degenerate   ( 1,  0, 16)    // (CCW)
    17,             // Degenerate   ( 0, 16, 17)    // (CW)
    18,             // Back Face    (16, 17, 18)    // CCW
    19,             // Back Face    (17, 18, 19)    // CW

     6,             // Degenerate   (18, 19,  6)    // (CCW)
    4,              // Degenerate   (19,  6,  4)    // (CW)
    7,              // Right Face   ( 6,  4,  7)    // CCW
    5,              // Right Face   ( 4,  7,  5)    // CW

    10,             // Degenerate   ( 7,  5, 10)    // (CCW)
    8,              // Degenerate   ( 5, 10,  8)    // (CW)
    11,             // Bottom Face  (10,  8, 11)    // CCW
    9               // Bottom Face  ( 8, 11,  9)    // CW
};

(「CW」は三角ストリップの時計回りの三角形を示します。「CCW」は反時計回りを示します)

これが私がOpenGLバッファを生成する方法です:

glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);            
glBufferData(GL_ARRAY_BUFFER, 24*sizeof(VertexData3D), &vertexArray[0], GL_STATIC_DRAW);    
glBindBuffer(GL_ARRAY_BUFFER, 0);

glGenBuffers(1, &indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 24*sizeof(GLushort), &indexArray[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

これらはOpenGLパラメータです:(マテリアル、照明など)

static GLfloat lightPosition[4]        = { LIGHT_X_POS, LIGHT_Y_POS, LIGHT_Z_POS, 1.0f };
static GLfloat cubeAmbientMaterial[4]  = { 0.30f, 0.30f, 0.30f, 1.00f };    
static GLfloat cubeDiffuseMaterial[4]  = { 0.650f, 0.650f, 0.650f, 1.00f };
static GLfloat cubeSpecularMaterial[4] = { 1.0f, 1.0f, 1.0f, 1.0f};
static GLfloat cubeShininess           = 1500.0f;

//Lighting is calculated in MODEL Coordinates:
//Eye and Light Source are located high up along the Z Axis
static GLfloat eyePosition[3]      = { 0.0f,  0.0f, CAMERA_Z_POS };

そしてこれはドローコールです:

// VBO Offsets
static GLsizei stride         = (GLsizei)(sizeof(VertexData3D));
static GLvoid* positionOffset = (GLvoid*)(0);
static GLvoid* normalOffset   = (GLvoid*)(sizeof(Vertex3D));
static GLvoid* textureOffset  = (GLvoid*)(2*sizeof(Vertex3D));

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);

glBindTexture(GL_TEXTURE_2D, yourTextureID); // Bind your texture

glUseProgram(yourProgram);
// Setup program (Shaders)
glUniformMatrix4fv(viewLocationInProgram, 1, 0, viewMatrix); // Upload the 4x4 view matrix

glUniform3fv(lightPositionLocationInProgram,     1, lightPosition   );
glUniform3fv(eyePositionLocationInProgram,       1, eyePosition     );
glUniform3fv(ambientMaterialLocationInProgram,      1, cubeAmbientMaterial );
glUniform3fv(specularMaterialLocationInProgram,     1, cubeSpecularMaterial);
glUniform3fv(diffuseMaterialLocationInProgram,      1, cubeDiffuseMaterial );
glUniform1f(shininessLocationInProgram,     cubeShininess       );

glVertexAttribPointer(positionLocationInProgram, 3, GL_FLOAT, GL_FALSE, stride, positionOffset);
glVertexAttribPointer(normalLocationInProgram,   3, GL_FLOAT, GL_FALSE, stride, normalOffset);
glVertexAttribPointer(texCoordLocationInProgram, 2, GL_FLOAT, GL_FALSE, stride, textureOffset);

glEnableVertexAttribArray(positionLocationInProgram);   
glEnableVertexAttribArray(normalLocationInProgram);     
glEnableVertexAttribArray(texCoordLocationInProgram);

glUniformMatrix4fv(modelLocationInProgram,  1, 0, modelMatrix);
glUniformMatrix3fv(normalMatrixLocationInProgram, 1, 0, normalMatrix);
glDrawElements(GL_TRIANGLE_STRIP, 48, GL_UNSIGNED_SHORT, 0);

glDrawElements(GL_TRIANGLE_STRIP, 48, GL_UNSIGNED_SHORT, 0);

glDisableVertexAttribArray(positionLocationInProgram);
glDisableVertexAttribArray(normalLocationInProgram);
glDisableVertexAttribArray(texCoordLocationInProgram);

次のコードを使用して、セットアップ時にシェーダーの各属性/unifoermへのハンドルを1回取得します。

positionLocationInProgram = glGetAttribLocation(yourProgram, "Position");
normalLocationInProgram = glGetAttribLocation(yourProgram, "Normal");
texCoordLocationInProgram = glGetAttribLocation(yourProgram, "TextureCoord");
modelLocation = glGetUniformLocation(yourProgram, "Model");
viewLocationInProgram = glGetUniformLocation(yourProgram, "View");
normalMatrixLocationInProgram = glGetUniformLocation(yourProgram, "NormalMatrix");
lightPositionLocationInProgram = glGetUniformLocation(yourProgram, "LightPosition");
eyePositionLocationInProgram = glGetUniformLocation(yourProgram, "EyePosition");
ambientMaterialLocationInProgram = glGetUniformLocation(yourProgram, "AmbientMaterial");
diffuseMaterialLocationInProgram = glGetUniformLocation(yourProgram, "DiffuseMaterial"); 
specularMaterialLocationInProgram = glGetUniformLocation(yourProgram, "SpecularMaterial");
shininessLocationInProgram = glGetUniformLocation(yourProgram, "Shininess");
samplerLocationInProgram = glGetUniformLocation(yourProgram, "Sampler");

glUseProgram(yourProgram);
glUniform1i(samplerLocationInProgram, 0);

(「InProgram」で終わるすべての変数はGLintです);

そして最後に、頂点シェーダー:

// These change per-vertex
attribute vec4 Position;
attribute vec3 Normal;
attribute vec2 TextureCoord;

// These change once in a while (e.g., per object)
uniform mat4  Projection;
uniform mat4  Model;
uniform mat4  View;
uniform mat3  NormalMatrix;
uniform vec3  LightPosition;
uniform vec3  EyePosition;
uniform vec3  DiffuseMaterial;
uniform vec3  AmbientMaterial;
uniform vec3  SpecularMaterial;
uniform float Shininess;

// Thes go to the fragment shader (OUTPUT)
varying vec4 DestinationColor;
varying vec2 TextureCoordOut;

void main (void)
{       
    vec4 P = ( Projection * View * Model ) * Position;

    // Position in Model Coordinates
    vec3 P2 = vec3( Model * Position );

    vec3 N = normalize(NormalMatrix*Normal);
    vec3 L = normalize(LightPosition - P2);
    vec3 E = normalize(EyePosition   - P2);

    vec3 H = normalize(L + E);

    float df = max(0.0, dot(N, L));
    float sf = max(0.0, dot(N, H));


    sf = pow(sf, Shininess);

    vec3 color = AmbientMaterial + (df *  DiffuseMaterial) + (sf * SpecularMaterial);

    DestinationColor = vec4(color, 1);

    TextureCoordOut = TextureCoord;

    gl_Position = P;    
}

...そしてFRAGMENTシェーダー:

varying lowp    vec4 DestinationColor;
varying mediump vec2 TextureCoordOut;

uniform sampler2D Sampler;

void main (void)
{
    gl_FragColor = (texture2D(Sampler, TextureCoordOut ) * DestinationColor);
}

ここには多くの複雑な可能性があることに注意してください。OpenGLは些細なことではありません。このコードはそのままでは機能しない可能性がありますが、達成したいことの良い出発点になると思います。他の人のコードをコピーして貼り付けるだけではうまくいかないことがたくさんあるので、私はあなたがこのことを学ぶことを真剣に勧めます。

于 2012-07-07T13:18:47.257 に答える