2

iOSのOpenGLESにテクスチャをロードしようとしています。これが私が取っているアプローチです:

  1. objを解析し、そこからposition、normal、およびtexcoord属性を取得します。
  2. (このテストでは)シェーダーへの位置とtexcoordのみを有効にします。
  3. 任意の512x512pngをrawに変換し、サンプラー0を介してそれをGLにロードします。
  4. 頂点シェーダーでは、texcoordsをフラグメントシェーダーに渡すときに、正規のボリューム/クリップスペースでgl_Positionを返すだけです。
  5. フラグメントシェーダーで、texture2dからのルックアップをgl_FragColorに割り当てます。

テクスチャファイル:t1.png: ここに画像の説明を入力してください

レンダリング結果:

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

明らかに、キューブにマッピングされたテクスチャはありません。ご覧のとおり、texture2D()の原因からいくつかの値を取得していますが、シェーダーで照明や色が渡されたり処理されたりすることはありません...私の推測では、変換していると思う方法をどういうわけか混乱させていますpngをrawバッファに変換して、テクスチャメモリに渡します。

これはobjファイルです。テストキューブ:

# Blender v2.63 (sub 0) OBJ File: ''
# www.blender.org
mtllib cube2.mtl
o Cube
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -0.999999
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 1.000000 0.000000 0.000000
vn -0.000000 -0.000000 1.000000
vn -1.000000 -0.000000 -0.000000
vn 0.000000 0.000000 -1.000000
usemtl Material
s off
f 1/1/1 2/2/1 3/3/1
f 1/1/1 3/3/1 4/4/1
f 5/1/2 8/2/2 7/3/2
f 5/1/2 7/3/2 6/4/2
f 1/1/3 5/2/3 6/3/3
f 1/1/3 6/3/3 2/4/3
f 2/1/4 6/2/4 7/3/4
f 2/1/4 7/3/4 3/4/4
f 3/1/5 7/2/5 8/3/5
f 3/1/5 8/3/5 4/4/5
f 5/1/6 1/2/6 4/3/6
f 5/1/6 4/3/6 8/4/6

次に、objを解析してデータ構造を作成するコードがあります。法線は正しく解析されています。次に、関連するコードスニペットは次のとおりです。

リンク中に位置とtexcoordsがバインドされていることを確認してください。

        // Attach vertex shader to program.
        glAttachShader(_program, vertShader);

        // Attach fragment shader to program.
        glAttachShader(_program, fragShader);

        // Bind attribute locations.
        glBindAttribLocation(_program, 0, "position");
        glBindAttribLocation(_program, 1, "tCoordinates");

頂点シェーダー(texcoordsをフラグメントシェーダーに渡すだけです):

uniform mat4 modelViewProjectionMatrix;
uniform mat3 normalMatrix;

attribute vec4 position;
attribute vec2 tCoordinates;

varying highp vec2 tCoordinatesVarying;

void main()
{
    tCoordinatesVarying = tCoordinates;
    gl_Position = modelViewProjectionMatrix * position;
}

ロードされたテクスチャからvec4を取得し、それをフラグカラーとして渡すだけのフラグメントシェーダー:

uniform sampler2D s_texture;

varying highp vec2 tCoordinatesVarying;

void main()
{
    gl_FragColor = texture2D(s_texture, tCoordinatesVarying);
}

そして、頂点属性とテクスチャおよびテクスチャユニット/サンプラーバインディングを設定するアプリのセットアップコード、事前描画:(今のところCGオブジェクトをリリースしないことは無視してください)

 NSString* path = [[NSBundle mainBundle] pathForResource:@"t1.png" ofType:nil];
    NSData* texData = [NSData dataWithContentsOfFile:path];
    UIImage* image = [UIImage imageWithData:texData];
    GLuint width = CGImageGetWidth(image.CGImage);
    GLuint height = CGImageGetHeight(image.CGImage);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    void* imageData = malloc(height*width*4);
    CGContextRef context = CGBitmapContextCreate(imageData, width, height, 8, 4*width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Host);
    CGContextClearRect(context, CGRectMake(0, 0, width, height));
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), image.CGImage);
    CGContextRelease(context);

    [EAGLContext setCurrentContext:self.context];
    [self loadShaders];

    glEnable(GL_DEPTH_TEST);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

    glActiveTexture(GL_TEXTURE0);

    glGenTextures(1, &_textureId);
    glBindTexture(GL_TEXTURE_2D, _textureId);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);

    int loc = glGetUniformLocation(_program, "s_texture");
    glUniform1i(loc, 0);

    glGenVertexArraysOES(1, &_vertexArray);
    glBindVertexArrayOES(_vertexArray);

    glGenBuffers(1, &_vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, vboData->vertexAttributesSize, vboData->vertexAttributes, GL_STATIC_DRAW);
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vboData->vertexAttributesStride,vboData->vPositionOffset);
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, vboData->vertexAttributesStride,vboData->vTCoordinatesOffset);
4

1 に答える 1

0

zacajの提案から、シェーダーにtexcoordを入れていないことに気づきました。バグは次のとおりです。

glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, vboData->vertexAttributesStride,vboData->vTCoordinatesOffset);

それで、私は属性番号を参照して有効にしましたGLKVertexAttribTexCoord0が、属性1で属性をバインドしていました。明らかに、GLK定数は1に変換されませんでした。

代わりに

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, vboData->vertexAttributesStride,vboData->vTCoordinatesOffset);

シェーダーでtexcoordsを取得し始めました。

于 2012-10-15T06:26:17.997 に答える