2014-11-18 3 views
0

Я следил за учебником LazyFoo по текстурованию GLSL 2D (http://lazyfoo.net/tutorials/OpenGL/34_glsl_texturing/index.php), и мне удалось заставить большинство деталей работать.GLSL: рендеринг 2D-текстуры

Однако программа делает текстуру приближенной к реальности. Это проблема с вершиной или с текстурой? Ниже вершинные шейдеры я использую в моей реализации:

texCoord = LTexCoord; 
gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * vec4(LVertexPos2D.x, LVertexPos2D.y, 0.0, 1.0); 

и ниже фрагмент шейдера я использовал:

gl_FragColor = texture(textureID, texCoord); 

Что касается функции рендеринга, я отклониться от учебника с использованием OpenGL-х матрицы неподвижных трубопроводов (не нужно обновить матрицы):

//If the texture exists 
    if(mTextureID != 0) 
    { 
     //Texture coordinates 
     GLfloat texTop = 0.f; 
     GLfloat texBottom = (GLfloat)mImageHeight/(GLfloat)mTextureHeight; 
     GLfloat texLeft = 0.f; 
     GLfloat texRight = (GLfloat)mImageWidth/(GLfloat)mTextureWidth; 

     //Vertex coordinates 
     GLfloat quadWidth = mImageWidth; 
     GLfloat quadHeight = mImageHeight; 

     //Set vertex data 
     LVertexData2D vData[ 4 ]; 

     //Texture coordinates 
     vData[ 0 ].texCoord.s = texLeft; vData[ 0 ].texCoord.t = texTop; 
     vData[ 1 ].texCoord.s = texRight; vData[ 1 ].texCoord.t = texTop; 
     vData[ 2 ].texCoord.s = texRight; vData[ 2 ].texCoord.t = texBottom; 
     vData[ 3 ].texCoord.s = texLeft; vData[ 3 ].texCoord.t = texBottom; 

     //Vertex positions 
     vData[ 0 ].position.x =  0.f; vData[ 0 ].position.y =  0.f; 
     vData[ 1 ].position.x = quadWidth; vData[ 1 ].position.y =  0.f; 
     vData[ 2 ].position.x = quadWidth; vData[ 2 ].position.y = quadHeight; 
     vData[ 3 ].position.x =  0.f; vData[ 3 ].position.y = quadHeight; 

     glEnable(GL_TEXTURE_2D); 
     glBindTexture(GL_TEXTURE_2D, mTextureID); 
     glContext.textureShader->bind(); 
     glContext.textureShader->setTextureID(mTextureID); 
     glContext.textureShader->enableVertexPointer(); 
     glContext.textureShader->enableTexCoordPointer(); 
      glBindBuffer(GL_ARRAY_BUFFER, mVBOID); 
      glBufferSubData(GL_ARRAY_BUFFER, 0, 4 * sizeof(LVertexData2D), vData); 
      glContext.textureShader->setTexCoordPointer(sizeof(LVertexData2D), (GLvoid*)offsetof(LVertexData2D, texCoord)); 
      glContext.textureShader->setVertexPointer(sizeof(LVertexData2D), (GLvoid*)offsetof(LVertexData2D, position)); 
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIBOID); 
      glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, NULL); 
     glContext.textureShader->disableVertexPointer(); 
     glContext.textureShader->disableTexCoordPointer(); 
     glContext.textureShader->unbind(); 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 
     glBindTexture(GL_TEXTURE_2D, NULL); 
     glDisable(GL_TEXTURE_2D);   // disable texture 2d 


    } 
} 

в ответ на KORADI, вершинные и координаты текстур инстанцируются как таковые ниже:

void TextureShader::setVertexPointer(GLsizei stride, const GLvoid* data) 
{ 
    glVertexAttribPointer(mVertexPosLocation, 2, GL_FLOAT, GL_FALSE, stride, data); 
} 
void TextureShader::setTexCoordPointer(GLsizei stride, const GLvoid* data) 
{ 
    glVertexAttribPointer(mTexCoordLocation, 2, GL_FLOAT, GL_FALSE, stride, data); 
} 

Он оказывается в главном цикле со следующим кодом:

glPushMatrix(); 
    glTranslatef(glContext.gFBOTexture->imageWidth()/-2.f, glContext.gFBOTexture->imageHeight()/-2.f, 0.f); 
    glContext.gFBOTexture->render(); 
glPopMatrix(); 

есть что-то очевидно, что я с видом? Я новичок в GLSL.

Edit: Добавлено больше кода

+1

Ничего нельзя сказать, имея только вершинный шейдер. Предоставьте весь код, связанный с OpenGL. – lisyarus

+0

Почему вы используете 'mImageWidth' и' mImageHeight', как вы его используете? Кажется, вам нужно какое-то пиксельное точное отображение, но это предполагает, что ваши GL-матрицы настроены правильно. Не видя их, невозможно сказать, какая часть текстуры на самом деле заканчивается на экране. – derhass

ответ

0

После обдумывает над ним в течение нескольких дней, этот вопрос с тем, как отправить sampler2D форму в GLSL:

glBindTexture(GL_TEXTURE_2D, mTextureID); 
glContext.textureShader->bind(); 
glContext.textureShader->setTextureID(mTextureID); 

было исправлено на:

glBindTexture(GL_TEXTURE_2D, mTextureID); 
glContext.textureShader->bind(); 
glContext.textureShader->setTextureID(0); 

setTextureID() устанавливает единую переменную sampler2D. После связывания текстуры унитарность sampler2D должна быть установлена ​​в 0, а не на адрес текстуры.

+0

Точнее, значение сэмплера является текстурной единицей, к которой привязана текстура. –

+0

Ноль - это потому, что ноль - это начальная активная единица текстуры. Вы можете вызвать ['glActiveTexture (GL_TEXTURE1)'] (https://www.opengl.org/sdk/docs/man/docbook4/xhtml/glActiveTexture.xml) перед связыванием текстуры, например, а затем вызвать 'glContext.textureShader- > setTextureID (1); '. – jozxyqk

Смежные вопросы