您的顶点着色器不会根据您的变换状态来变换顶点.所有与矩阵相关的 GL 函数,如 glOrtho、glTranslate、glMatrixMode 都已弃用.您必须使用自己的矩阵函数(或类似 glm 的库)并通过统一(或其他方式)将矩阵提供给着色器.在兼容性配置文件中,您还可以使用 GLSL 内置uniforms,它允许您访问带有这些不推荐使用的函数的旧内置矩阵,但我强烈建议不要依赖不推荐使用的功能.无论哪种情况,您的着色器都必须实际应用您的顶点和模型视图转换,这通常归结为矩阵向量产品,例如 projection * modelView * vec4(pos,1).至少可以说,您的属性指针很奇怪.您对顶点位置使用偏移量 0,对 texture 坐标使用 offsetof(...::worldCoord) 偏移量.现在,根据您定义成员的顺序,两者可能指向内存中完全相同的值,这将解释您提到的并且不以任何方式使用纹理坐标"部分.I'm trying to draw out two textured triangles to make a square using a VBO containing the coordinates on the screen and coordinates of the texture and an IBO with the indices. However I'm running into a problem. Without using a shader I get the correct size and position of the two triangles but no texture no matter how I try. With a shader I get a texture but the triangle is wrong size, in the wrong position and not using the texture coordinates in any way.Creating the texture glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexImage2D(GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0, texture_format, GL_UNSIGNED_BYTE, surface->pixels); glBindTexture(GL_TEXTURE_2D, NULL);Filling the VBO and IBO(TileData is a struct with two size 2 arrays) indices.push_back(0); indices.push_back(1); indices.push_back(2); indices.push_back(0); indices.push_back(2); indices.push_back(3); TileData tile; tile.texCoord[0] = 0 / imageSizeX; tile.texCoord[1] = 0 / imageSizeY; tile.worldCoord[0] = 0; tile.worldCoord[1] = 0; tiles.push_back(tile); tile.texCoord[0] = (0 + texWidth) / imageSizeX; tile.texCoord[1] = 0 / imageSizeY; tile.worldCoord[0] = 0 + texWidth; tile.worldCoord[1] = 0; tiles.push_back(tile); tile.texCoord[0] = (0 + texWidth) / imageSizeX; tile.texCoord[1] = (0 + texHeight) / imageSizeY; tile.worldCoord[0] = 0 + texWidth; tile.worldCoord[1] = 0 + texHeight; tiles.push_back(tile); tile.texCoord[0] = 0 / imageSizeX; tile.texCoord[1] = (0 + texHeight) / imageSizeY; tile.worldCoord[0] = 0; tile.worldCoord[1] = 0 + texHeight; tiles.push_back(tile);This gives code gives me the world coordinates and texture coordinates:0, 0 0, 016, 0 0.25, 016, 16 0.25, 10, 16 0, 1Generate my buffers glGenBuffers(1, &vboID); glBindBuffer(GL_ARRAY_BUFFER, vboID); glBufferData(GL_ARRAY_BUFFER, tiles.size() * sizeof(TileData), &tiles[0], GL_STATIC_DRAW); glGenBuffers(1, &iboID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboID); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);Draw function with shader glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(camera.x, camera.x + 320, camera.y + 240, camera.y, -1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shaderHandler.programID); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); GLint texLocation = glGetUniformLocation(shaderHandler.programID, "tex"); glUniform1i(texLocation, 0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vboID); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(CGame::TileData), (GLvoid *)0); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, vboID); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(CGame::TileData), (GLvoid*)offsetof(CGame::TileData, CGame::TileData::worldCoord)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboID); glDrawElements(GL_TRIANGLES, indices->size(), GL_UNSIGNED_INT, (GLvoid*)0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glBindTexture(GL_TEXTURE_2D, 0); SDL_GL_SwapWindow(window);ResultWith shaderDraw function without shader(The above code can also get the same result as this one if I unlink the shaderprogram) glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glClientActiveTexture(GL_TEXTURE0); glBindBuffer(GL_ARRAY_BUFFER, vboID); glVertexPointer(2, GL_FLOAT, sizeof(CGame::TileData), (GLvoid*)0); glTexCoordPointer(2, GL_FLOAT, sizeof(CGame::TileData), (GLvoid*)offsetof(CGame::TileData, CGame::TileData::worldCoord)); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboID); glDrawElements(GL_TRIANGLES, indices->size(), GL_UNSIGNED_INT, (GLvoid*)0); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); SDL_GL_SwapWindow(window);Resulst Without shaderVertex Shader#version 330layout(location = 0) in vec2 vert;layout(location = 1) in vec2 vertTexCoord;out vec2 fragTexCoord;void main() { fragTexCoord = vertTexCoord; gl_Position = vec4(vert, 0, 1);}Fragment Shader#version 330uniform sampler2D tex; in vec2 fragTexCoord; out vec4 finalColor; void main() { finalColor = texture2D(tex, fragTexCoord);}At this point I've no idea how to continue. I can't find anything that helps me on here or anywhere. I've tried so much things that I probably use something deprecated or doing something unsupported but I can't figure out what. 解决方案 I can see a couple of issues:In the fixed function, you have to explicitely call glEnable(GL_TEXTURE_2D) to tell the GL that your currently bound 2D texture shall be applied (separately for each texture unit).Your vertex shader does never transform the vertices according to your transform state. All the matrix-related GL functions like glOrtho, glTranslate, glMatrixMode are deprecated. You have to use your own matrix functions (or a library like glm) and supply the matrices to the shader via uniforms (or other means). In a compatiblity profile, you could also use the GLSL builtin uniforms which allow you to access the old builtin matrices set with those deprecated functions, but I strongly recommend to not rely on deprecated functionality. In either case, your shader has to actually apply your vertex and modelview transformations, which typically boils down to matrix-vector products like projection * modelView * vec4(pos,1).Your attribute pointers are weird, to say the least. You use an offset of 0 for the vertex positions, and and offset of offsetof(...::worldCoord) for the texture coordinates. Now depending on which order your members are defined, both might point to the exact same values in memory, which would explain the "and not using the texture coordinates in any way" part you mentioned. 这篇关于使用 VBO/IBO 的 OpenGL 纹理三角形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-23 06:32