2012-08-13 36 views
1

我有一個尺寸爲320x320的正方形圖像,我從中創建了一個OpenGL紋理。我使用最基本的Vertext和Fragment着色器,我想在整個視圖中顯示紋理。視圖(從許多OpenGL iOS示例中的UIView派生而來的EAGLView)的大小也是320x320。爲什麼我的iPhone OpenGL-ES紋理不包含視口?

問題是,圖像繪製在左上角,只佔整個視圖的50%左右。它不包括100%的觀點。我不知道爲什麼?

Red square is EAGLView

這裏是我的代碼:

position = glGetAttribLocation(m_shaderProgram, "position"); 
inputTextureCoordinate = glGetAttribLocation(m_shaderProgram, "inputTextureCoordinate");  
inputImageTexture = glGetUniformLocation(m_shaderProgram, "inputImageTexture"); 

static const GLfloat textureCoordinates[] = { 
    0.0f, 1.0f, 
    1.0f, 1.0f, 
    0.0f, 0.0f, 
    1.0f, 0.0f, 
}; 

static const GLfloat imageVertices[] = { 
    -1.0f, -1.0f, 
    1.0f, -1.0f, 
    -1.0f, 1.0f, 
    1.0f, 1.0f, 
}; 

[EAGLContext setCurrentContext:context]; 

glViewport(0, 0, backingWidth, backingHeight); // These are 320, 320 

glUseProgram(m_shaderProgram); 

glClearColor(0, 0, 0, 1); 
glClear(GL_COLOR_BUFFER_BIT); 

glActiveTexture(GL_TEXTURE2); 
glBindTexture(GL_TEXTURE_2D, sourceTextureID); // The texture is also of size 320x320 

glUniform1i(inputImageTexture, 2); 

glVertexAttribPointer(position, 2, GL_FLOAT, 0, 0, imageVertices); 
glVertexAttribPointer(textureCoordinate, 2, GL_FLOAT, 0, 0, textureCoordinates); 

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);  
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 
[context presentRenderbuffer:GL_RENDERBUFFER_OES]; 

Vertext着色器。

attribute vec4 position; 
attribute vec4 inputTextureCoordinate; 

varying vec2 textureCoordinate; 

void main() 
{ 
    gl_Position = position; 
    textureCoordinate = inputTextureCoordinate.xy; 
} 

片段着色器。

varying highp vec2 textureCoordinate; 
uniform sampler2D inputImageTexture; 

void main() 
{ 
    gl_FragColor = texture2D(inputImageTexture, textureCoordinate); 
} 
+0

你考慮過iphone 4和2x尺寸因子嗎? (嘗試渲染它兩倍大,以彌補視網膜顯示) – Pochi 2012-08-13 08:25:29

+0

我嘗試了不同的尺寸,而不是320.但結果是一樣的。我在這裏只是用320來舉例。 – abix 2012-08-13 08:48:28

+0

你的意思是你已經試過改變視口嗎? cuz應該明確地使它看起來更大或更小 – Pochi 2012-08-13 08:51:19

回答

2

所以問題是紋理的尺寸不是2的能力。所以我們需要相應地調整紋理座標。插入以下幾行解決了這個問題...

GLfloat textureCoordinates[] = { 
    0.0f, 1.0f, 
    1.0f, 1.0f, 
    0.0f, 0.0f, 
    1.0f, 0.0f, 
}; 

float nearest2sPower = 2; 

if (nearest2sPower < backingWidth) { 
    while (nearest2sPower < backingWidth) { 
     nearest2sPower *= 2; 
    } 
} 

verticalFlipTextureCoordinates[2] = backingWidth/nearest2sPower; 
verticalFlipTextureCoordinates[6] = backingWidth/nearest2sPower; 

nearest2sPower = 2; 

if (nearest2sPower < backingWidth) { 
    while (nearest2sPower < backingWidth) { 
     nearest2sPower *= 2; 
    } 
} 

verticalFlipTextureCoordinates[1] = backingHeight/nearest2sPower; 
verticalFlipTextureCoordinates[3] = backingHeight/nearest2sPower; 
+0

儘管這確實是正確的答案,但它將取決於海報如何上傳紋理。大多數預先打包的解決方案都將達到兩個最接近的功率,但如果內存服務的話,ES 2.0實際上並不需要它。 – Tommy 2012-08-15 23:48:11

+0

這真的不應該被要求,所以我不認爲這是問題的真正解決方案。所有支持OpenGL ES 2.0的iOS設備都支持非二次冪的紋理(對於鉗位模式和mipmap的使用稍有限制)。如果這是紋理上傳的真正的非功率 - 2的錯誤,你只會得到一個黑色的圖像(相信我,我不止一次犯這個錯誤)。 – 2012-08-16 00:20:43

+0

@湯米和布拉德,對我來說這是一個愚蠢的錯誤。其實我複製了一些從UIImage創建紋理的代碼。並且該代碼在內部創建紋理,以「寬度和高度的下一個最接近的冪」。所以,我實際上是用我的代碼取消了額外的寬度和高度。對不起,錯誤的答案。該代碼不是必需的。 – abix 2012-08-17 13:26:56