本文介绍了如何使用OpenGL将3D效果赋予UIImageView/uiview看起来像是3D CUBE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 OpenGL 的新手,对它了解不多.我想向UIImageView添加 3D效果.如何使用OpenGL实现此目的?我想做类似此图中所示的操作:

I am new to OpenGL and don't much have knowledge in it. I want to add a 3D effect to a UIImageView . How can I achieve this using OpenGL? I want to do something like seen in this image:

我搜索并发现可以使用OpenGL.我已经使用OpenGL引用了此链接.我创建了一个多维数据集,并对

I have searched and found that it is possible using OpenGL. I have referred to this link With OpenGL . I have created a cube, and got some effect with

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

但是我通过 glDrawRangeElements 知道了制作一个3D立方体,但是我不知道如何实现相同的功能.

But I come to know with glDrawRangeElements we can make a 3d cube, But I do not have idea how to implement the same.

编辑

这是我的代码,显示文本和索引数组

Here is my code showing ther vertext and indices array

const Vertex Vertices [] = {

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索引[] = {

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做一些更好的工作,那就还可以.

So please suggest me . If it is possible to do some better work with Core Graphics , then also fine.

请帮助我获得解决方案.提前致谢!

Please help me to get the solution.Thanks in Advance!

推荐答案

忘记UIImage/etc.如果要使用OpenGL在3D中渲染多维数据集,则必须使用OpenGL纹理对其进行纹理映射.这是OpenGL中所有非常基本的东西.网络上肯定有很多关于1.纹理贴图和2.绘制立方体的教程.

Forget about UIImage/etc. If you are rendering a cube in 3D with OpenGL, you must texture-map it using an OpenGL texture. This is all pretty basic stuff in OpenGL; there must be like a ton of tutorials on the web about 1. Texture mapping and 2. Drawing a Cube.

确保搜索"OpenGL ES 1.1","OpenGL ES 2.0"或"GLKit"

Make sure to search for "OpenGL ES 1.1", "OpenGL ES 2.0", OR "GLKit"

编辑试试这个: http://www.raywenderlich.com/4404/opengl-es-2-0-for-iphone-tutorial-part-2-textures

编辑2

好的,一些源代码.首先,我使用这种顶点数据格式:

OK, some source code.First, I use this vertex data format:

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;

接下来,这是一个立方体的顶点数据

Next, this is the vertex data for one cube

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模型矩阵(请参见下面的着色器程序设置)来平移/缩放/旋转立方体.数据格式是浮点数的C数组.如何设置它,不在这里讨论的范围,您可以在Internet上搜索它.

Cube size is 1x1x1. You must provide a 4x4 Model matrix (see shader program setup below) to translate/scale/rotate your cube. The data format is a C array of floats. How to set it up, is beyond the scope here and you can search it in the internet.

纹理坐标假定您使用的是这样的纹理:(每个正方形都是一个面)

Texture coordinates assume you are using a texture like this: (each square is a face)

...这是索引数据:

...and this is the Index Data:

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"表示逆时针)

('CW' denotes a Clockwise triangle in the triangle strip. 'CCW' denotes Counter-clockwise)

这是我生成OpenGL缓冲区的方式:

This is how I generate the OpenGL buffers:

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参数:(材质,照明等)

These are the OpenGL parameters: (material, lighting, etc.)

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的句柄:

You get the handles to each attribute/unifoerm in the shader ONCE on setup, with this code:

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"结尾的变量都是GLints);

(All variables that end in 'InProgram' are GLints);

最后是顶点着色器:

// 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着色器:

...And the FRAGMENT shader:

varying lowp    vec4 DestinationColor;
varying mediump vec2 TextureCoordOut;

uniform sampler2D Sampler;

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

请注意,这里有很多可能的复杂性,OpenGL并不是一个琐碎的主题,该代码可能无法正常工作,但我相信这是一个很好的开始指向您想要实现的目标.我强烈建议您学习这些知识,因为如果您仅复制/粘贴其他人的代码,那么会有很多小事情会出错.

Please note that there are lots of possible intricacies here, OpenGL is not a trivial subject, this code may not work as is, but I believe it's a good starting point for what you want to achieve. I seriously recommend you learn this stuff, because there is a ton of little things that can go wrong if you only copy/paste somebody else's code.

这篇关于如何使用OpenGL将3D效果赋予UIImageView/uiview看起来像是3D CUBE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 22:21