纹理渲染不正确 (OpenGL)
Texture renders incorrectly (OpenGL)
我一直在尝试渲染 8x8 纹理。我使用了 2 个教程中的代码,但纹理渲染不正确。现在我有这个初始化代码:
int shaderProgram,fragmentShader,vertexShader,texture,elementBuffer,vertexBuffer, vertexArray;
public Texture2D(String texturePath_, String vertexShader_,String fragmentShader_)
{
vertexArray=GL30.glGenVertexArrays();
GL30.glBindVertexArray(vertexArray);
String[] vertexshader=Utilities.loadShaderFile(vertexShader_,getClass());
String[] fragmentshader=Utilities.loadShaderFile(fragmentShader_,getClass());
if(vertexshader==null)
throw new NullPointerException("The vertex shader is null");
if(fragmentshader==null)
throw new NullPointerException("The fragment shader is null");
vertexShader=GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
GL20.glShaderSource(vertexShader,vertexshader);
GL20.glCompileShader(vertexShader);
Utilities.showShaderCompileLog(vertexShader);
fragmentShader=GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
GL20.glShaderSource(fragmentShader,fragmentshader);
GL20.glCompileShader(fragmentShader);
Utilities.showShaderCompileLog(fragmentShader);
shaderProgram= GL20.glCreateProgram();
GL20.glAttachShader(shaderProgram,fragmentShader);
GL20.glAttachShader(shaderProgram,vertexShader);
GL30.glBindFragDataLocation(shaderProgram,0,"fragcolor");
GL20.glLinkProgram(shaderProgram);
GL20.glUseProgram(shaderProgram);
texture= GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D,texture);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_WRAP_S, GL13.GL_CLAMP_TO_BORDER);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_WRAP_T,GL13.GL_CLAMP_TO_BORDER);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_MIN_FILTER,GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_MAG_FILTER,GL11.GL_LINEAR);
ByteBuffer image;
FloatBuffer verteces;
IntBuffer imagewidth,imageheight, positions,imagechannels;
try(MemoryStack memoryStack=MemoryStack.stackPush())
{
imageheight=memoryStack.mallocInt(1);
imagewidth=memoryStack.mallocInt(1);
positions=memoryStack.mallocInt(6);
imagechannels=memoryStack.mallocInt(1);
image= STBImage.stbi_load(texturePath_,imagewidth,imageheight,imagechannels,0);
if(image==null) throw new NullPointerException("Failed to load image");
verteces=memoryStack.mallocFloat(28);
}
positions.put(0).put(1).put(2).put(2).put(3).put(0).flip();
int width=imagewidth.get();
int height=imageheight.get();
GL11.glTexImage2D(GL11.GL_TEXTURE_2D,0,GL11.GL_RGBA,width,height,0,GL11.GL_RGBA,GL11.GL_UNSIGNED_BYTE,image);
elementBuffer=GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER,elementBuffer);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER,positions,GL15.GL_STATIC_DRAW);
float x1=0f, x2=1f;
float y1=1f,y2=-1f;
verteces.put(x1).put(y1).put(1).put(1).put(1).put(0).put(0);
verteces.put(x1).put(y2).put(1).put(1).put(1).put(1).put(0);
verteces.put(x2).put(y2).put(1).put(1).put(1).put(1).put(1);
verteces.put(x2).put(y1).put(1).put(1).put(1).put(0).put(1).flip();
vertexBuffer=GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,vertexBuffer);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER,verteces,GL15.GL_STATIC_DRAW);
int uniform=GL20.glGetUniformLocation(shaderProgram,"texture_image");
GL20.glUniform1i(uniform,0);
int position=GL20.glGetAttribLocation(shaderProgram,"position");
GL20.glEnableVertexAttribArray(position);
GL20.glVertexAttribPointer(position,2,GL11.GL_FLOAT,false,0,0);
int color=GL20.glGetAttribLocation(shaderProgram,"color");
GL20.glEnableVertexAttribArray(color);
GL20.glVertexAttribPointer(color,3,GL11.GL_FLOAT,false,7*Float.BYTES, 2 * Float.BYTES);
int textureST=GL20.glGetAttribLocation(shaderProgram,"textureCoord");
GL20.glEnableVertexAttribArray(textureST);
GL20.glVertexAttribPointer(textureST,3,GL11.GL_FLOAT,false,7*Float.BYTES, 5 * Float.BYTES);
Utilities.showErrors(1);
}
结果是:
但我想要纹理占据所有区域。着色器编译正常,没有 GL 错误。
如果我将值更改为教程中的值:
verteces.put(-1f).put(1f).put(1).put(1).put(1).put(0).put(0);
verteces.put(1f).put(1f).put(1).put(1).put(1).put(1).put(0);
verteces.put(1f).put(-1f).put(1).put(1).put(1).put(1).put(1);
verteces.put(-1f).put(-1f).put(1).put(1).put(1).put(0).put(1).flip();
我得到:
教程:https://open.gl/textures and https://github.com/SilverTiger/lwjgl3-tutorial/wiki/Textures
我使用的是配置文件 3.0 和着色器版本 300 ES。纹理格式为PNG。
顶点属性布局:
GL20.glVertexAttribPointer(position,2,GL11.GL_FLOAT,false,0,0);
GL20.glVertexAttribPointer(color,3,GL11.GL_FLOAT,false,7*Float.BYTES, 2 * Float.BYTES);
GL20.glVertexAttribPointer(textureST,3,GL11.GL_FLOAT,false,7*Float.BYTES, 5 * Float.BYTES);
看起来不正确。它有多个问题:
- 纹理坐标尝试从数组中读取 3 个浮点数。结合步幅,您的最后一个顶点将在 VBO 之外读取。很可能纹理坐标应该只读取 2 个浮点数。
- 使用的浮点数总数 (2+3+3=8) 不适合每个顶点仅给出 7 个浮点数的数据。这在纹理坐标只读取两个浮点数时得到解决。
- 位置的步幅看起来不对。 0 表示所有位置都紧密排列。基本上,位置使用 VBO 中的前 8 个浮点数。如果您查看它们:
{-1, 1, 1, 1, 1, 0, 0, 1}
,那么这正是您所看到的几何图形。幸运的是它首先起作用了。解决方案:将位置布局更改为:
GL20.glVertexAttribPointer(position,2,GL11.GL_FLOAT,false,7*Float.BYTES,0);
我一直在尝试渲染 8x8 纹理。我使用了 2 个教程中的代码,但纹理渲染不正确。现在我有这个初始化代码:
int shaderProgram,fragmentShader,vertexShader,texture,elementBuffer,vertexBuffer, vertexArray;
public Texture2D(String texturePath_, String vertexShader_,String fragmentShader_)
{
vertexArray=GL30.glGenVertexArrays();
GL30.glBindVertexArray(vertexArray);
String[] vertexshader=Utilities.loadShaderFile(vertexShader_,getClass());
String[] fragmentshader=Utilities.loadShaderFile(fragmentShader_,getClass());
if(vertexshader==null)
throw new NullPointerException("The vertex shader is null");
if(fragmentshader==null)
throw new NullPointerException("The fragment shader is null");
vertexShader=GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
GL20.glShaderSource(vertexShader,vertexshader);
GL20.glCompileShader(vertexShader);
Utilities.showShaderCompileLog(vertexShader);
fragmentShader=GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
GL20.glShaderSource(fragmentShader,fragmentshader);
GL20.glCompileShader(fragmentShader);
Utilities.showShaderCompileLog(fragmentShader);
shaderProgram= GL20.glCreateProgram();
GL20.glAttachShader(shaderProgram,fragmentShader);
GL20.glAttachShader(shaderProgram,vertexShader);
GL30.glBindFragDataLocation(shaderProgram,0,"fragcolor");
GL20.glLinkProgram(shaderProgram);
GL20.glUseProgram(shaderProgram);
texture= GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D,texture);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_WRAP_S, GL13.GL_CLAMP_TO_BORDER);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_WRAP_T,GL13.GL_CLAMP_TO_BORDER);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_MIN_FILTER,GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D,GL11.GL_TEXTURE_MAG_FILTER,GL11.GL_LINEAR);
ByteBuffer image;
FloatBuffer verteces;
IntBuffer imagewidth,imageheight, positions,imagechannels;
try(MemoryStack memoryStack=MemoryStack.stackPush())
{
imageheight=memoryStack.mallocInt(1);
imagewidth=memoryStack.mallocInt(1);
positions=memoryStack.mallocInt(6);
imagechannels=memoryStack.mallocInt(1);
image= STBImage.stbi_load(texturePath_,imagewidth,imageheight,imagechannels,0);
if(image==null) throw new NullPointerException("Failed to load image");
verteces=memoryStack.mallocFloat(28);
}
positions.put(0).put(1).put(2).put(2).put(3).put(0).flip();
int width=imagewidth.get();
int height=imageheight.get();
GL11.glTexImage2D(GL11.GL_TEXTURE_2D,0,GL11.GL_RGBA,width,height,0,GL11.GL_RGBA,GL11.GL_UNSIGNED_BYTE,image);
elementBuffer=GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER,elementBuffer);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER,positions,GL15.GL_STATIC_DRAW);
float x1=0f, x2=1f;
float y1=1f,y2=-1f;
verteces.put(x1).put(y1).put(1).put(1).put(1).put(0).put(0);
verteces.put(x1).put(y2).put(1).put(1).put(1).put(1).put(0);
verteces.put(x2).put(y2).put(1).put(1).put(1).put(1).put(1);
verteces.put(x2).put(y1).put(1).put(1).put(1).put(0).put(1).flip();
vertexBuffer=GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,vertexBuffer);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER,verteces,GL15.GL_STATIC_DRAW);
int uniform=GL20.glGetUniformLocation(shaderProgram,"texture_image");
GL20.glUniform1i(uniform,0);
int position=GL20.glGetAttribLocation(shaderProgram,"position");
GL20.glEnableVertexAttribArray(position);
GL20.glVertexAttribPointer(position,2,GL11.GL_FLOAT,false,0,0);
int color=GL20.glGetAttribLocation(shaderProgram,"color");
GL20.glEnableVertexAttribArray(color);
GL20.glVertexAttribPointer(color,3,GL11.GL_FLOAT,false,7*Float.BYTES, 2 * Float.BYTES);
int textureST=GL20.glGetAttribLocation(shaderProgram,"textureCoord");
GL20.glEnableVertexAttribArray(textureST);
GL20.glVertexAttribPointer(textureST,3,GL11.GL_FLOAT,false,7*Float.BYTES, 5 * Float.BYTES);
Utilities.showErrors(1);
}
结果是:
但我想要纹理占据所有区域。着色器编译正常,没有 GL 错误。 如果我将值更改为教程中的值:
verteces.put(-1f).put(1f).put(1).put(1).put(1).put(0).put(0);
verteces.put(1f).put(1f).put(1).put(1).put(1).put(1).put(0);
verteces.put(1f).put(-1f).put(1).put(1).put(1).put(1).put(1);
verteces.put(-1f).put(-1f).put(1).put(1).put(1).put(0).put(1).flip();
我得到:
教程:https://open.gl/textures and https://github.com/SilverTiger/lwjgl3-tutorial/wiki/Textures
我使用的是配置文件 3.0 和着色器版本 300 ES。纹理格式为PNG。
顶点属性布局:
GL20.glVertexAttribPointer(position,2,GL11.GL_FLOAT,false,0,0);
GL20.glVertexAttribPointer(color,3,GL11.GL_FLOAT,false,7*Float.BYTES, 2 * Float.BYTES);
GL20.glVertexAttribPointer(textureST,3,GL11.GL_FLOAT,false,7*Float.BYTES, 5 * Float.BYTES);
看起来不正确。它有多个问题:
- 纹理坐标尝试从数组中读取 3 个浮点数。结合步幅,您的最后一个顶点将在 VBO 之外读取。很可能纹理坐标应该只读取 2 个浮点数。
- 使用的浮点数总数 (2+3+3=8) 不适合每个顶点仅给出 7 个浮点数的数据。这在纹理坐标只读取两个浮点数时得到解决。
- 位置的步幅看起来不对。 0 表示所有位置都紧密排列。基本上,位置使用 VBO 中的前 8 个浮点数。如果您查看它们:
{-1, 1, 1, 1, 1, 0, 0, 1}
,那么这正是您所看到的几何图形。幸运的是它首先起作用了。解决方案:将位置布局更改为:GL20.glVertexAttribPointer(position,2,GL11.GL_FLOAT,false,7*Float.BYTES,0);