2015-01-05 3 views
4

현재 비트 맵을 사용하여 정수 값을 렌더링하려하고 있습니다 (침입자에 대해 스코어 보드 사용)하지만 게임이 실행되는 동안 텍스처 좌표를 변경하는 데 문제가 있습니다.OpenGL : 즉석에서 텍스처 좌표 변경

나는과 같이 쉐이더 및 데이터 연결 :

GLint texAttrib = glGetAttribLocation(shaderProgram, "texcoord"); 
glEnableVertexAttribArray(texAttrib); 
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 
4 * sizeof(float), (void*)(2 * sizeof(float))); 

그리고 내 쉐이더에서

I 다음을 수행하십시오 버텍스 쉐이더 :

#version 150 

uniform mat4 mvp; 

in vec2 position; 
in vec2 texcoord; 

out vec2 Texcoord; 


void main() { 
    Texcoord = texcoord; 
    gl_Position = mvp * vec4(position, 0.0, 1.0) ; 
} 

FragmentShader :

#version 150 core 
in vec2 Texcoord; 
out vec4 outColor; 

uniform sampler2D tex; 
void main() { 
    outColor = texture2D(tex, Texcoord); 
} 

방법 이 코드를 변경하거나 texcoord 변수를 변경할 수있는 함수를 구현합니까?

+0

UV 좌표가 올바른 위치에 설정되어있는 메쉬를 생성하는 함수를 만듭니다. 공원에서 산책하는 것이 아니라 너무 어렵지 않습니다. – BWG

+0

@BWG "올바른 위치에 UV 좌표가 설정되었습니다."라는 말이 무슨 뜻인지 잘 모르겠습니다. 명확히하기 위해, 나는 문자/숫자를 초기에 렌더링 할 수 있도록 관리하지만 텍스쳐 좌표를 변경함으로써 텍스쳐 아틀라스를 사용하여 문자/숫자를 변경하려고합니다. – user3162904

+2

"셰이더와 데이터를 그렇게 링크"라고 말하면, 그렇게하지 말아야합니다. 셰이더는 한 번만 설정하면되지만 새 문자를 그리면 메쉬의 데이터를 업데이트해야합니다. 또는 셰이더에 정수를 전달하고 텍스처 좌표를 생성 할 수 있습니다. – BWG

답변

5

텍스처 좌표를 자주 수정해야하지만 다른 버텍스 속성은 변경되지 않으면 별도의 VBO에서 텍스처 좌표를 유지하는 것이 좋습니다. 인터리브 된 속성을 사용하는 것이 일반적으로 바람직하지만, 이것이 반드시 가장 효율적인 솔루션이 아닌 경우입니다.

두 개의 VBO가 있습니다. 하나는 위치에 대한 것이고 다른 하나는 텍스처 좌표입니다.

GLuint vboIds[2]; 
glGenBuffers(2, vboIds); 

// Load positions. 
glBindBuffer(GL_ARRAY_BUFFER, vboIds[0]); 
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW); 

// Load texture coordinates. 
glBindBuffer(GL_ARRAY_BUFFER, vboIds[1]); 
glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords), texCoords, GL_DYNAMIC_DRAW); 

주 사용법 힌트 glBufferData()에 다른 마지막 인수 : 귀하의 설치 코드는 다음과 같이 보일 것입니다. GL_STATIC_DRAW은 데이터가 정기적으로 수정되지 않는다는 것을 OpenGL 구현에 제안하지만 GL_DYNAMIC_DRAW은 자주 수정 될 것을 제안합니다.

그런 다음, 언제든지 텍스처 데이터 변경, 당신은 glBufferSubData()으로 수정할 수 있습니다 : 물론

glBindBuffer(GL_ARRAY_BUFFER, vboIds[1]); 
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(texCoords), texCoords); 

을 그 중 일부를 변경하는 경우에만 변경 부분에 대한 호출을 만들 것입니다.

텍스처 좌표가 얼마나 정확하게 변경되는지는 지정하지 않았습니다. 단순 변환과 같은 것이라면 원래 텍스처 좌표를 수정하는 대신 쉐이더 코드에서 그 변환을 적용하는 것이 훨씬 더 효율적입니다.

예를 들어 텍스처 좌표 만 이동하려고한다고 가정 해보십시오. 당신은 당신의 버텍스 쉐이더의 변화에 ​​대한 균일 한 변수가 다음 좌표 입력 텍스처에 속성을 추가 할 수 있습니다

uniform vec2 TexCoordShift; 
in vec2 TexCoord; 
out vec2 FragTexCoord; 
... 
    FragTexCoord = TexCoord + TexCoordShift; 

다음 C에서 ++ 코드 :

// Once during setup, after linking program. 
TexCoordShiftLoc = glGetUniformLocation(program, "TexCoordShift"); 

// To change transformation, after glUseProgram(), before glDraw*(). 
glUniform2f(TexCoordShiftLoc, xShift, yShift); 
+0

내 잘못은 언급하지 않았지만 그게 사실입니다. 그런 번역을하는 방법을 보여 주시겠습니까? 내 생각 엔 오프셋에 대한 또 다른 쉐이더 변수이지만 위의 메서드가 아닌 다른 메서드를 변경하려는 방법을 모르겠습니다. – user3162904

+0

답변 끝에 추가되었습니다. –

3

그래서이 기술의 효율성에 대해서는 약속하지 않지만 텍스트 렌더링이 내 프로그램의 속도를 늦추는 것은 내가하는 일이고 저주받을 것입니다.

나는 데이터의 벡터 벡터와 업로드 된 데이터에 대한 포인터를 저장하는 약간의 숫자로 구성된 메시를 저장하기위한 전용 클래스를 가지고있다. 나는이 같은 OpenGL과 데이터를 업로드 :

다음
  glBindBuffer(GL_ARRAY_BUFFER, position); 
      glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * data.position.size(), &data.position[0], GL_DYNAMIC_DRAW); 

      glBindBuffer(GL_ARRAY_BUFFER, normal); 
      glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * data.normal.size(), &data.normal[0], GL_DYNAMIC_DRAW); 

      glBindBuffer(GL_ARRAY_BUFFER, uv); 
      glBufferData(GL_ARRAY_BUFFER, sizeof(vec2) * data.uv.size(), &data.uv[0], GL_DYNAMIC_DRAW); 

      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index); 
      glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * data.index.size(), &data.index[0], GL_DYNAMIC_DRAW); 

이 그것을 그릴이 같은 이동 :

 glEnableVertexAttribArray(positionBinding); 
     glBindBuffer(GL_ARRAY_BUFFER, position); 
     glVertexAttribPointer(positionBinding, 3, GL_FLOAT, GL_FALSE, 0, NULL); 

     glEnableVertexAttribArray(normalBinding); 
     glBindBuffer(GL_ARRAY_BUFFER, normal); 
     glVertexAttribPointer(normalBinding, 3, GL_FLOAT, GL_TRUE, 0, NULL); 

     glEnableVertexAttribArray(uvBinding); 
     glBindBuffer(GL_ARRAY_BUFFER, uv); 
     glVertexAttribPointer(uvBinding, 2, GL_FLOAT, GL_FALSE, 0, NULL); 

     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index); 

     glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, NULL); 

     glDisableVertexAttribArray(positionBinding); 
     glDisableVertexAttribArray(normalBinding); 
     glDisableVertexAttribArray(uvBinding); 

당신은 확실히 아래로 음색 수 있도록이 설정은 전체 본격적인 3D 엔진 설계 조금. 기본적으로, 나는 4 개의 버퍼, 위치, uv, normal, index를 가지고있다. 처음 두 개만 필요하기 때문에 나머지는 무시하십시오.

어쨌든 내가 텍스트를 그리려 할 때마다, 내가 보여준 첫 번째 코드 청크를 사용하여 데이터를 업로드 한 다음 두 번째 청크를 사용하여 데이터를 그립니다. 그것은 꽤 잘 작동하고, 그것은 매우 우아합니다. 다음 코드를 사용하여 텍스트를 그립니다.

vbo(genTextMesh("some string")).draw(); //vbo is my mesh containing class 

질문이 있으시면 언제든지 문의하십시오.

+0

그럼 이제 자서 빠져 나올거야. 나는 내일 그것에 그것에 탄다. 노력에 감사드립니다. – user3162904

2

나는 유니폼을 사용합니다 vec2을 사용하여 버텍스 쉐이더에 텍스처 오프셋을 전달합니다.

얼마나 효율적인지 모르겠지만 텍스처 좌표가 같은 모양이고 방금 이동 한 경우이 옵션이 유용합니다.

#version 150 

uniform mat4 mvp; 
uniform vec2 texOffset; 

in vec2 position; 
in vec2 texcoord; 

out vec2 Texcoord; 


void main() { 
    Texcoord = texcoord + texOffset; 
    gl_Position = mvp * vec4(position, 0.0, 1.0) ; 
}