我目前在OpenGL ES 2.0中创建纹理时遇到一些问题。出于某种原因,iOS上的纹理是偏移的,Android上的纹理不对齐。我使用.bmp
图片获取了像素数据来创建纹理。
错误:: iOS的:
错误::机器人:
这就是我渲染纹理的方式:
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;
}