/**
* Copyright 2008 - 2015 The Loon Game Engine Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
* @project loon
* @author cping
* @email:javachenpeng@yahoo.com
* @version 0.5
*/
package loon.html5.gwt;
import com.google.gwt.dom.client.CanvasElement;
import com.google.gwt.dom.client.ImageElement;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import loon.jni.HasArrayBufferView;
import loon.opengl.GL20;
import loon.opengl.GLExt;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.typedarrays.shared.ArrayBufferView;
import com.google.gwt.typedarrays.shared.Float32Array;
import com.google.gwt.typedarrays.shared.Int16Array;
import com.google.gwt.typedarrays.shared.Int32Array;
import com.google.gwt.typedarrays.shared.TypedArrays;
import com.google.gwt.webgl.client.WebGLBuffer;
import com.google.gwt.webgl.client.WebGLFramebuffer;
import com.google.gwt.webgl.client.WebGLProgram;
import com.google.gwt.webgl.client.WebGLRenderbuffer;
import com.google.gwt.webgl.client.WebGLRenderingContext;
import com.google.gwt.webgl.client.WebGLShader;
import com.google.gwt.webgl.client.WebGLTexture;
import com.google.gwt.webgl.client.WebGLUniformLocation;
import com.google.gwt.webgl.client.WebGLActiveInfo;
import static com.google.gwt.webgl.client.WebGLRenderingContext.ARRAY_BUFFER;
import static com.google.gwt.webgl.client.WebGLRenderingContext.BYTE;
import static com.google.gwt.webgl.client.WebGLRenderingContext.COMPILE_STATUS;
import static com.google.gwt.webgl.client.WebGLRenderingContext.ELEMENT_ARRAY_BUFFER;
import static com.google.gwt.webgl.client.WebGLRenderingContext.FLOAT;
import static com.google.gwt.webgl.client.WebGLRenderingContext.INT;
import static com.google.gwt.webgl.client.WebGLRenderingContext.LINK_STATUS;
import static com.google.gwt.webgl.client.WebGLRenderingContext.ONE;
import static com.google.gwt.webgl.client.WebGLRenderingContext.SHORT;
import static com.google.gwt.webgl.client.WebGLRenderingContext.STREAM_DRAW;
import static com.google.gwt.webgl.client.WebGLRenderingContext.UNPACK_PREMULTIPLY_ALPHA_WEBGL;
import static com.google.gwt.webgl.client.WebGLRenderingContext.UNSIGNED_BYTE;
import static com.google.gwt.webgl.client.WebGLRenderingContext.UNSIGNED_SHORT;
public final class GWTGL20 extends GL20 implements GLExt {
// //////////NYI(not yet implemented) method begin
@Override
public void glGetShaderPrecisionFormat(int shadertype, int precisiontype,
IntBuffer range, IntBuffer precision) {
throw new RuntimeException("NYI glGetShaderInfoLog");
}
@Override
public void glGetVertexAttribiv(int index, int pname, IntBuffer params) {
throw new UnsupportedOperationException(
"NYI glGetVertexAttribiv: WebGL getVertexAttribv always returns a float buffer.");
}
@Override
public boolean glIsVBOArrayEnabled() {
throw new RuntimeException("NYI glIsVBOArrayEnabled");
}
@Override
public boolean glIsVBOElementEnabled() {
throw new RuntimeException("NYI glIsVBOElementEnabled");
}
@Override
public ByteBuffer glMapBuffer(int arg0, int arg1) {
throw new RuntimeException("NYI glMapBuffer");
}
@Override
public String getPlatformGLExtensions() {
throw new RuntimeException("NYI getPlatformGLExtensions");
}
@Override
public void glProgramBinary(int arg0, int arg1, Buffer arg2, int arg3) {
throw new RuntimeException("NYI glProgramBinary");
}
@Override
public void glReadPixels(int x, int y, int width, int height, int format,
int type, int pixelsBufferOffset) {
throw new RuntimeException("NYI glReadPixels");
}
@Override
public void glReleaseShaderCompiler() {
throw new RuntimeException("NYI glReleaseShaderCompiler");
}
@Override
public void glShaderBinary(int n, IntBuffer shaders, int binaryformat,
Buffer binary, int length) {
throw new RuntimeException("NYI glReleaseShaderCompiler");
}
@Override
public void glShaderBinary(int n, int[] shaders, int offset,
int binaryformat, Buffer binary, int length) {
throw new RuntimeException("NYI glShaderBinary");
}
@Override
public void glShaderSource(int shader, int count, String[] strings,
IntBuffer length) {
throw new RuntimeException("NYI glShaderSource");
}
@Override
public void glShaderSource(int shader, int count, String[] strings,
int[] length, int lengthOffset) {
throw new RuntimeException("NYI glShaderSource");
}
@Override
public void glTexImage2D(int arg0, int arg1, int arg2, int arg3, int arg4,
int arg5, int arg6, int arg7, int arg8) {
throw new RuntimeException("NYI glTexImage2D");
}
@Override
public void glTexImage3D(int arg0, int arg1, int arg2, int arg3, int arg4,
int arg5, int arg6, int arg7, int arg8, Buffer arg9) {
throw new RuntimeException("NYI glTexImage3D");
}
@Override
public void glTexImage3D(int arg0, int arg1, int arg2, int arg3, int arg4,
int arg5, int arg6, int arg7, int arg8, int arg9) {
throw new RuntimeException("NYI glTexImage3D");
}
@Override
public void glTexSubImage2D(int arg0, int arg1, int arg2, int arg3,
int arg4, int arg5, int arg6, int arg7, int arg8) {
throw new RuntimeException("NYI glTexSubImage2D");
}
@Override
public void glTexSubImage3D(int arg0, int arg1, int arg2, int arg3,
int arg4, int arg5, int arg6, int arg7, int arg8, int arg9,
Buffer arg10) {
throw new RuntimeException("NYI glTexSubImage3D");
}
@Override
public void glTexSubImage3D(int arg0, int arg1, int arg2, int arg3,
int arg4, int arg5, int arg6, int arg7, int arg8, int arg9,
int arg10) {
throw new RuntimeException("NYI glTexSubImage3D");
}
@Override
public boolean isExtensionAvailable(String extension) {
throw new RuntimeException("NYI isExtensionAvailable");
}
@Override
public boolean isFunctionAvailable(String function) {
throw new RuntimeException("NYI isFunctionAvailable");
}
@Override
public void glCompressedTexImage2D(int target, int level,
int internalformat, int width, int height, int border,
int imageSize, Buffer data) {
throw new RuntimeException("NYI glCompressedTexImage2D");
}
@Override
public void glCompressedTexSubImage2D(int target, int level, int xoffset,
int yoffset, int width, int height, int format, int imageSize,
Buffer data) {
throw new RuntimeException("NYI glCompressedTexSubImage2D");
}
@Override
public boolean glUnmapBuffer(int arg0) {
throw new RuntimeException("NYI glUnmapBuffer");
}
@Override
public void glGetFloatv(int pname, FloatBuffer params) {
throw new RuntimeException("NYI glGetFloatv");
}
@Override
public void glGetFramebufferAttachmentParameteriv(int target,
int attachment, int pname, IntBuffer params) {
throw new RuntimeException("NYI glGetFramebufferAttachmentParameteriv");
}
@Override
public void glGetRenderbufferParameteriv(int target, int pname,
IntBuffer params) {
throw new RuntimeException("NYI glGetRenderbufferParameteriv");
}
@Override
public int getSwapInterval() {
throw new RuntimeException("NYI getSwapInterval");
}
@Override
public void glCompressedTexImage3D(int arg0, int arg1, int arg2, int arg3,
int arg4, int arg5, int arg6, int arg7, Buffer arg8) {
throw new RuntimeException("NYI glCompressedTexImage3D");
}
@Override
public void glCompressedTexSubImage3D(int arg0, int arg1, int arg2,
int arg3, int arg4, int arg5, int arg6, int arg7, int arg8,
int arg9, Buffer arg10) {
throw new RuntimeException("NYI glCompressedTexSubImage3D");
}
@Override
public void glCopyTexSubImage3D(int arg0, int arg1, int arg2, int arg3,
int arg4, int arg5, int arg6, int arg7, int arg8) {
throw new RuntimeException("NYI glCopyTexSubImage3D");
}
@Override
public void glFramebufferTexture3D(int target, int attachment,
int textarget, int texture, int level, int zoffset) {
throw new RuntimeException("NYI glFramebufferTexture3D");
}
@Override
public void glGetActiveAttrib(int program, int index, int bufsize,
int[] length, int lengthOffset, int[] size, int sizeOffset,
int[] type, int typeOffset, byte[] name, int nameOffset) {
throw new RuntimeException("NYI glGetActiveAttrib");
}
@Override
public void glGetActiveAttrib(int program, int index, int bufsize,
IntBuffer length, IntBuffer size, IntBuffer type, ByteBuffer name) {
throw new RuntimeException("NYI glGetActiveAttrib");
}
@Override
public void glGetActiveUniform(int program, int index, int bufsize,
int[] length, int lengthOffset, int[] size, int sizeOffset,
int[] type, int typeOffset, byte[] name, int nameOffset) {
throw new RuntimeException("NYI glGetActiveUniform");
}
@Override
public void glGetActiveUniform(int program, int index, int bufsize,
IntBuffer length, IntBuffer size, IntBuffer type, ByteBuffer name) {
throw new RuntimeException("NYI glGetActiveUniform");
}
@Override
public void glGetAttachedShaders(int program, int maxcount, int[] count,
int countOffset, int[] shaders, int shadersOffset) {
throw new RuntimeException("NYI glGetAttachedShaders");
}
@Override
public void glGetAttachedShaders(int program, int maxcount,
IntBuffer count, IntBuffer shaders) {
throw new RuntimeException("NYI glGetAttachedShaders");
}
@Override
public void glGetBooleanv(int pname, ByteBuffer params) {
throw new RuntimeException("NYI glGetBooleanv");
}
@Override
public int glGetBoundBuffer(int arg0) {
throw new RuntimeException("NYI glGetBoundBuffer");
}
@Override
public void glGetProgramBinary(int arg0, int arg1, IntBuffer arg2,
IntBuffer arg3, Buffer arg4) {
throw new RuntimeException("NYI glGetProgramBinary");
}
@Override
public void glGetProgramInfoLog(int program, int bufsize, IntBuffer length,
ByteBuffer infolog) {
throw new RuntimeException("NYI glGetProgramInfoLog");
}
@Override
public void glGetShaderInfoLog(int shader, int bufsize, IntBuffer length,
ByteBuffer infolog) {
throw new RuntimeException("NYI glGetShaderInfoLog");
}
@Override
public void glGetShaderPrecisionFormat(int shadertype, int precisiontype,
int[] range, int rangeOffset, int[] precision, int precisionOffset) {
throw new RuntimeException("NYI glGetShaderPrecisionFormat");
}
@Override
public void glGetShaderSource(int shader, int bufsize, int[] length,
int lengthOffset, byte[] source, int sourceOffset) {
throw new RuntimeException("NYI glGetShaderSource");
}
@Override
public void glGetShaderSource(int shader, int bufsize, IntBuffer length,
ByteBuffer source) {
throw new RuntimeException("NYI glGetShaderSource");
}
@Override
public void glCompressedTexImage2D(int arg0, int arg1, int arg2, int arg3,
int arg4, int arg5, int arg6, int arg7) {
throw new RuntimeException("NYI glCompressedTexImage2D");
}
@Override
public void glCompressedTexImage3D(int arg0, int arg1, int arg2, int arg3,
int arg4, int arg5, int arg6, int arg7, int arg8) {
throw new RuntimeException("NYI glCompressedTexImage3D");
}
@Override
public void glCompressedTexSubImage2D(int arg0, int arg1, int arg2,
int arg3, int arg4, int arg5, int arg6, int arg7, int arg8) {
throw new RuntimeException("NYI glCompressedTexSubImage2D");
}
@Override
public void glCompressedTexSubImage3D(int arg0, int arg1, int arg2,
int arg3, int arg4, int arg5, int arg6, int arg7, int arg8,
int arg9, int arg10) {
throw new RuntimeException("NYI glCompressedTexSubImage3D");
}
// ///////NYI method end
private final static class CacheMap<T extends JavaScriptObject> extends
JavaScriptObject {
protected CacheMap() {
super();
}
public static native <T extends JavaScriptObject> CacheMap<T> create() /*-{
return [ undefined ];
}-*/;
public native T get(int key) /*-{
return this[key];
}-*/;
public native void put(int key, T value) /*-{
this[key] = value;
}-*/;
public native int add(T value) /*-{
this.push(value);
return this.length - 1;
}-*/;
public native T remove(int key) /*-{
var value = this[key];
delete this[key];
return value;
}-*/;
}
static class VertexAttribArrayState {
int type;
int size;
int stride;
boolean normalize;
Buffer nioBuffer;
int nioBufferPosition;
int nioBufferLimit;
WebGLBuffer webGlBuffer;
}
static final int VERTEX_ATTRIB_ARRAY_COUNT = 5;
private final CacheMap<WebGLProgram> programs = CacheMap.create();
private final CacheMap<WebGLShader> shaders = CacheMap.create();
private final CacheMap<WebGLBuffer> buffers = CacheMap.create();
private final CacheMap<WebGLFramebuffer> frameBuffers = CacheMap.create();
private final CacheMap<WebGLRenderbuffer> renderBuffers = CacheMap.create();
private final CacheMap<WebGLTexture> textures = CacheMap.create();
private final CacheMap<CacheMap<WebGLUniformLocation>> uniforms = CacheMap
.create();
private int currProgram = 0;
private int enabledArrays = 0;
private int previouslyEnabledArrays = 0;
private int useNioBuffer = 0;
private VertexAttribArrayState[] vertexAttribArrayState = new VertexAttribArrayState[VERTEX_ATTRIB_ARRAY_COUNT];
private WebGLBuffer elementBuffer;
private WebGLBuffer boundArrayBuffer;
private WebGLBuffer requestedArrayBuffer;
private WebGLBuffer boundElementArrayBuffer;
private WebGLBuffer requestedElementArrayBuffer;
private WebGLRenderingContext glc;
public GWTGL20() {
super(new Buffers() {
public ByteBuffer createByteBuffer(int size) {
ByteBuffer buffer = ByteBuffer.allocateDirect(size);
buffer.order(ByteOrder.nativeOrder());
return buffer;
}
}, GWTUrl.checkGLErrors);
}
public Float32Array copy(FloatBuffer buffer) {
return ((Float32Array) ((HasArrayBufferView) buffer).getTypedArray())
.subarray(buffer.position(), buffer.remaining());
}
public Int16Array copy(ShortBuffer buffer) {
return ((Int16Array) ((HasArrayBufferView) buffer).getTypedArray())
.subarray(buffer.position(), buffer.remaining());
}
public Int32Array copy(IntBuffer buffer) {
return ((Int32Array) ((HasArrayBufferView) buffer).getTypedArray())
.subarray(buffer.position(), buffer.remaining());
}
private static int getElementSize(Buffer buffer) {
if ((buffer instanceof FloatBuffer) || (buffer instanceof IntBuffer))
return 4;
else if (buffer instanceof ShortBuffer)
return 2;
else if (buffer instanceof ByteBuffer)
return 1;
else
throw new RuntimeException("Unrecognized buffer type: "
+ buffer.getClass());
}
private ArrayBufferView getTypedArray(Buffer buffer, int type, int byteSize) {
if (!(buffer instanceof HasArrayBufferView)) {
throw new RuntimeException("Native buffer required " + buffer);
}
HasArrayBufferView arrayHolder = (HasArrayBufferView) buffer;
int bufferElementSize = arrayHolder.getElementSize();
ArrayBufferView webGLArray = arrayHolder.getTypedArray();
if (byteSize == -1) {
byteSize = buffer.remaining() * bufferElementSize;
}
if (byteSize == buffer.capacity() * bufferElementSize
&& type == arrayHolder.getElementType()) {
return webGLArray;
}
int byteOffset = webGLArray.byteOffset() + buffer.position()
* bufferElementSize;
switch (type) {
case FLOAT:
return TypedArrays.createFloat32Array(webGLArray.buffer(),
byteOffset, byteSize / 4);
case UNSIGNED_BYTE:
return TypedArrays.createUint8Array(webGLArray.buffer(),
byteOffset, byteSize);
case UNSIGNED_SHORT:
return TypedArrays.createUint16Array(webGLArray.buffer(),
byteOffset, byteSize / 2);
case INT:
return TypedArrays.createInt32Array(webGLArray.buffer(),
byteOffset, byteSize / 4);
case SHORT:
return TypedArrays.createInt16Array(webGLArray.buffer(),
byteOffset, byteSize / 2);
case BYTE:
return TypedArrays.createInt8Array(webGLArray.buffer(), byteOffset,
byteSize);
default:
throw new IllegalArgumentException("Type: " + type);
}
}
private int getTypeSize(int type) {
switch (type) {
case GL_FLOAT:
case GL_INT:
return 4;
case GL_SHORT:
case GL_UNSIGNED_SHORT:
return 2;
case GL_BYTE:
case GL_UNSIGNED_BYTE:
return 1;
default:
throw new IllegalArgumentException();
}
}
private WebGLUniformLocation getUniformLocation(int location) {
return uniforms.get(currProgram).get(location);
}
void init(WebGLRenderingContext glc) {
glc.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, ONE);
this.glc = glc;
elementBuffer = glc.createBuffer();
for (int ii = 0; ii < VERTEX_ATTRIB_ARRAY_COUNT; ii++) {
VertexAttribArrayState data = new VertexAttribArrayState();
data.webGlBuffer = glc.createBuffer();
vertexAttribArrayState[ii] = data;
}
}
protected void prepareDraw() {
VertexAttribArrayState previousNio = null;
int previousElementSize = 0;
if (useNioBuffer == 0 && enabledArrays == previouslyEnabledArrays) {
return;
}
for (int i = 0; i < VERTEX_ATTRIB_ARRAY_COUNT; i++) {
int mask = 1 << i;
int enabled = enabledArrays & mask;
if (enabled != (previouslyEnabledArrays & mask)) {
if (enabled != 0) {
glc.enableVertexAttribArray(i);
} else {
glc.disableVertexAttribArray(i);
}
}
if (enabled != 0 && (useNioBuffer & mask) != 0) {
VertexAttribArrayState data = vertexAttribArrayState[i];
if (previousNio != null
&& previousNio.nioBuffer == data.nioBuffer
&& previousNio.nioBufferLimit >= data.nioBufferLimit) {
if (boundArrayBuffer != previousNio.webGlBuffer) {
glc.bindBuffer(ARRAY_BUFFER, previousNio.webGlBuffer);
boundArrayBuffer = data.webGlBuffer;
}
glc.vertexAttribPointer(i, data.size, data.type,
data.normalize, data.stride, data.nioBufferPosition
* previousElementSize);
} else {
if (boundArrayBuffer != data.webGlBuffer) {
glc.bindBuffer(ARRAY_BUFFER, data.webGlBuffer);
boundArrayBuffer = data.webGlBuffer;
}
int elementSize = getElementSize(data.nioBuffer);
int savePosition = data.nioBuffer.position();
if (data.nioBufferPosition * elementSize < data.stride) {
data.nioBuffer.position(0);
glc.bufferData(
ARRAY_BUFFER,
getTypedArray(data.nioBuffer, data.type,
data.nioBufferLimit * elementSize),
STREAM_DRAW);
glc.vertexAttribPointer(i, data.size, data.type,
data.normalize, data.stride,
data.nioBufferPosition * elementSize);
previousNio = data;
previousElementSize = elementSize;
} else {
data.nioBuffer.position(data.nioBufferPosition);
glc.bufferData(
ARRAY_BUFFER,
getTypedArray(
data.nioBuffer,
data.type,
(data.nioBufferLimit - data.nioBufferPosition)
* elementSize), STREAM_DRAW);
glc.vertexAttribPointer(i, data.size, data.type,
data.normalize, data.stride, 0);
}
data.nioBuffer.position(savePosition);
}
}
}
previouslyEnabledArrays = enabledArrays;
}
@Override
public void glActiveTexture(int texture) {
glc.activeTexture(texture);
}
@Override
public void glAttachShader(int program, int shader) {
WebGLProgram glProgram = programs.get(program);
WebGLShader glShader = shaders.get(shader);
glc.attachShader(glProgram, glShader);
}
@Override
public void glBindAttribLocation(int program, int index, String name) {
WebGLProgram glProgram = programs.get(program);
glc.bindAttribLocation(glProgram, index, name);
}
@Override
public void glBindBuffer(int target, int buffer) {
WebGLBuffer webGlBuf = buffers.get(buffer);
if (target == GL_ARRAY_BUFFER) {
requestedArrayBuffer = webGlBuf;
} else if (target == GL_ELEMENT_ARRAY_BUFFER) {
requestedElementArrayBuffer = webGlBuf;
} else {
glc.bindBuffer(target, webGlBuf);
}
}
@Override
public void glBindFramebuffer(int target, int framebuffer) {
glc.bindFramebuffer(target, frameBuffers.get(framebuffer));
}
@Override
public void glBindRenderbuffer(int target, int renderbuffer) {
glc.bindRenderbuffer(target, renderBuffers.get(renderbuffer));
}
@Override
public void glBindTexture(int target, int texture) {
glc.bindTexture(target, textures.get(texture));
}
@Override
public void glBlendColor(float red, float green, float blue, float alpha) {
glc.blendColor(red, green, blue, alpha);
}
@Override
public void glBlendEquation(int mode) {
glc.blendEquation(mode);
}
@Override
public void glBlendEquationSeparate(int modeRGB, int modeAlpha) {
glc.blendEquationSeparate(modeRGB, modeAlpha);
}
@Override
public void glBlendFunc(int sfactor, int dfactor) {
glc.blendFunc(sfactor, dfactor);
}
@Override
public void glBlendFuncSeparate(int srcRGB, int dstRGB, int srcAlpha,
int dstAlpha) {
glc.blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
}
@Override
public void glBufferData(int target, int byteSize, Buffer data, int usage) {
if (target == GL_ARRAY_BUFFER) {
if (requestedArrayBuffer != boundArrayBuffer) {
glc.bindBuffer(target, requestedArrayBuffer);
boundArrayBuffer = requestedArrayBuffer;
}
} else if (target == GL_ELEMENT_ARRAY_BUFFER) {
if (requestedElementArrayBuffer != boundElementArrayBuffer) {
glc.bindBuffer(target, requestedElementArrayBuffer);
boundElementArrayBuffer = requestedElementArrayBuffer;
}
}
glc.bufferData(target, getTypedArray(data, GL_BYTE, byteSize), usage);
}
@Override
public void glBufferSubData(int target, int offset, int size, Buffer data) {
if (target == GL_ARRAY_BUFFER
&& requestedArrayBuffer != boundArrayBuffer) {
glc.bindBuffer(target, requestedArrayBuffer);
boundArrayBuffer = requestedArrayBuffer;
}
throw new RuntimeException("NYI glBufferSubData");
}
@Override
public int glCheckFramebufferStatus(int target) {
return glc.checkFramebufferStatus(target);
}
@Override
public final void glClear(int mask) {
glc.clear(mask);
}
@Override
public final void glClearColor(float red, float green, float blue,
float alpha) {
glc.clearColor(red, green, blue, alpha);
}
@Override
public void glClearDepth(double depth) {
glc.clearDepth((float) depth);
}
@Override
public void glClearDepthf(float depth) {
glc.clearDepth(depth);
}
@Override
public void glClearStencil(int s) {
glc.clearStencil(s);
}
@Override
public void glColorMask(boolean red, boolean green, boolean blue,
boolean alpha) {
glc.colorMask(red, green, blue, alpha);
}
@Override
public void glCompileShader(int shader) {
WebGLShader glShader = shaders.get(shader);
glc.compileShader(glShader);
}
@Override
public void glCopyTexImage2D(int target, int level, int internalformat,
int x, int y, int width, int height, int border) {
glc.copyTexImage2D(target, level, internalformat, x, y, width, height,
border);
}
@Override
public void glCopyTexSubImage2D(int target, int level, int xoffset,
int yoffset, int x, int y, int width, int height) {
glc.copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width,
height);
}
@Override
public int glCreateProgram() {
WebGLProgram program = glc.createProgram();
return programs.add(program);
}
@Override
public int glCreateShader(int type) {
WebGLShader shader = glc.createShader(type);
return shaders.add(shader);
}
@Override
public final void glCullFace(int mode) {
glc.cullFace(mode);
}
@Override
public void glDeleteBuffers(int n, IntBuffer buffers) {
int pos = buffers.position();
for (int i = 0; i < n; i++) {
int id = buffers.get(pos + i);
WebGLBuffer buffer = this.buffers.remove(id);
glc.deleteBuffer(buffer);
}
}
@Override
public void glDeleteBuffers(int n, int[] buffers, int offset) {
for (int i = 0; i < n; i++) {
int id = buffers[i + offset];
WebGLBuffer buffer = this.buffers.remove(id);
glc.deleteBuffer(buffer);
}
}
@Override
public void glDeleteFramebuffers(int n, IntBuffer framebuffers) {
int pos = framebuffers.position();
for (int i = 0; i < n; i++) {
int id = framebuffers.get(pos + i);
WebGLFramebuffer fb = this.frameBuffers.remove(id);
glc.deleteFramebuffer(fb);
}
}
@Override
public void glDeleteFramebuffers(int n, int[] framebuffers, int offset) {
for (int i = 0; i < n; i++) {
int id = framebuffers[i + offset];
WebGLFramebuffer fb = this.frameBuffers.remove(id);
glc.deleteFramebuffer(fb);
}
}
@Override
public void glDeleteProgram(int program) {
WebGLProgram prog = programs.remove(program);
glc.deleteProgram(prog);
}
@Override
public void glDeleteRenderbuffers(int n, IntBuffer renderbuffers) {
int pos = renderbuffers.position();
for (int i = 0; i < n; i++) {
int id = renderbuffers.get(pos + i);
WebGLRenderbuffer rb = this.renderBuffers.remove(id);
glc.deleteRenderbuffer(rb);
}
}
@Override
public void glDeleteRenderbuffers(int n, int[] renderbuffers, int offset) {
for (int i = 0; i < n; i++) {
int id = renderbuffers[i + offset];
WebGLRenderbuffer rb = this.renderBuffers.remove(id);
glc.deleteRenderbuffer(rb);
}
}
@Override
public void glDeleteShader(int shader) {
WebGLShader sh = shaders.remove(shader);
glc.deleteShader(sh);
}
@Override
public void glDeleteTextures(int n, IntBuffer textures) {
int pos = textures.position();
for (int i = 0; i < n; i++) {
int id = textures.get(pos + i);
WebGLTexture texture = this.textures.remove(id);
glc.deleteTexture(texture);
}
}
@Override
public void glDeleteTextures(int n, int[] textures, int offset) {
for (int i = 0; i < n; i++) {
int id = textures[i + offset];
WebGLTexture texture = this.textures.remove(id);
glc.deleteTexture(texture);
}
}
@Override
public void glDepthFunc(int func) {
glc.depthFunc(func);
}
@Override
public void glDepthMask(boolean flag) {
glc.depthMask(flag);
}
@Override
public void glDepthRange(double zNear, double zFar) {
glc.depthRange((float) zNear, (float) zFar);
}
@Override
public void glDepthRangef(float zNear, float zFar) {
glc.depthRange(zNear, zFar);
}
@Override
public void glDetachShader(int program, int shader) {
glc.detachShader(programs.get(program), shaders.get(shader));
}
@Override
public void glDisable(int cap) {
glc.disable(cap);
}
@Override
public void glDisableVertexAttribArray(int index) {
enabledArrays &= ~(1 << index);
}
@Override
public void glDrawArrays(int mode, int first, int count) {
prepareDraw();
glc.drawArrays(mode, first, count);
}
@Override
public void glDrawElements(int mode, int count, int type, Buffer indices) {
prepareDraw();
if (boundElementArrayBuffer != elementBuffer) {
glc.bindBuffer(ELEMENT_ARRAY_BUFFER, elementBuffer);
boundElementArrayBuffer = elementBuffer;
}
glc.bufferData(ELEMENT_ARRAY_BUFFER,
getTypedArray(indices, type, count * getTypeSize(type)),
STREAM_DRAW);
glc.drawElements(mode, count, type, 0);
}
@Override
public void glDrawElements(int mode, int count, int type, int indices) {
prepareDraw();
if (requestedElementArrayBuffer != boundElementArrayBuffer) {
glc.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, requestedElementArrayBuffer);
boundElementArrayBuffer = requestedElementArrayBuffer;
}
glc.drawElements(mode, count, type, indices);
}
@Override
public void glEnable(int cap) {
glc.enable(cap);
}
@Override
public void glEnableVertexAttribArray(int index) {
enabledArrays |= (1 << index);
}
@Override
public void glFinish() {
glc.finish();
}
@Override
public void glFlush() {
glc.flush();
}
@Override
public void glFramebufferRenderbuffer(int target, int attachment,
int renderbuffertarget, int renderbuffer) {
glc.framebufferRenderbuffer(target, attachment, renderbuffertarget,
renderBuffers.get(renderbuffer));
}
@Override
public void glFramebufferTexture2D(int target, int attachment,
int textarget, int texture, int level) {
glc.framebufferTexture2D(target, attachment, textarget,
textures.get(texture), level);
}
@Override
public void glFrontFace(int mode) {
glc.frontFace(mode);
}
@Override
public int glGenBuffer() {
WebGLBuffer buffer = glc.createBuffer();
return buffers.add(buffer);
}
@Override
public void glGenBuffers(int n, IntBuffer buffers) {
int pos = buffers.position();
for (int i = 0; i < n; i++) {
WebGLBuffer buffer = glc.createBuffer();
int id = this.buffers.add(buffer);
buffers.put(pos + i, id);
}
}
@Override
public void glGenBuffers(int n, int[] buffers, int offset) {
for (int i = 0; i < n; i++) {
WebGLBuffer buffer = glc.createBuffer();
int id = this.buffers.add(buffer);
buffers[i + offset] = id;
}
}
@Override
public void glGenerateMipmap(int target) {
glc.generateMipmap(target);
}
@Override
public void glGenFramebuffers(int n, IntBuffer framebuffers) {
int pos = framebuffers.position();
for (int i = 0; i < n; i++) {
WebGLFramebuffer fb = glc.createFramebuffer();
int id = this.frameBuffers.add(fb);
framebuffers.put(pos + i, id);
}
}
@Override
public void glGenFramebuffers(int n, int[] framebuffers, int offset) {
for (int i = 0; i < n; i++) {
WebGLFramebuffer fb = glc.createFramebuffer();
int id = this.frameBuffers.add(fb);
framebuffers[i + offset] = id;
}
}
@Override
public void glGenRenderbuffers(int n, IntBuffer renderbuffers) {
int pos = renderbuffers.position();
for (int i = 0; i < n; i++) {
WebGLRenderbuffer rb = glc.createRenderbuffer();
int id = this.renderBuffers.add(rb);
renderbuffers.put(pos + i, id);
}
}
@Override
public void glGenRenderbuffers(int n, int[] renderbuffers, int offset) {
for (int i = 0; i < n; i++) {
WebGLRenderbuffer rb = glc.createRenderbuffer();
int id = this.renderBuffers.add(rb);
renderbuffers[i + offset] = id;
}
}
@Override
public void glGenTextures(int n, IntBuffer textures) {
int pos = textures.position();
for (int i = 0; i < n; i++) {
WebGLTexture texture = glc.createTexture();
int id = this.textures.add(texture);
textures.put(pos + i, id);
}
}
@Override
public void glGenTextures(int n, int[] textures, int offset) {
for (int i = 0; i < n; i++) {
WebGLTexture texture = glc.createTexture();
int id = this.textures.add(texture);
textures[i + offset] = id;
}
}
@Override
public String glGetActiveAttrib(int program, int index, IntBuffer size,
Buffer type) {
WebGLActiveInfo activeAttrib = glc.getActiveAttrib(
programs.get(program), index);
size.put(activeAttrib.getSize());
((IntBuffer) type).put(activeAttrib.getType());
return activeAttrib.getName();
}
@Override
public String glGetActiveUniform(int program, int index, IntBuffer size,
Buffer type) {
WebGLActiveInfo activeUniform = glc.getActiveUniform(
programs.get(program), index);
size.put(activeUniform.getSize());
((IntBuffer) type).put(activeUniform.getType());
return activeUniform.getName();
}
@Override
public int glGetAttribLocation(int program, String name) {
WebGLProgram prog = programs.get(program);
return glc.getAttribLocation(prog, name);
}
@Override
public boolean glGetBoolean(int pname) {
return glc.getParameterb(pname);
}
@Override
public void glGetBufferParameteriv(int target, int pname, IntBuffer params) {
params.put(params.position(), glc.getBufferParameter(target, pname));
}
@Override
public final int glGetError() {
return glc.getError();
}
@Override
public int glGetInteger(int pname) {
return glc.getParameteri(pname);
}
@Override
public void glGetIntegerv(int pname, IntBuffer params) {
Int32Array result = (Int32Array) glc.getParameterv(pname);
int pos = params.position();
int len = result.length();
for (int i = 0; i < len; i++) {
params.put(pos + i, result.get(i));
}
}
@Override
public float glGetFloat(int pname) {
return glc.getParameterf(pname);
}
@Override
public void glGetProgramiv(int program, int pname, IntBuffer params) {
if (pname == GL20.GL_DELETE_STATUS || pname == GL20.GL_LINK_STATUS
|| pname == GL20.GL_VALIDATE_STATUS) {
boolean result = glc.getProgramParameterb(programs.get(program),
pname);
params.put(result ? GL20.GL_TRUE : GL20.GL_FALSE);
} else {
params.put(glc.getProgramParameteri(programs.get(program), pname));
}
}
@Override
public String glGetProgramInfoLog(int program) {
return glc.getProgramInfoLog(programs.get(program));
}
@Override
public void glGetProgramiv(int program, int pname, int[] params, int offset) {
if (pname == GL_LINK_STATUS)
params[offset] = glc.getProgramParameterb(programs.get(program),
LINK_STATUS) ? GL_TRUE : GL_FALSE;
else
throw new RuntimeException("NYI glGetProgramiv: " + pname);
}
@Override
public void glGetShaderiv(int shader, int pname, IntBuffer params) {
if (pname == GL_COMPILE_STATUS) {
params.put(glc.getShaderParameterb(shaders.get(shader),
COMPILE_STATUS) ? GL_TRUE : GL_FALSE);
} else {
throw new RuntimeException("NYI glGetShaderiv: " + pname);
}
}
@Override
public String glGetShaderInfoLog(int shader) {
return glc.getShaderInfoLog(shaders.get(shader));
}
@Override
public String glGetString(int id) {
return glc.getParameterString(id);
}
@Override
public void glGetTexParameterfv(int target, int pname, FloatBuffer params) {
params.put(params.position(), glc.getTexParameter(target, pname));
}
@Override
public void glGetTexParameteriv(int target, int pname, IntBuffer params) {
params.put(params.position(), glc.getTexParameter(target, pname));
}
@Override
public void glGetUniformfv(int program, int location, FloatBuffer params) {
Float32Array v = glc.getUniformv(programs.get(program),
uniforms.get(program).get(location));
for (int i = 0; i < v.length(); i++) {
params.put(params.position() + i, v.get(i));
}
}
@Override
public void glGetUniformiv(int program, int location, IntBuffer params) {
Int32Array v = glc.getUniformv(programs.get(program),
uniforms.get(program).get(location));
for (int i = 0; i < v.length(); i++) {
params.put(params.position() + i, v.get(i));
}
}
@Override
public int glGetUniformLocation(int program, String name) {
WebGLUniformLocation location = glc.getUniformLocation(
programs.get(program), name);
CacheMap<WebGLUniformLocation> progUniforms = uniforms.get(program);
if (progUniforms == null) {
progUniforms = CacheMap.<WebGLUniformLocation> create();
uniforms.put(program, progUniforms);
}
int id = progUniforms.add(location);
return id;
}
@Override
public void glGetVertexAttribfv(int index, int pname, FloatBuffer params) {
Float32Array v = glc.getVertexAttribv(index, pname);
for (int i = 0; i < v.length(); i++) {
params.put(params.position() + i, v.get(i));
}
}
@Override
public void glHint(int target, int mode) {
glc.hint(target, mode);
}
@Override
public boolean glIsBuffer(int buffer) {
return glc.isBuffer(buffers.get(buffer));
}
@Override
public boolean glIsEnabled(int cap) {
return glc.isEnabled(cap);
}
@Override
public boolean glIsFramebuffer(int framebuffer) {
return glc.isFramebuffer(frameBuffers.get(framebuffer));
}
@Override
public boolean glIsProgram(int program) {
return glc.isProgram(programs.get(program));
}
@Override
public boolean glIsRenderbuffer(int renderbuffer) {
return glc.isRenderbuffer(renderBuffers.get(renderbuffer));
}
@Override
public boolean glIsShader(int shader) {
return glc.isShader(shaders.get(shader));
}
@Override
public boolean glIsTexture(int texture) {
return glc.isTexture(textures.get(texture));
}
@Override
public void glLineWidth(float width) {
glc.lineWidth(width);
}
@Override
public void glLinkProgram(int program) {
glc.linkProgram(programs.get(program));
}
@Override
public void glPixelStorei(int i, int j) {
glc.pixelStorei(i, j);
}
@Override
public void glPolygonOffset(float factor, float units) {
glc.polygonOffset(factor, units);
}
@Override
public void glReadPixels(int x, int y, int width, int height, int format,
int type, Buffer pixels) {
glc.readPixels(x, y, width, height, format, type,
getTypedArray(pixels, type, -1));
}
@Override
public void glRenderbufferStorage(int target, int internalformat,
int width, int height) {
glc.renderbufferStorage(target, internalformat, width, height);
}
@Override
public void glSampleCoverage(float value, boolean invert) {
glc.sampleCoverage(value, invert);
}
@Override
public final void glScissor(int x, int y, int width, int height) {
glc.scissor(x, y, width, height);
}
@Override
public void glShaderSource(int shader, String string) {
glc.shaderSource(shaders.get(shader), string);
}
@Override
public void glStencilFunc(int func, int ref, int mask) {
glc.stencilFunc(func, ref, mask);
}
@Override
public void glStencilFuncSeparate(int face, int func, int ref, int mask) {
glc.stencilFuncSeparate(face, func, ref, mask);
}
@Override
public void glStencilMask(int mask) {
glc.stencilMask(mask);
}
@Override
public void glStencilMaskSeparate(int face, int mask) {
glc.stencilMaskSeparate(face, mask);
}
@Override
public void glStencilOp(int fail, int zfail, int zpass) {
glc.stencilOp(fail, zfail, zpass);
}
@Override
public void glStencilOpSeparate(int face, int fail, int zfail, int zpass) {
glc.stencilOpSeparate(face, fail, zfail, zpass);
}
@Override
public void glTexImage2D(int target, int level, int internalformat,
int width, int height, int border, int format, int type,
Buffer pixels) {
ArrayBufferView buffer = (pixels == null) ? null : getTypedArray(
pixels, type, -1);
glc.texImage2D(target, level, internalformat, width, height, border,
format, type, buffer);
}
public void glTexImage2D(int target, int level, int internalformat,
int format, int type, ImageElement image) {
glc.texImage2D(target, level, internalformat, format, type, image);
checkError("texImage2D");
}
public void glTexImage2D(int target, int level, int internalformat,
int format, int type, CanvasElement image) {
glc.texImage2D(target, level, internalformat, format, type, image);
checkError("texImage2D");
}
@Override
public void glTexParameteri(int glTexture2d, int glTextureMinFilter,
int glFilterMin) {
glc.texParameteri(glTexture2d, glTextureMinFilter, glFilterMin);
}
@Override
public void glTexParameterf(int target, int pname, float param) {
glc.texParameterf(target, pname, param);
}
@Override
public void glTexParameterfv(int target, int pname, FloatBuffer params) {
glc.texParameterf(target, pname, params.get());
}
@Override
public void glTexParameteriv(int target, int pname, IntBuffer params) {
glc.texParameterf(target, pname, params.get());
}
@Override
public void glTexSubImage2D(int target, int level, int xoffset,
int yoffset, int width, int height, int format, int type,
Buffer pixels) {
glc.texSubImage2D(target, level, xoffset, yoffset, width, height,
format, type, getTypedArray(pixels, type, -1));
}
@Override
public void glUniform1f(int location, float x) {
glc.uniform1f(getUniformLocation(location), x);
}
@Override
public void glUniform1fv(int location, int count, FloatBuffer v) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniform1fv(loc, copy(v));
}
@Override
public void glUniform1i(int location, int x) {
glc.uniform1i(getUniformLocation(location), x);
}
@Override
public void glUniform1iv(int location, int count, IntBuffer v) {
glc.uniform1iv(getUniformLocation(location),
(Int32Array) getTypedArray(v, GL_INT, count * 4));
}
@Override
public void glUniform2f(int location, float x, float y) {
glc.uniform2f(getUniformLocation(location), x, y);
}
@Override
public void glUniform2fv(int location, int count, FloatBuffer v) {
glc.uniform2fv(getUniformLocation(location),
(Float32Array) getTypedArray(v, GL_FLOAT, count * 2 * 4));
}
@Override
public void glUniform2i(int location, int x, int y) {
glc.uniform2i(getUniformLocation(location), x, y);
}
@Override
public void glUniform2iv(int location, int count, IntBuffer v) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniform2iv(loc, copy(v));
}
@Override
public void glUniform2iv(int location, int count, int[] v, int offset) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniform2iv(loc, v);
}
@Override
public void glUniform3f(int location, float x, float y, float z) {
glc.uniform3f(getUniformLocation(location), x, y, z);
}
@Override
public void glUniform3fv(int location, int count, FloatBuffer v) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniform3fv(loc, copy(v));
}
@Override
public void glUniform3fv(int location, int count, float[] v, int offset) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniform3fv(loc, v);
}
@Override
public void glUniform3i(int location, int x, int y, int z) {
glc.uniform3i(getUniformLocation(location), x, y, z);
}
@Override
public void glUniform3iv(int location, int count, IntBuffer v) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniform3iv(loc, copy(v));
}
@Override
public void glUniform3iv(int location, int count, int[] v, int offset) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniform3iv(loc, v);
}
@Override
public void glUniform4f(int location, float x, float y, float z, float w) {
glc.uniform4f(getUniformLocation(location), x, y, z, w);
}
@Override
public void glUniform4fv(int location, int count, FloatBuffer v) {
glc.uniform4fv(getUniformLocation(location),
(Float32Array) getTypedArray(v, GL_FLOAT, 4 * 4 * count));
}
@Override
public void glUniform4i(int location, int x, int y, int z, int w) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniform4i(loc, x, y, z, w);
}
@Override
public void glUniform4iv(int location, int count, IntBuffer v) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniform4iv(loc, copy(v));
}
@Override
public void glUniform4iv(int location, int count, int[] v, int offset) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniform4iv(loc, v);
}
@Override
public void glUniformMatrix2fv(int location, int count, boolean transpose,
FloatBuffer value) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniformMatrix2fv(loc, transpose, copy(value));
}
@Override
public void glUniformMatrix2fv(int location, int count, boolean transpose,
float[] value, int offset) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniformMatrix2fv(loc, transpose, value);
}
@Override
public void glUniformMatrix3fv(int location, int count, boolean transpose,
FloatBuffer value) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniformMatrix3fv(loc, transpose, copy(value));
}
@Override
public void glUniformMatrix3fv(int location, int count, boolean transpose,
float[] value, int offset) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniformMatrix3fv(loc, transpose, value);
}
@Override
public void glUniformMatrix4fv(int location, int count, boolean transpose,
FloatBuffer value) {
glc.uniformMatrix4fv(getUniformLocation(location), transpose,
(Float32Array) getTypedArray(value, GL_FLOAT, count * 16 * 4));
}
@Override
public void glUseProgram(int program) {
currProgram = program;
glc.useProgram(programs.get(program));
}
@Override
public void glValidateProgram(int program) {
glc.validateProgram(programs.get(program));
}
@Override
public void glVertexAttrib1f(int indx, float x) {
glc.vertexAttrib1f(indx, x);
}
@Override
public void glVertexAttrib1fv(int indx, FloatBuffer values) {
glc.vertexAttrib1fv(indx, copy(values));
}
@Override
public void glVertexAttrib2f(int indx, float x, float y) {
glc.vertexAttrib2f(indx, x, y);
}
@Override
public void glVertexAttrib2fv(int indx, FloatBuffer values) {
glc.vertexAttrib2fv(indx, copy(values));
}
@Override
public void glVertexAttrib3f(int indx, float x, float y, float z) {
glc.vertexAttrib3f(indx, x, y, z);
}
@Override
public void glVertexAttrib3fv(int indx, FloatBuffer values) {
glc.vertexAttrib3fv(indx, copy(values));
}
@Override
public void glVertexAttrib4f(int indx, float x, float y, float z, float w) {
glc.vertexAttrib4f(indx, x, y, z, w);
}
@Override
public void glVertexAttrib4fv(int indx, FloatBuffer values) {
glc.vertexAttrib4fv(indx, copy(values));
}
@Override
public void glVertexAttribPointer(int arrayId, int size, int type,
boolean normalize, int byteStride, Buffer nioBuffer) {
VertexAttribArrayState data = vertexAttribArrayState[arrayId];
useNioBuffer |= 1 << arrayId;
data.nioBuffer = nioBuffer;
data.nioBufferPosition = nioBuffer.position();
data.nioBufferLimit = nioBuffer.limit();
data.size = size;
data.type = type;
data.normalize = normalize;
data.stride = byteStride == 0 ? size * getTypeSize(type) : byteStride;
}
@Override
public void glVertexAttribPointer(int indx, int size, int type,
boolean normalized, int stride, int ptr) {
useNioBuffer &= ~(1 << indx);
if (boundArrayBuffer != requestedArrayBuffer) {
glc.bindBuffer(GL_ARRAY_BUFFER, requestedArrayBuffer);
boundArrayBuffer = requestedArrayBuffer;
}
glc.vertexAttribPointer(indx, size, type, normalized, stride, ptr);
}
@Override
public void glViewport(int x, int y, int w, int h) {
glc.viewport(x, y, w, h);
}
@Override
public boolean hasGLSL() {
return true;
}
@Override
public void glGetShaderiv(int shader, int pname, int[] params, int offset) {
if (pname == GL_COMPILE_STATUS)
params[offset] = glc.getShaderParameterb(shaders.get(shader),
COMPILE_STATUS) ? GL_TRUE : GL_FALSE;
else
throw new RuntimeException("NYI glGetShaderiv: " + pname);
}
@Override
public void glUniform1fv(int location, int count, float[] v, int offset) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniform1fv(loc, v);
}
@Override
public void glUniform1iv(int location, int count, int[] v, int offset) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniform1iv(loc, v);
}
@Override
public void glUniform2fv(int location, int count, float[] v, int offset) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniform2fv(loc, v);
}
@Override
public void glUniform4fv(int location, int count, float[] v, int offset) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniform4fv(loc, v);
}
@Override
public void glUniformMatrix4fv(int location, int count, boolean transpose,
float[] value, int offset) {
WebGLUniformLocation loc = getUniformLocation(location);
glc.uniformMatrix4fv(loc, transpose, value);
}
}