[英]my sprites are switching between textures opengl
我正在使用 glDrawElements 绘制所有在缓冲区中的精灵。 为了告诉精灵在片段着色器中使用什么纹理,我有统一的 sampler2D 纹理 [32]; 每个顶点都有一个索引,它从顶点着色器传递给片段着色器:
color = texture(textures[index], fs_in.uv);
当我尝试使用超过 1 个激活的纹理绘制我的精灵时,它会在右上角获得错误的纹理
http://puu.sh/lyr5j/d8c2cf6c8f.png
我不知道为什么会发生这种情况 尝试过纹理参数
我似乎找不到任何遇到类似问题的人。
这是我的渲染器的 init 函数(我有意将 texid 作为 float 传递,因为我听说 int 不能正常工作(也尝试过))
glGenBuffers(1, &m_VDBO); glGenVertexArrays(1, &m_VAO);
glBindVertexArray(m_VAO);
glBindBuffer(GL_ARRAY_BUFFER, m_VDBO);
glBufferData(GL_ARRAY_BUFFER, RENDERER_BUFFER_SIZE, 0, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(SHADER_VERTEX_INDEX);
glEnableVertexAttribArray(SHADER_UV_INDEX);
glEnableVertexAttribArray(SHADER_COLOR_INDEX);
glEnableVertexAttribArray(SHADER_TEXID_INDEX);
glVertexAttribPointer(SHADER_VERTEX_INDEX, 3, GL_FLOAT, GL_FALSE, RENDERER_VERTEX_SIZE, (const void *) offsetof(VertexData, VertexData::vertex));
glVertexAttribPointer(SHADER_UV_INDEX, 2, GL_FLOAT, GL_FALSE, RENDERER_VERTEX_SIZE, (const void *) offsetof(VertexData, VertexData::uv));
glVertexAttribPointer(SHADER_COLOR_INDEX, 4, GL_UNSIGNED_BYTE, GL_TRUE, RENDERER_VERTEX_SIZE, (const void *) offsetof(VertexData, VertexData::color));
glVertexAttribPointer(SHADER_TEXID_INDEX, 1, GL_FLOAT, GL_FALSE, RENDERER_VERTEX_SIZE, (const void *)offsetof(VertexData, VertexData::texID));
glBindBuffer(GL_ARRAY_BUFFER, 0);
const GLushort modelindices[] = { 0, 1, 2, 2, 3, 0 };
GLuint indices[RENDERER_INDICES_SIZE];
for (int i = 0; i < RENDERER_INDICES_SIZE; i += 6)
{
for (int o = 0; o < 6; o++)
{
indices[i + o] = modelindices[o] + (i / 6 * 4);
}
}
glGenBuffers(1, &m_IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, RENDERER_INDICES_SIZE * sizeof(GLuint), indices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
冲洗功能
glBindVertexArray(m_VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IBO);
for (int i = 0; i < m_TextureSlots.size(); i++)
{
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, m_TextureSlots[i]);
}
glDrawElements(GL_TRIANGLES, m_IndexCount, GL_UNSIGNED_INT, 0);
m_TextureSlots.clear();
m_IndexCount = 0;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
我很难看出您的问题来自哪里,我唯一能建议的是查看我拥有的 Image2d 类对象构造函数。 现在,我的源依赖于外部类,例如严重依赖模板类型的ShaderManager
类、 Batch
类和BatchManager
类以将顶点发送到视频卡。 这个Image2d
也是一个继承对象。 但是,这可能有助于您跟踪自己的问题。 根据所使用的 OpenGL 和 GLSL 版本,不同版本的实现有两种不同的构造函数。 如果我没记错的话,版本 2 使用 BatchManager 将顶点发送到视频卡,而版本 1 没有在render()
方法中看到。
Image2d v1.0
// ----------------------------------------------------------------------------
// Image2d()
Image2d::Image2d( float fWidth, float fHeight, TextureInfo::FilterQuality filterQuality, bool generateMipMap, const std::string& strTextureFilename, const std::string& strId ) :
VisualMko( glm::uvec2(), strId ),
m_vboTexture( 0 ),
m_vboPosition( 0 ),
m_vboIndices( 0 ),
m_vao( 0 ) {
if ( fWidth <= 0 || fHeight <= 0 ) {
std::ostringstream strStream;
strStream << __FUNCTION__ << " Invalid image size (" << fWidth << "," << fHeight << ") must be more then 0 in each dimension.";
throw ExceptionHandler( strStream );
}
// Save TextureId
TextureFileReader textureFileReader( strTextureFilename );
m_textureInfo = textureFileReader.getOrCreateTextureInfo( filterQuality, generateMipMap, false );
// Define Texture Co-Ordinates
std::vector<float> vTextureCoordinates;
vTextureCoordinates.push_back( 0.0f );
vTextureCoordinates.push_back( 1.0f );
vTextureCoordinates.push_back( 0 );
vTextureCoordinates.push_back( 0 );
vTextureCoordinates.push_back( 1.0f );
vTextureCoordinates.push_back( 1.0f );
vTextureCoordinates.push_back( 1.0f );
vTextureCoordinates.push_back( 0 );
// Define Vertex Positions (x,y,z)
std::vector<float> vVertexPositions;
vVertexPositions.push_back( 0 );
vVertexPositions.push_back( fHeight );
vVertexPositions.push_back( 0 );
vVertexPositions.push_back( 0 );
vVertexPositions.push_back( 0 );
vVertexPositions.push_back( 0 );
vVertexPositions.push_back( fWidth );
vVertexPositions.push_back( fHeight );
vVertexPositions.push_back( 0 );
vVertexPositions.push_back( fWidth );
vVertexPositions.push_back( 0 );
vVertexPositions.push_back( 0 );
// Define 2 Triangle Faces
std::vector<unsigned char> vIndices;
vIndices.push_back( 0 );
vIndices.push_back( 1 );
vIndices.push_back( 2 );
vIndices.push_back( 3 );
// Create Vertex Array Object
glGenVertexArrays( 1, &m_vao );
glBindVertexArray( m_vao ); // Start Array
m_pShaderManager->setAttribute( A_COLOR, COLOR_WHITE );
// Create Position Buffer And Store On Video Card
glGenBuffers( 1, & m_vboPosition );
glBindBuffer( GL_ARRAY_BUFFER, m_vboPosition );
glBufferData( GL_ARRAY_BUFFER, vVertexPositions.size() * sizeof( vVertexPositions[0] ), &vVertexPositions[0], GL_STATIC_DRAW );
m_pShaderManager->enableAttribute( A_POSITION );
// Create Texture Coordinate Buffer
glGenBuffers( 1, &m_vboTexture );
glBindBuffer( GL_ARRAY_BUFFER, m_vboTexture );
glBufferData( GL_ARRAY_BUFFER, vTextureCoordinates.size() * sizeof( vTextureCoordinates[0] ), &vTextureCoordinates[0], GL_STATIC_DRAW );
m_pShaderManager->enableAttribute( A_TEXTURE_COORD0 );
// Create Index Buffer
glGenBuffers( 1, &m_vboIndices );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_vboIndices );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, vIndices.size() * sizeof( vIndices[0] ), &vIndices[0], GL_STATIC_DRAW );
glBindVertexArray( 0 ); // Stop Array
// Disable Attribute Pointers
m_pShaderManager->disableAttribute( A_POSITION );
m_pShaderManager->disableAttribute( A_TEXTURE_COORD0 );
// THIS MUST BE AFTER Vertex Array Buffer Is Unbound!
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); // Stop Buffer Index
glBindBuffer( GL_ARRAY_BUFFER, 0 ); // Stop Buffer
// We have a Valid Image2d Save Filename
m_strFilename = strTextureFilename;
} // Image2D - v1.0
Image2D - v2.0
// ----------------------------------------------------------------------------
// Image2d()
Image2d::Image2d( const glm::uvec2& origin, const glm::uvec2& size, const std::string& strTextureFilename, const std::string& strId ) :
VisualMko( size, strId ),
m_vboTexture( 0 ),
m_vboPosition( 0 ),
m_vboIndices( 0 ),
m_vao( 0 ) {
m_version = 2;
TextureFileReader textureFileReader( strTextureFilename );
m_textureInfo = textureFileReader.getOrCreateTextureInfo( TextureInfo::FILTER_NONE, false, false );
m_config.uTextureId = m_textureInfo.uTextureId;
if ( 0 == m_textureInfo.size.x || 0 == m_textureInfo.size.y ) {
std::ostringstream strStream;
strStream << __FUNCTION__ << "size of " << strTextureFilename << " is invalid " << m_textureInfo.size;
throw ExceptionHandler( strStream );
}
// Verify Image Fits Inside Texture
if ( m_textureInfo.size.x < size.x + origin.x || m_textureInfo.size.y < size.y + origin.y ) {
std::ostringstream strStream;
strStream << __FUNCTION__ << " " << strTextureFilename << " size is " << m_textureInfo.size
<< " which is too small for an image that is " << size
<< " pixels in size, with an origin point set at " << origin ;
throw ExceptionHandler( strStream );
}
glm::vec2 textureCoordScaleFactor( 1.0f / static_cast<float>( m_textureInfo.size.x ),
1.0f / static_cast<float>( m_textureInfo.size.y ) );
glm::vec2 textureCoordBottomLeft = glm::vec2( textureCoordScaleFactor.x * origin.x,
textureCoordScaleFactor.y * ( m_textureInfo.size.y - origin.y - size.y ) );
glm::vec2 textureCoordTopRight = glm::vec2( textureCoordScaleFactor.x * ( origin.x + size.x ),
textureCoordScaleFactor.y * ( m_textureInfo.size.y - origin.y ) );
// Set Colors And Texture Coordinates (Position Will Be Updated In Render Function)
m_vVertices.push_back( GuiVertex( glm::vec2(), COLOR_WHITE, glm::vec2( textureCoordBottomLeft.x, textureCoordTopRight.y ) ) );
m_vVertices.push_back( GuiVertex( glm::vec2(), COLOR_WHITE, glm::vec2( textureCoordBottomLeft.x, textureCoordBottomLeft.y ) ) );
m_vVertices.push_back( GuiVertex( glm::vec2(), COLOR_WHITE, glm::vec2( textureCoordTopRight.x, textureCoordTopRight.y ) ) );
m_vVertices.push_back( GuiVertex( glm::vec2(), COLOR_WHITE, glm::vec2( textureCoordTopRight.x, textureCoordBottomLeft.y ) ) );
} // Image2d - v2.0
这是我的render()
方法
// ----------------------------------------------------------------------------
// render()
void Image2d::render() {
if ( 1 == m_version ) {
m_pShaderManager->setTexture( 0, U_TEXTURE0_SAMPLER_2D, m_textureInfo.uTextureId );
glBindVertexArray( m_vao );
glDrawElements( GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, nullptr );
glBindVertexArray( 0 );
} else {
// Version 2.0
// Update Vertices
if ( m_transformMatrix.updateTranslation || m_transformMatrix.updateScale || m_transformMatrix.updateRotation ) {
m_transformMatrix.updateTranslation = m_transformMatrix.updateScale = m_transformMatrix.updateRotation = false;
// Order Of Operations Matter Here!
glm::mat4 matrix; // Identity
if ( m_transformMatrix.hasTranslation ) {
matrix[3][0] = m_transformMatrix.translation.x;
matrix[3][1] = m_transformMatrix.translation.y;
}
if ( m_transformMatrix.hasRotation ) {
matrix = glm::rotate( matrix, m_transformMatrix.fRotationAngleRadians, glm::vec3( 0.0f, 0.0f, -1.0f ) );
}
if ( m_transformMatrix.hasScale ) {
matrix = matrix * glm::mat4( m_transformMatrix.scale.x, 0.0f, 0.0f, 0.0f,
0.0f, m_transformMatrix.scale.y, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f );
}
// Center Offset
if ( m_offsetPosition.x != 0 || m_offsetPosition.y != 0 ) {
matrix = glm::translate( matrix, glm::vec3( -m_offsetPosition.x, -m_offsetPosition.y, 0.0f ) );
}
// Apply Transformation To All 4 Vertices
m_vVertices[0].position = glm::vec2( matrix * glm::vec4( 0, 0, 0, 1.0f ) );
m_vVertices[1].position = glm::vec2( matrix * glm::vec4( 0, m_size.y, 0, 1.0f ) );
m_vVertices[2].position = glm::vec2( matrix * glm::vec4( m_size.x, 0, 0, 1.0f ) );
m_vVertices[3].position = glm::vec2( matrix * glm::vec4( m_size.x, m_size.y, 0, 1.0f ) );
}
renderBatch();
}
} // render
确保您在glBufferData(GL_ARRAY_BUFFER, RENDERER_BUFFER_SIZE, 0, GL_DYNAMIC_DRAW);
中指定的大小glBufferData(GL_ARRAY_BUFFER, RENDERER_BUFFER_SIZE, 0, GL_DYNAMIC_DRAW);
是准确的。 还要确保在适当的时间停止 VertexArray 并禁用属性指针。 您绑定的所有内容都必须是未绑定的,对于某些类型,订单确实很重要!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.