libgdx/libgdx · error · GdxRuntimeException
Can't use + buffer.getClass().getName() + with type + typ
Error message
Can't use + buffer.getClass().getName() + with type + type + with this method. Use ByteBuffer and one of GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT or GL_FLOAT for type. Blame LWJGL
What it means
Thrown by LwjglGL20.glVertexAttribPointer when a ByteBuffer is bound as the attribute buffer but the type argument is none of GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT or GL_FLOAT. For each accepted type the backend reinterprets the ByteBuffer (asShortBuffer/asFloatBuffer) to satisfy LWJGL's typed overloads; other types — notably GL_UNSIGNED_INT and GL_FIXED — have no desktop overload path, hence 'Blame LWJGL'.
Source
Thrown at backends/gdx-backend-lwjgl/src/com/badlogic/gdx/backends/lwjgl/LwjglGL20.java:836
public void glVertexAttrib4fv (int indx, FloatBuffer values) {
GL20.glVertexAttrib4f(indx, values.get(), values.get(), values.get(), values.get());
}
public void glVertexAttribPointer (int indx, int size, int type, boolean normalized, int stride, Buffer buffer) {
if (buffer instanceof ByteBuffer) {
if (type == GL_BYTE)
GL20.glVertexAttribPointer(indx, size, false, normalized, stride, (ByteBuffer)buffer);
else if (type == GL_UNSIGNED_BYTE)
GL20.glVertexAttribPointer(indx, size, true, normalized, stride, (ByteBuffer)buffer);
else if (type == GL_SHORT)
GL20.glVertexAttribPointer(indx, size, false, normalized, stride, ((ByteBuffer)buffer).asShortBuffer());
else if (type == GL_UNSIGNED_SHORT)
GL20.glVertexAttribPointer(indx, size, true, normalized, stride, ((ByteBuffer)buffer).asShortBuffer());
else if (type == GL_FLOAT)
GL20.glVertexAttribPointer(indx, size, normalized, stride, ((ByteBuffer)buffer).asFloatBuffer());
else
throw new GdxRuntimeException("Can't use " + buffer.getClass().getName() + " with type " + type
+ " with this method. Use ByteBuffer and one of GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT or GL_FLOAT for type. Blame LWJGL");
} else if (buffer instanceof FloatBuffer) {
if (type == GL_FLOAT)
GL20.glVertexAttribPointer(indx, size, normalized, stride, (FloatBuffer)buffer);
else
throw new GdxRuntimeException(
"Can't use " + buffer.getClass().getName() + " with type " + type + " with this method.");
} else
throw new GdxRuntimeException(
"Can't use " + buffer.getClass().getName() + " with this method. Use ByteBuffer instead. Blame LWJGL");
}
public void glViewport (int x, int y, int width, int height) {
GL11.glViewport(x, y, width, height);
}
public void glDrawElements (int mode, int count, int type, int indices) {
GL11.glDrawElements(mode, count, type, indices);View on GitHub (pinned to 97f4086187)
Solutions
- Use GL_FLOAT with a FloatBuffer (or ByteBuffer reinterpreted via asFloatBuffer) for float attribute data — the standard desktop path.
- For integer attribute data, upload through an IntBuffer-backed VBO and the int-offset glVertexAttribPointer overload.
- Replace GL_FIXED layouts with float layouts on desktop; fixed-point is not a desktop type.
Example fix
// before Gdx.gl20.glVertexAttribPointer(loc, 4, GL20.GL_UNSIGNED_INT, false, stride, byteBuffer); // throws // after Gdx.gl20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vboHandle); Gdx.gl20.glVertexAttribPointer(loc, 4, GL20.GL_FLOAT, false, stride, 0);
Defensive patterns
Strategy: type-guard
Validate before calling
private static final Set<Integer> BYTE_BUFFER_TYPES = Set.of(GL20.GL_BYTE, GL20.GL_UNSIGNED_BYTE, GL20.GL_SHORT, GL20.GL_UNSIGNED_SHORT, GL20.GL_FLOAT);
if (buffer instanceof ByteBuffer && !BYTE_BUFFER_TYPES.contains(type)) throw new IllegalArgumentException("ByteBuffer supports BYTE/UBYTE/SHORT/USHORT/FLOAT only"); Type guard
private static boolean isByteBufferAttribTypeOK(java.nio.Buffer b, int type) {
return !(b instanceof ByteBuffer) || type == GL20.GL_BYTE || type == GL20.GL_UNSIGNED_BYTE
|| type == GL20.GL_SHORT || type == GL20.GL_UNSIGNED_SHORT || type == GL20.GL_FLOAT;
} Prevention
- No GL_UNSIGNED_INT or GL_FIXED attributes via ByteBuffer on desktop — use VBO + int-offset overload.
- Prefer float vertex layouts; they work everywhere.
When it happens
Trigger: Calling Gdx.gl20.glVertexAttribPointer(indx, size, GL_UNSIGNED_INT|GL_FIXED|..., normalized, stride, (ByteBuffer)buffer). Note: int attribute data cannot be passed via ByteBuffer here; and GL_FIXED is GLES-only.
Common situations: Porting Android meshes that use GL_FIXED (GLES1-era) or unsigned-int attributes; hand-written vertex layouts where the type constant was mistyped or copied from an index-buffer call.
Related errors
- Can't use + buffer.getClass().getName() + with type + typ
- Can't use + buffer.getClass().getName() + with this method
- Using null for the data not possible, blame LWJGL
- Can't use + data.getClass().getName() + with this method.
- Can't use + indices.getClass().getName() + with this metho
AI-assisted analysis of libgdx/libgdx@97f4086187 (2026-08-14).
Data as JSON: /api/errors/e4a061778559ca75.
Report an issue: GitHub.