use of com.jme3.renderer.RendererException in project jmonkeyengine by jMonkeyEngine.
the class GLRenderer method updateTexImageData.
/**
* Uploads the given image to the GL driver.
*
* @param img The image to upload
* @param type How the data in the image argument should be interpreted.
* @param unit The texture slot to be used to upload the image, not important
* @param scaleToPot If true, the image will be scaled to power-of-2 dimensions
* before being uploaded.
*/
public void updateTexImageData(Image img, Texture.Type type, int unit, boolean scaleToPot) {
int texId = img.getId();
if (texId == -1) {
// create texture
gl.glGenTextures(intBuf1);
texId = intBuf1.get(0);
img.setId(texId);
objManager.registerObject(img);
statistics.onNewTexture();
}
// bind texture
int target = convertTextureType(type, img.getMultiSamples(), -1);
bindTextureAndUnit(target, img, unit);
if (!img.hasMipmaps() && img.isGeneratedMipmapsRequired()) {
if (!caps.contains(Caps.FrameBuffer) && gl2 != null) {
gl2.glTexParameteri(target, GL2.GL_GENERATE_MIPMAP, GL.GL_TRUE);
img.setMipmapsGenerated(true);
} else {
// For OpenGL3 and up.
// We'll generate mipmaps via glGenerateMipmapEXT (see below)
}
} else if (img.hasMipmaps()) {
// Image already has mipmaps, set the max level based on the
// number of mipmaps we have.
gl.glTexParameteri(target, GL.GL_TEXTURE_MAX_LEVEL, img.getMipMapSizes().length - 1);
} else {
// Image does not have mipmaps and they are not required.
// Specify that that the texture has no mipmaps.
gl.glTexParameteri(target, GL.GL_TEXTURE_MAX_LEVEL, 0);
}
int imageSamples = img.getMultiSamples();
if (imageSamples > 1) {
if (img.getFormat().isDepthFormat()) {
img.setMultiSamples(Math.min(limits.get(Limits.DepthTextureSamples), imageSamples));
} else {
img.setMultiSamples(Math.min(limits.get(Limits.ColorTextureSamples), imageSamples));
}
}
// Check if graphics card doesn't support multisample textures
if (!caps.contains(Caps.TextureMultisample)) {
if (img.getMultiSamples() > 1) {
throw new RendererException("Multisample textures are not supported by the video hardware");
}
}
// Check if graphics card doesn't support depth textures
if (img.getFormat().isDepthFormat() && !caps.contains(Caps.DepthTexture)) {
throw new RendererException("Depth textures are not supported by the video hardware");
}
if (target == GL.GL_TEXTURE_CUBE_MAP) {
// Check max texture size before upload
int cubeSize = limits.get(Limits.CubemapSize);
if (img.getWidth() > cubeSize || img.getHeight() > cubeSize) {
throw new RendererException("Cannot upload cubemap " + img + ". The maximum supported cubemap resolution is " + cubeSize);
}
if (img.getWidth() != img.getHeight()) {
throw new RendererException("Cubemaps must have square dimensions");
}
} else {
int texSize = limits.get(Limits.TextureSize);
if (img.getWidth() > texSize || img.getHeight() > texSize) {
throw new RendererException("Cannot upload texture " + img + ". The maximum supported texture resolution is " + texSize);
}
}
Image imageForUpload;
if (scaleToPot) {
imageForUpload = MipMapGenerator.resizeToPowerOf2(img);
} else {
imageForUpload = img;
}
if (target == GL.GL_TEXTURE_CUBE_MAP) {
List<ByteBuffer> data = imageForUpload.getData();
if (data.size() != 6) {
logger.log(Level.WARNING, "Invalid texture: {0}\n" + "Cubemap textures must contain 6 data units.", img);
return;
}
for (int i = 0; i < 6; i++) {
texUtil.uploadTexture(imageForUpload, GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, i, linearizeSrgbImages);
}
} else if (target == GLExt.GL_TEXTURE_2D_ARRAY_EXT) {
if (!caps.contains(Caps.TextureArray)) {
throw new RendererException("Texture arrays not supported by graphics hardware");
}
List<ByteBuffer> data = imageForUpload.getData();
// -1 index specifies prepare data for 2D Array
texUtil.uploadTexture(imageForUpload, target, -1, linearizeSrgbImages);
for (int i = 0; i < data.size(); i++) {
// upload each slice of 2D array in turn
// this time with the appropriate index
texUtil.uploadTexture(imageForUpload, target, i, linearizeSrgbImages);
}
} else {
texUtil.uploadTexture(imageForUpload, target, 0, linearizeSrgbImages);
}
if (img.getMultiSamples() != imageSamples) {
img.setMultiSamples(imageSamples);
}
if (caps.contains(Caps.FrameBuffer) || gl2 == null) {
if (!img.hasMipmaps() && img.isGeneratedMipmapsRequired() && img.getData(0) != null) {
glfbo.glGenerateMipmapEXT(target);
img.setMipmapsGenerated(true);
}
}
img.clearUpdateNeeded();
}
use of com.jme3.renderer.RendererException in project jmonkeyengine by jMonkeyEngine.
the class GLRenderer method setFrameBuffer.
public void setFrameBuffer(FrameBuffer fb) {
if (fb == null && mainFbOverride != null) {
fb = mainFbOverride;
}
if (context.boundFB == fb) {
if (fb == null || !fb.isUpdateNeeded()) {
return;
}
}
if (!caps.contains(Caps.FrameBuffer)) {
throw new RendererException("Framebuffer objects are not supported" + " by the video hardware");
}
// generate mipmaps for last FB if needed
if (context.boundFB != null) {
for (int i = 0; i < context.boundFB.getNumColorBuffers(); i++) {
RenderBuffer rb = context.boundFB.getColorBuffer(i);
Texture tex = rb.getTexture();
if (tex != null && tex.getMinFilter().usesMipMapLevels()) {
setTexture(0, rb.getTexture());
int textureType = convertTextureType(tex.getType(), tex.getImage().getMultiSamples(), rb.getFace());
glfbo.glGenerateMipmapEXT(textureType);
}
}
}
if (fb == null) {
bindFrameBuffer(null);
setReadDrawBuffers(null);
} else {
if (fb.isUpdateNeeded()) {
updateFrameBuffer(fb);
} else {
bindFrameBuffer(fb);
setReadDrawBuffers(fb);
}
// update viewport to reflect framebuffer's resolution
setViewPort(0, 0, fb.getWidth(), fb.getHeight());
assert fb.getId() > 0;
assert context.boundFBO == fb.getId();
context.boundFB = fb;
}
}
use of com.jme3.renderer.RendererException in project jmonkeyengine by jMonkeyEngine.
the class GLRenderer method setTexture.
@Override
public void setTexture(int unit, Texture tex) {
Image image = tex.getImage();
if (image.isUpdateNeeded() || (image.isGeneratedMipmapsRequired() && !image.isMipmapsGenerated())) {
// Check NPOT requirements
boolean scaleToPot = false;
try {
checkNonPowerOfTwo(tex);
} catch (RendererException ex) {
if (logger.isLoggable(Level.WARNING)) {
int nextWidth = FastMath.nearestPowerOfTwo(tex.getImage().getWidth());
int nextHeight = FastMath.nearestPowerOfTwo(tex.getImage().getHeight());
logger.log(Level.WARNING, "Non-power-of-2 textures are not supported! Scaling texture '" + tex.getName() + "' of size " + tex.getImage().getWidth() + "x" + tex.getImage().getHeight() + " to " + nextWidth + "x" + nextHeight);
}
scaleToPot = true;
}
updateTexImageData(image, tex.getType(), unit, scaleToPot);
}
int texId = image.getId();
assert texId != -1;
setupTextureParams(unit, tex);
}
use of com.jme3.renderer.RendererException in project jmonkeyengine by jMonkeyEngine.
the class GLRenderer method setVertexAttrib.
public void setVertexAttrib(VertexBuffer vb, VertexBuffer idb) {
if (vb.getBufferType() == VertexBuffer.Type.Index) {
throw new IllegalArgumentException("Index buffers not allowed to be set to vertex attrib");
}
if (context.boundShaderProgram <= 0) {
throw new IllegalStateException("Cannot render mesh without shader bound");
}
Attribute attrib = context.boundShader.getAttribute(vb.getBufferType());
int loc = attrib.getLocation();
if (loc == -1) {
// not defined
return;
}
if (loc == -2) {
loc = gl.glGetAttribLocation(context.boundShaderProgram, "in" + vb.getBufferType().name());
// the internal name of the enum (Position).
if (loc < 0) {
attrib.setLocation(-1);
// not available in shader.
return;
} else {
attrib.setLocation(loc);
}
}
if (vb.isInstanced()) {
if (!caps.contains(Caps.MeshInstancing)) {
throw new RendererException("Instancing is required, " + "but not supported by the " + "graphics hardware");
}
}
int slotsRequired = 1;
if (vb.getNumComponents() > 4) {
if (vb.getNumComponents() % 4 != 0) {
throw new RendererException("Number of components in multi-slot " + "buffers must be divisible by 4");
}
slotsRequired = vb.getNumComponents() / 4;
}
if (vb.isUpdateNeeded() && idb == null) {
updateBufferData(vb);
}
VertexBuffer[] attribs = context.boundAttribs;
for (int i = 0; i < slotsRequired; i++) {
if (!context.attribIndexList.moveToNew(loc + i)) {
gl.glEnableVertexAttribArray(loc + i);
}
}
if (attribs[loc] != vb) {
// NOTE: Use id from interleaved buffer if specified
int bufId = idb != null ? idb.getId() : vb.getId();
assert bufId != -1;
if (context.boundArrayVBO != bufId) {
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, bufId);
context.boundArrayVBO = bufId;
//statistics.onVertexBufferUse(vb, true);
} else {
//statistics.onVertexBufferUse(vb, false);
}
if (slotsRequired == 1) {
gl.glVertexAttribPointer(loc, vb.getNumComponents(), convertFormat(vb.getFormat()), vb.isNormalized(), vb.getStride(), vb.getOffset());
} else {
for (int i = 0; i < slotsRequired; i++) {
// The pointer maps the next 4 floats in the slot.
// E.g.
// P1: XXXX____________XXXX____________
// P2: ____XXXX____________XXXX________
// P3: ________XXXX____________XXXX____
// P4: ____________XXXX____________XXXX
// stride = 4 bytes in float * 4 floats in slot * num slots
// offset = 4 bytes in float * 4 floats in slot * slot index
gl.glVertexAttribPointer(loc + i, 4, convertFormat(vb.getFormat()), vb.isNormalized(), 4 * 4 * slotsRequired, 4 * 4 * i);
}
}
for (int i = 0; i < slotsRequired; i++) {
int slot = loc + i;
if (vb.isInstanced() && (attribs[slot] == null || !attribs[slot].isInstanced())) {
// non-instanced -> instanced
glext.glVertexAttribDivisorARB(slot, vb.getInstanceSpan());
} else if (!vb.isInstanced() && attribs[slot] != null && attribs[slot].isInstanced()) {
// instanced -> non-instanced
glext.glVertexAttribDivisorARB(slot, 0);
}
attribs[slot] = vb;
}
}
}
use of com.jme3.renderer.RendererException in project jmonkeyengine by jMonkeyEngine.
the class MaterialDebugAppState method reloadMaterial.
public Material reloadMaterial(Material mat) {
//clear the entire cache, there might be more clever things to do, like clearing only the matdef, and the associated shaders.
assetManager.clearCache();
//creating a dummy mat with the mat def of the mat to reload
Material dummy = new Material(mat.getMaterialDef());
for (MatParam matParam : mat.getParams()) {
dummy.setParam(matParam.getName(), matParam.getVarType(), matParam.getValue());
}
dummy.getAdditionalRenderState().set(mat.getAdditionalRenderState());
//creating a dummy geom and assigning the dummy material to it
Geometry dummyGeom = new Geometry("dummyGeom", new Box(1f, 1f, 1f));
dummyGeom.setMaterial(dummy);
try {
//preloading the dummyGeom, this call will compile the shader again
renderManager.preloadScene(dummyGeom);
} catch (RendererException e) {
//compilation error, the shader code will be output to the console
//the following code will output the error
//System.err.println(e.getMessage());
Logger.getLogger(MaterialDebugAppState.class.getName()).log(Level.SEVERE, e.getMessage());
return null;
}
Logger.getLogger(MaterialDebugAppState.class.getName()).log(Level.INFO, "Material succesfully reloaded");
//System.out.println("Material succesfully reloaded");
return dummy;
}
Aggregations