我花了很多时间试图找出如何在屏幕上绘制透明纹理,但我的代码似乎不起作用。到目前为止,只有完全不透明的纹理才能正常绘制(如下图的背景)。正如你在下图中看到的,透明部分被红色填充,而不是透明的。(我使用paint.net来绘制透明度,对吗?)
编辑(也使用新代码):现在透明的部分已经消失了,但是有一个红色的小轮廓,就像下面的图像,那里有半透明的像素。我如何使它也呈现为透明的?而且,我不明白为什么设置 glClearColor 的alpha不会改变任何东西。
我将 glClearColor 设置为红色,但Alpha为0。
GL11.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
下面是我绘制纹理的代码(使用 slick-util):
PNGDecoder decoder = null;
try {
decoder = new PNGDecoder(new FileInputStream(Main.projectPath + path));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
ByteBuffer buffer = ByteBuffer.allocateDirect(4 * decoder.getWidth() * decoder.getHeight());
try {
decoder.decode(buffer, decoder.getWidth() * 4, PNGDecoder.RGBA);
} catch (IOException e) {
e.printStackTrace();
}
buffer.flip();
int id = GL13.glGenTextures();
GL13.glBindTexture(GL13.GL_TEXTURE_2D, id);
GL13.glPixelStorei(GL13.GL_UNPACK_ALIGNMENT, 1);
GL13.glTexParameterf(GL13.GL_TEXTURE_2D, GL13.GL_TEXTURE_MIN_FILTER, GL13.GL_NEAREST);
GL13.glTexParameterf(GL13.GL_TEXTURE_2D, GL13.GL_TEXTURE_MAG_FILTER, GL13.GL_NEAREST);
width = decoder.getWidth();
height = decoder.getHeight();
GL13.glTexImage2D(GL13.GL_TEXTURE_2D, 0, GL13.GL_RGBA, decoder.getWidth(), decoder.getHeight(), 0, GL13.GL_RGBA, GL13.GL_UNSIGNED_BYTE, buffer);
GL30.glGenerateMipmap(GL13.GL_TEXTURE_2D);
GL13.glTexParameteri(GL13.GL_TEXTURE_2D, GL13.GL_TEXTURE_WRAP_S, GL13.GL_RGBA);
GL13.glTexParameteri(GL13.GL_TEXTURE_2D, GL13.GL_TEXTURE_WRAP_T, GL13.GL_RGBA);
GL13.glTexParameteri(GL13.GL_TEXTURE_2D, GL13.GL_TEXTURE_MIN_FILTER, GL13.GL_NEAREST_MIPMAP_NEAREST);
GL13.glTexParameteri(GL13.GL_TEXTURE_2D, GL13.GL_TEXTURE_MAG_FILTER,GL13. GL_NEAREST);
this.texture = new Texture(id);
this.textureID = id;
下面是我在屏幕上渲染纹理的代码:
public void renderMesh(Mesh mesh) {
GL30.glBindVertexArray(mesh.getVAO());
GL30.glEnableVertexAttribArray(0);
GL30.glEnableVertexAttribArray(1);
GL30.glEnableVertexAttribArray(2);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, mesh.getIBO());
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL13.glBindTexture(GL11.GL_TEXTURE_2D, mesh.getMaterial().getTextureID());
shader.bind();
GL11.glDrawElements(GL11.GL_TRIANGLES, mesh.getIndices().length, GL11.GL_UNSIGNED_INT, 0);
shader.unbind();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL30.glDisableVertexAttribArray(0);
GL30.glDisableVertexAttribArray(1);
GL30.glDisableVertexAttribArray(2);
GL30.glBindVertexArray(0);
}
我想知道这个代码的错误是什么。
编辑:下面是我的init和着色器代码:初始化代码:
window = GLFW.glfwCreateWindow(width, height, title, isFullscreen ? GLFW.glfwGetPrimaryMonitor() : 0, 0);
if (window == 0) {
System.err.println("ERROR: Window wasn't created");
return;
}
GLFWVidMode videoMode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
windowPosX[0] = (videoMode.width() - width) / 2;
windowPosY[0] = (videoMode.height() - height) / 2;
GLFW.glfwSetWindowPos(window, windowPosX[0], windowPosY[0]);
GLFW.glfwMakeContextCurrent(window);
GL.createCapabilities();
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glMatrixMode(GL11.GL_TEXTURE);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_ALPHA_TEST);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glPushMatrix();
createCallbacks();
GLFW.glfwShowWindow(window);
GLFW.glfwSwapInterval(1);
顶点着色器:
#version 460 core
in vec3 position;
in vec4 color;
in vec2 textureCoord;
out vec4 passColor;
out vec2 passTextureCoord;
void main() {
gl_Position = vec4(position, 1.0);
passColor = color;
passTextureCoord = textureCoord;
}
片段着色器:
#version 330 core
out vec4 FragColor;
in vec2 passTextureCoord;
uniform sampler2D texture1;
void main()
{
vec4 texColor = texture(texture1, passTextureCoord);
if(texColor.a < 0.1)
discard;
FragColor = texColor;
}
1条答案
按热度按时间6rvt4ljy1#
为了解决红色轮廓的问题,我认为您需要将丢弃像素的阈值设置得更高一些。
我的怀疑是绘图程序没有绘制完全透明的像素。例如,如果一个像素的alpha值为0.2,它不会被丢弃,尽管它有点透明。然后渲染器试图将它与背景混合,因为它不在顺序中。
像素可能是红色的,因为您将背景颜色设置为红色:
因此,解决此问题的方法是将对象从后往前排序,或者将片段着色器中的丢弃阈值提高到0.9。