情况:
我在OpenGL中使用顶点缓冲对象(LWJGL java binding,GL11)来渲染矩形。我可以毫无问题地渲染纹理(顶点和纹理坐标),同时为它添加颜色可以产生所需的效果(比如使它变成半透明)。 仅使用顶点和颜色使其不可见。
期试验研究
我在代码中找不到任何错误,也无法找到问题的根源。
渲染时已激活状态:
GL_TEXTURE_2D,GL_SMOOTH(阴影模型),GL_DEPTH_TEST,GL_LEQUAL(深度函数),GL_BACK(剔除脸)
Blend Func:GL_SRC_ALPHA和GL_ONE_MINUS_SRC_ALPHA
Alpha Func:GL_GREATER和0.1F
投影:glOrtho(0,1,1,0,0,1000);
所有矩形在Z轴上为-1(我在渲染GUI之前调用glTranslatef(0,0,-1)
),在X轴和Y轴之间在0和1之间。另外我必须说a纹理是绑定的,但这不应该是问题。
重要代码
注意: Color类基本上包装了RGBA颜色,并且由我编写,因此它不是java.awt
包的Color类。
注2:我知道我的VertexBufferObject类没有使用动态绘制VBO进行优化,但我找不到时间来处理它。
顶点缓冲区对象
private boolean isStatic;
private boolean hasColor;
private boolean hasTexture;
private boolean hasNormals;
private int renderMode;
private int vertices;
private int vertexSize;
private ByteBuffer buffer;
private int vboId;
private boolean isDirty;
public VertexBufferObject (int renderMode, boolean isStatic, boolean hasColor, boolean hasTexture, boolean hasNormals, int vertices) {
this.isStatic = isStatic;
this.hasColor = hasColor;
this.hasTexture = hasTexture;
this.hasNormals = hasNormals;
this.vertices = vertices;
this.renderMode = renderMode;
vertexSize = calculateVertexSize();
}
public void markDirty () {
isDirty = true;
}
public void createBuffer () {
buffer = BufferUtils.createByteBuffer(getVertexSize());
markDirty();
}
public void createVBO () {
buffer.flip();
vboId = ARBVertexBufferObject.glGenBuffersARB();
// Buffer into vbo
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, vboId);
ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, buffer, (isStatic ? ARBVertexBufferObject.GL_STATIC_DRAW_ARB : ARBVertexBufferObject.GL_DYNAMIC_DRAW_ARB));
// Unbind
ARBVertexBufferObject.glUnmapBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB);
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, 0);
if (isStatic) buffer = null;
}
public void addVertex (float x, float y, float z) {
buffer.putFloat(x);
buffer.putFloat(y);
buffer.putFloat(z);
}
public void addTextureCoordinates (float u, float v) {
buffer.putFloat(u);
buffer.putFloat(v);
}
public void addColor (Color color) {
addColor(color.getRGBAInt());
}
public void addColor (int rgba) {
buffer.putInt(rgba);
System.out.println(Integer.toBinaryString(rgba));
}
public void addNormal (byte x, byte y, byte z) {
buffer.put(x);
buffer.put(y);
buffer.put(z);
}
public void setVertex (int index, float x, float y, float z) {
index *= vertexSize;
buffer.position(index);
buffer.putFloat(x);
buffer.putFloat(y);
buffer.putFloat(z);
markDirty();
}
public void setTextureCoordinates (int index, float u, float v) {
index *= vertexSize + 12;
buffer.position(index);
buffer.putFloat(u);
buffer.putFloat(v);
markDirty();
}
public void setColor (int index, Color color) {
setColor(index, color.getRGBAInt());
}
public void setColor (int index, int rgba) {
index *= vertexSize + (hasTexture ? 20 : 12);
buffer.position(index);
buffer.putInt(rgba);
markDirty();
}
public void setNormal (int index, byte x, byte y, byte z) {
index *= vertexSize - 3;
buffer.position(index);
buffer.put(x);
buffer.put(y);
buffer.put(z);
markDirty();
}
public void draw () {
draw(0, vertices);
}
public void draw (int start, int vertexNumber) {
if (vboId == 0) return;
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, vboId);
// Update Dynamic VBO
if (isDirty && !isStatic) {
buffer.position(0);
int vboType = isStatic ? ARBVertexBufferObject.GL_STATIC_DRAW_ARB : ARBVertexBufferObject.GL_DYNAMIC_DRAW_ARB;
ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, 0, vboType);
ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, buffer, vboType);
isDirty = false;
}
// Stride
int stride = 12;
if (hasTexture) stride += 8;
if (hasColor) stride += 4;
if (hasNormals) stride += 3;
// Apply Pointers
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glVertexPointer(3, GL11.GL_FLOAT, stride, 0);
if (hasTexture) {
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL11.glTexCoordPointer(2, GL11.GL_FLOAT, stride, 12);
}
if (hasColor) {
GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
GL11.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, stride, hasTexture ? 20 : 12);
}
if (hasNormals) {
GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
GL11.glNormalPointer(GL11.GL_BYTE, stride, stride - 3);
}
// Draw with specified render mode
GL11.glDrawArrays(renderMode, start, vertexNumber);
// Unbind VBO
if (hasTexture) GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
if (hasColor) GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
if (hasNormals) GL11.glDisableClientState(GL11.GL_NORMAL_ARRAY);
GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, 0);
}
public void destroy () {
ARBVertexBufferObject.glDeleteBuffersARB(vboId);
}
private int calculateVertexSize () {
return vertices * 12 + vertices * (hasTexture ? 8 : 0) + vertices * (hasColor ? 4 : 0) + vertices * (hasNormals ? 4 : 0);
}
ColorFrameRenderer (基本上是矩形)
private VertexBufferObject vbo;
private Color color;
public ColorFrameRenderer(int sizeX, int sizeY, Color color) {
super(sizeX, sizeY);
this.color = color;
}
@Override
public void render() {
if (!render) return;
vbo.draw();
}
@Override
public void init() {
vbo = new VertexBufferObject(GL11.GL_QUADS, false, true, false, false, 4);
vbo.createBuffer();
vbo.addVertex(x, y, 0);
vbo.addColor(color);
vbo.addVertex(x, y + sizeY, 0);
vbo.addColor(color);
vbo.addVertex(x + sizeX, y + sizeY, 0);
vbo.addColor(color);
vbo.addVertex(x + sizeX, y, 0);
vbo.addColor(color);
vbo.createVBO();
}
@Override
public void setPosition (float x, float y, float z) {
super.setPosition(x, y, z);
if (vbo != null) {
vbo.setVertex(0, this.x, this.y, 0);
vbo.setVertex(1, this.x, this.y + sizeY, 0);
vbo.setVertex(2, this.x + sizeX, this.y + sizeY, 0);
vbo.setVertex(3, this.x + sizeX, this.y, 0);
}
}
感谢您的帮助和建议!
请理解,由于它所属的或多或少的秘密项目,我无法提供整个代码。
答案 0 :(得分:4)
渲染时激活状态: GL_TEXTURE_2D
我认为那是你的问题:如果你不想纹理,请禁用GL_TEXTURE_ ....否则整个基元将从最后使用的纹理坐标中采样,可能是alpha = 0样本。