OpenGL不一致的纹理创建

时间:2016-08-11 19:29:14

标签: android c++ ios opengl-es opengl-es-2.0

我目前在OpenGL ES 2.0中创建纹理时遇到一些问题。出于某种原因,iOS上的纹理是偏移的,Android上的纹理不对齐。我使用.bmp图片获取了像素数据来创建纹理。

错误:: iOS的:

ios error

错误::机器人:

android error

这就是我渲染纹理的方式:

void PolygonRenderer::renderTextures() {
    // Data read from the header of the BMP file
    unsigned char header[54]; // Each BMP file begins by a 54-bytes header
    unsigned int dataPos;     // Position in the file where the actual data begins
    unsigned int width, height;
    unsigned int imageSize;   // = width*height*3
    // Actual RGB data
    unsigned char * data;
    // Open the file
    FILE * file = fopen(iconPath,"rb");
    if (!file) {
        log("Image could not be opened\n");
        return;
    }
    if (fread(header, 1, 54, file) != 54) {
        log("Not a correct BMP file");
        return;
    }
    if (header[0] != 'B' || header[1] != 'M') {
        log("Not a correct BMP file");
        return;
    }
    // Read ints from the byte array
    dataPos     = *(int*)&(header[0x0A]);
    imageSize   = *(int*)&(header[0x22]);
    width       = *(int*)&(header[0x12]);
    height      = *(int*)&(header[0x16]);

    if (imageSize == 0) {
        imageSize = width * height;
    }
    log("Image size: %d, %d, total: %d", width, height, imageSize);
    if (dataPos == 0) {
        dataPos = 54;
    }

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);

    data = new unsigned char[imageSize];
    log("Elements read: %d", fread(data, 1, imageSize, file));
    fclose(file);

    glActiveTexture(GL_TEXTURE0);

    GLuint textureId;
    glGenTextures(1, &textureId);
    glBindTexture(GL_TEXTURE_2D, textureId);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,
        GL_UNSIGNED_BYTE, data);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    checkForGLError("Add texture:");
    log("Texture created: %d", textureId);
    loadingTexture = textureId;
}

我使用RGB的原因,即使.bmp保存为BGR是因为我使用R通道作为不透明度并在外部设置颜色。 (这也是OpenGL ES 2.0,它只有GL_RGB和GL_RGBA。)

渲染多边形摘录:

glUseProgram(shader.get(1));

GLuint projectionLocation =
    glGetUniformLocation(shader.get(1), "projection");
glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, projectionMatrix);
GLuint viewLocation = glGetUniformLocation(shader.get(1), "view");

glBindTexture(GL_TEXTURE_2D, loadingTexture);

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);

glUniformMatrix4fv(viewLocation, 1, GL_FALSE,
    &frame.combinedMatrix[16 * loadingPolygons[1].ViewGroup]);

glBindBuffer(GL_ARRAY_BUFFER, loadingPolygons[1].Buffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat),
    0);

glBindBuffer(GL_ARRAY_BUFFER, loadingPolygons[1].Buffer);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat),
    (GLvoid*)(3 * sizeof(GLfloat)));

glBindBuffer(GL_ARRAY_BUFFER, loadingPolygons[1].Buffer);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat),
    (GLvoid*)(6 * sizeof(GLfloat)));

checkForGLError("In Renderer");
glDrawArrays(GL_TRIANGLES, 0, 6);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);

glBindTexture(GL_TEXTURE_2D, 0);

顶点着色器来源:

std::string textureVertex =
    "attribute vec3 vertexloc;                                              \n"
    "attribute vec3 vertexcol;                                              \n"
    "attribute vec2 vertexuv;                                               \n"
    "varying vec2 TexCoords;                                                \n"
    "varying vec3 textColor;                                                \n"
    "uniform mat4 projection;                                               \n"
    "uniform mat4 view;                                                     \n"
    "void main()                                                            \n"
    "{                                                                      \n"
    "    gl_Position = projection * view * vec4(vertexloc, 1.0);   \n"
    "    TexCoords = vertexuv;                                              \n"
    "    textColor = vertexcol;                                             \n"
    "}";

Fragment Shader来源:

std::string textureFragment =
    "precision mediump float;                                               \n"
    "varying vec2 TexCoords;                                                \n"
    "varying vec3 textColor;                                                \n"
    "uniform sampler2D text;                                                \n"
    "void main()                                                            \n"
    "{                                                                      \n"
    "    vec4 sampled = vec4(1.0, 1.0, 1.0, texture2D(text, TexCoords).r);  \n"
    "    gl_FragColor = vec4(textColor, 1.0) * sampled;                     \n"
    "}";

编辑:添加了第二个loadingPolygon值:

w = 250;
h = 43;
x = sWindowWidth / 2 - w / 2;
y = - sWindowHeight / 4 - h / 2;
temp = {
    x,              y + h,          0.3,
    textureColor.x,    textureColor.y,    textureColor.z,
    0, 1,

    x,              y,              0.3,
    textureColor.x,    textureColor.y,    textureColor.z,
    0, 0,

    x + w,          y,              0.3,
    textureColor.x,    textureColor.y,    textureColor.z,
    1, 0,

    x,              y + h,          0.3,
    textureColor.x,    textureColor.y,    textureColor.z,
    0, 1,

    x + w,          y,              0.3,
    textureColor.x,    textureColor.y,    textureColor.z,
    1, 0,

    x + w,          y + h,          0.3,
    textureColor.x,    textureColor.y,    textureColor.z,
    1, 1
};
polygonRenderer.addLoadingPolygon(temp);

编辑2:Android eglconfig:

setEGLConfigChooser(8, 8, 8, 8, 16, 0);

编辑3:创建着色器:

GLuint Shader::LoadShader(std::string vertexSource,
    std::string fragmentSource, std::map<int, std::string> attribs) {

    GLuint vertexShader = LoadSubShader(vertexSource, GL_VERTEX_SHADER);
    GLuint fragmentShader = LoadSubShader(fragmentSource, GL_FRAGMENT_SHADER);

    if (vertexShader == 0 || fragmentShader == 0)
        return 0;

    GLuint program = glCreateProgram();

    if (program == 0) {
        log("Error compiling shader");
        return 0;
    }
    glAttachShader(program, vertexShader);
    glAttachShader(program, fragmentShader);

    std::map<int, string>::iterator it;
    for(it = attribs.begin(); it != attribs.end(); it++) {
        glBindAttribLocation(program, it->first, it->second.c_str());
    }

    glLinkProgram(program);

    GLint linked;
    glGetProgramiv(program, GL_LINK_STATUS, &linked);

    if (!linked) {
        log("ERROR");
        GLint infoLen = 0;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen);

        if (infoLen > 1) {
            char infoLog[512];
            glGetProgramInfoLog(program, infoLen, NULL, infoLog);
            log("Error linking program: %s", infoLog);
        }

        glDeleteProgram(program);
        return GL_FALSE;
    }
//    glDetachShader(program, vertexShader);
//    glDetachShader(program, fragmentShader);
    return program;
}

0 个答案:

没有答案