public ClipStateRecord(final ContextCapabilities caps) { planeEnabled = new boolean[ClipState.MAX_CLIP_PLANES]; if (caps.areDoubleCoefficientsInClipPlaneEquationSupported()) { buf = BufferUtils.createDoubleBuffer(4); } else { buf = BufferUtils.createFloatBuffer(4); } }
public void killParticle() { setStatus(Status.Dead); final Vector3 tempVec3 = Vector3.fetchTempInstance(); final FloatBuffer vertexBuffer = parent.getParticleGeometry().getMeshData().getVertexBuffer(); BufferUtils.populateFromBuffer(tempVec3, vertexBuffer, startIndex); final int verts = ParticleSystem.getVertsForParticleType(type); for (int x = 1; x < verts; x++) { BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + x); } Vector3.releaseTempInstance(tempVec3); }
/** * Sets the vertices that make the pyramid. Where the center of the box is the origin and the base * and height are set during construction. */ protected void setVertexData() { peak = new Vector3(0, 0, 0); vert0 = new Vector3(-width / 2, -height / 2, -length); vert1 = new Vector3(width / 2, -height / 2, -length); vert2 = new Vector3(width / 2, height / 2, -length); vert3 = new Vector3(-width / 2, height / 2, -length); FloatBuffer verts = BufferUtils.createVector3Buffer(12); // side 1 verts.put((float) vert0.getX()).put((float) vert0.getY()).put((float) vert0.getZ()); verts.put((float) vert1.getX()).put((float) vert1.getY()).put((float) vert1.getZ()); verts.put((float) peak.getX()).put((float) peak.getY()).put((float) peak.getZ()); // side 2 verts.put((float) vert1.getX()).put((float) vert1.getY()).put((float) vert1.getZ()); verts.put((float) vert2.getX()).put((float) vert2.getY()).put((float) vert2.getZ()); verts.put((float) peak.getX()).put((float) peak.getY()).put((float) peak.getZ()); // side 3 verts.put((float) vert2.getX()).put((float) vert2.getY()).put((float) vert2.getZ()); verts.put((float) vert3.getX()).put((float) vert3.getY()).put((float) vert3.getZ()); verts.put((float) peak.getX()).put((float) peak.getY()).put((float) peak.getZ()); // side 4 verts.put((float) vert3.getX()).put((float) vert3.getY()).put((float) vert3.getZ()); verts.put((float) vert0.getX()).put((float) vert0.getY()).put((float) vert0.getZ()); verts.put((float) peak.getX()).put((float) peak.getY()).put((float) peak.getZ()); verts.rewind(); sides.getMeshData().setVertexBuffer(verts); }
/** Defines the normals of each face of the pyramid. */ protected void setNormalData() { Vector3 normal = new Vector3(); Vector3 work = new Vector3(); FloatBuffer norms = BufferUtils.createVector3Buffer(12); // side 1 MathUtil.createNormal(normal, vert0, vert1, peak, work); norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ()); norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ()); norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ()); // side 2 MathUtil.createNormal(normal, vert1, vert2, peak, work); norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ()); norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ()); norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ()); // side 3 MathUtil.createNormal(normal, vert2, vert3, peak, work); norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ()); norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ()); norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ()); // side 4 MathUtil.createNormal(normal, vert3, vert0, peak, work); norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ()); norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ()); norms.put((float) normal.getX()).put((float) normal.getY()).put((float) normal.getZ()); norms.rewind(); sides.getMeshData().setNormalBuffer(norms); }
/** * update position (using current position and velocity), color (interpolating between start and * end color), size (interpolating between start and end size), spin (using parent's spin speed) * and current age of particle. If this particle's age is greater than its lifespan, it is set to * status DEAD. * * <p>Note that this only changes the parameters of the Particle, not the geometry the particle is * associated with. * * @param secondsPassed number of seconds passed since last update. * @return true if this particle is not ALIVE (in other words, if it is ready to be reused.) */ public boolean updateAndCheck(final double secondsPassed) { if (status != Status.Alive) { return true; } currentAge += secondsPassed * 1000; // add ms time to age if (currentAge > lifeSpan) { killParticle(); return true; } final Vector3 temp = Vector3.fetchTempInstance(); _position.addLocal(_velocity.multiply(secondsPassed * 1000f, temp)); Vector3.releaseTempInstance(temp); // get interpolated values from appearance ramp: parent.getRamp().getValuesAtAge(currentAge, lifeSpan, currColor, values, parent); // interpolate colors final int verts = ParticleSystem.getVertsForParticleType(type); for (int x = 0; x < verts; x++) { BufferUtils.setInBuffer( currColor, parent.getParticleGeometry().getMeshData().getColorBuffer(), startIndex + x); } // check for tex animation final int newTexIndex = parent.getTexAnimation().getTexIndexAtAge(currentAge, lifeSpan, parent); // Update tex coords if applicable if (currentTexIndex != newTexIndex) { // Only supported in Quad type for now. if (ParticleType.Quad.equals(parent.getParticleType())) { // determine side final float side = (float) Math.sqrt(parent.getTexQuantity()); int index = newTexIndex; if (index >= parent.getTexQuantity()) { index %= parent.getTexQuantity(); } // figure row / col final float row = side - (int) (index / side) - 1; final float col = index % side; // set texcoords final float sU = col / side, eU = (col + 1) / side; final float sV = row / side, eV = (row + 1) / side; final FloatBuffer texs = parent.getParticleGeometry().getMeshData().getTextureCoords(0).getBuffer(); texs.position(startIndex * 2); texs.put(eU).put(sV); texs.put(eU).put(eV); texs.put(sU).put(eV); texs.put(sU).put(sV); texs.clear(); } currentTexIndex = newTexIndex; } return false; }
private void allocateVertices() { // allocate vertices final int verts = _axisSamples * (_radialSamples + 1) + (_closed ? 2 : 0); _meshData.setVertexBuffer(BufferUtils.createVector3Buffer(_meshData.getVertexBuffer(), verts)); // allocate normals if requested _meshData.setNormalBuffer(BufferUtils.createVector3Buffer(_meshData.getNormalBuffer(), verts)); // allocate texture coordinates _meshData.setTextureBuffer(BufferUtils.createVector2Buffer(verts), 0); final int count = ((_closed ? 2 : 0) + 2 * (_axisSamples - 1)) * _radialSamples; if (_meshData.getIndices() == null || _meshData.getIndices().getBufferLimit() != 3 * count) { _meshData.setIndices(BufferUtils.createIndexBufferData(3 * count, verts - 1)); } setGeometryData(); setIndexData(); }
/** * Constructor * * @param color */ public SimpleCrosshair(ReadOnlyColorRGBA color) { super("Crosshair"); ReadOnlyColorRGBA[] crosshairColor = {color, color, color, color}; getMeshData().setIndexMode(IndexMode.Lines); getMeshData().setVertexBuffer(BufferUtils.createFloatBuffer(crosshairVertex)); FloatBuffer colorBuffer = BufferUtils.createFloatBuffer(crosshairColor); colorBuffer.rewind(); getMeshData().setColorBuffer(colorBuffer); getMeshData().setIndexBuffer(BufferUtils.createIntBuffer(crosshairIndex)); getMeshData().getIndexBuffer().limit(4); getMeshData().getIndexBuffer().rewind(); getSceneHints().setAllPickingHints(false); setModelBound(new BoundingBox()); updateModelBound(); MaterialState crosshairMaterialState = new MaterialState(); crosshairMaterialState.setColorMaterial(MaterialState.ColorMaterial.Emissive); crosshairMaterialState.setEnabled(true); getSceneHints().setLightCombineMode(LightCombineMode.Off); setRenderState(crosshairMaterialState); updateGeometricState(0, true); }
private void recreateBuffers() { // determine vert quantity - first the sphere caps final int sampleLines = (2 * sphereSamples - 1 + axisSamples); final int verts = (radialSamples + 1) * sampleLines + 2; _meshData.setVertexBuffer(BufferUtils.createVector3Buffer(_meshData.getVertexBuffer(), verts)); // allocate normals _meshData.setNormalBuffer(BufferUtils.createVector3Buffer(_meshData.getNormalBuffer(), verts)); // allocate texture coordinates _meshData.setTextureCoords(new TexCoords(BufferUtils.createVector2Buffer(verts)), 0); // determine tri quantity final int tris = 2 * radialSamples * sampleLines; _meshData.setIndexBuffer(BufferUtils.createIntBuffer(_meshData.getIndexBuffer(), 3 * tris)); setGeometryData(); setIndexData(); }
private Mesh createDegenerateStripMesh() { final Mesh mesh = new Mesh(); final MeshData meshData = mesh.getMeshData(); final FloatBuffer vertexBuffer = BufferUtils.createVector3Buffer(totalSize); final FloatBuffer normalBuffer = BufferUtils.createVector3Buffer(totalSize); final FloatBuffer textureBuffer = BufferUtils.createVector2Buffer(totalSize); final IntBuffer indexBuffer = BufferUtils.createIntBuffer((ySize - 1) * xSize * 2 + (ySize - 1) * 2); for (int y = 0; y < ySize; y++) { for (int x = 0; x < xSize; x++) { vertexBuffer.put(x).put(y).put(0); normalBuffer.put(0).put(0).put(1); textureBuffer.put(x).put(y); } } for (int y = 0; y < ySize - 1; y++) { for (int x = 0; x < xSize; x++) { final int index = y * xSize + x; indexBuffer.put(index); indexBuffer.put(index + xSize); } final int index = (y + 1) * xSize; indexBuffer.put(index + xSize - 1); indexBuffer.put(index); } meshData.setVertexBuffer(vertexBuffer); meshData.setNormalBuffer(normalBuffer); meshData.setTextureBuffer(textureBuffer, 0); meshData.setIndexBuffer(indexBuffer); meshData.setIndexMode(IndexMode.TriangleStrip); return mesh; }
protected static int create(final ByteBuffer program) { final IntBuffer buf = BufferUtils.createIntBuffer(1); ARBProgram.glGenProgramsARB(buf); ARBProgram.glBindProgramARB(ARBVertexProgram.GL_VERTEX_PROGRAM_ARB, buf.get(0)); ARBProgram.glProgramStringARB( ARBVertexProgram.GL_VERTEX_PROGRAM_ARB, ARBProgram.GL_PROGRAM_FORMAT_ASCII_ARB, program); checkProgramError(); return buf.get(0); }
/** * Queries OpenGL for errors in the vertex program. Errors are logged as SEVERE, noting both the * line number and message. */ private static void checkProgramError() { if (GL11.glGetError() == GL11.GL_INVALID_OPERATION) { // retrieve the error position final IntBuffer errorloc = BufferUtils.createIntBuffer(16); GL11.glGetInteger(ARBProgram.GL_PROGRAM_ERROR_POSITION_ARB, errorloc); logger.severe( "Error " + GL11.glGetString(ARBProgram.GL_PROGRAM_ERROR_STRING_ARB) + " in vertex program on line " + errorloc.get(0)); } }
private static void checkLinkError(final int programId) { final GL gl = GLContext.getCurrentGL(); final JoglRenderContext context = (JoglRenderContext) ContextManager.getCurrentContext(); final IntBuffer compiled = context.getDirectNioBuffersSet().getSingleIntBuffer(); compiled.clear(); if (gl.isGL2()) { gl.getGL2().glGetObjectParameterivARB(programId, GL2ES2.GL_LINK_STATUS, compiled); } else { if (gl.isGL2ES2()) { gl.getGL2ES2().glGetProgramiv(programId, GL2ES2.GL_LINK_STATUS, compiled); } } if (compiled.get(0) == GL.GL_FALSE) { if (gl.isGL2()) { gl.getGL2().glGetObjectParameterivARB(programId, GL2ES2.GL_INFO_LOG_LENGTH, compiled); } else { if (gl.isGL2ES2()) { gl.getGL2ES2().glGetProgramiv(programId, GL2ES2.GL_INFO_LOG_LENGTH, compiled); } } final int length = compiled.get(0); String out = null; if (length > 0) { final ByteBuffer infoLogBuf = context.getDirectNioBuffersSet().getInfoLogBuffer(); final ByteBuffer infoLog; if (length <= infoLogBuf.capacity()) { infoLog = infoLogBuf; infoLogBuf.rewind().limit(length); } else { infoLog = BufferUtils.createByteBuffer(length); } if (gl.isGL2()) { gl.getGL2().glGetInfoLogARB(programId, infoLog.limit(), compiled, infoLog); } else { if (gl.isGL2ES2()) { gl.getGL2ES2().glGetProgramInfoLog(programId, infoLog.limit(), compiled, infoLog); } } final byte[] infoBytes = new byte[length]; infoLog.get(infoBytes); out = new String(infoBytes); } logger.severe(out); // throw new Ardor3dException("Error linking GLSL shader: " + out); } }
/** * Reset particle conditions. Besides the passed lifespan, we also reset color, size, and spin * angle to their starting values (as given by parent.) Status is set to Status.Available. * * @param lifeSpan the recreated particle's new lifespan */ public void recreateParticle(final double lifeSpan) { this.lifeSpan = lifeSpan; final int verts = ParticleSystem.getVertsForParticleType(type); currColor.set(parent.getStartColor()); for (int x = 0; x < verts; x++) { BufferUtils.setInBuffer( currColor, parent.getParticleGeometry().getMeshData().getColorBuffer(), startIndex + x); } values[VAL_CURRENT_SIZE] = parent.getStartSize(); currentAge = 0; values[VAL_CURRENT_MASS] = 1; status = Status.Available; }
private static void checkLinkError(final int programId) { final GL gl = GLU.getCurrentGL(); final IntBuffer compiled = BufferUtils.createIntBuffer(1); gl.glGetObjectParameterivARB(programId, GL.GL_LINK_STATUS, compiled); if (compiled.get(0) == GL.GL_FALSE) { gl.glGetObjectParameterivARB(programId, GL.GL_INFO_LOG_LENGTH, compiled); final int length = compiled.get(0); String out = null; if (length > 0) { final ByteBuffer infoLog = BufferUtils.createByteBuffer(length); gl.glGetInfoLogARB(programId, infoLog.limit(), compiled, infoLog); final byte[] infoBytes = new byte[length]; infoLog.get(infoBytes); out = new String(infoBytes); } logger.severe(out); // throw new Ardor3dException("Error linking GLSL shader: " + out); } }
/** * Check for program errors. If an error is detected, program exits. * * @param compiled the compiler state for a given shader * @param id shader's id */ private static void checkProgramError(final IntBuffer compiled, final int id) { final GL gl = GLU.getCurrentGL(); if (compiled.get(0) == GL.GL_FALSE) { final IntBuffer iVal = BufferUtils.createIntBuffer(1); gl.glGetObjectParameterivARB(id, GL.GL_OBJECT_INFO_LOG_LENGTH_ARB, iVal); final int length = iVal.get(0); String out = null; if (length > 0) { final ByteBuffer infoLog = BufferUtils.createByteBuffer(length); gl.glGetInfoLogARB(id, infoLog.limit(), iVal, infoLog); final byte[] infoBytes = new byte[length]; infoLog.get(infoBytes); out = new String(infoBytes); } logger.severe(out); throw new Ardor3dException("Error compiling GLSL shader: " + out); } }
/** * Queries OpenGL for errors in the vertex program. Errors are logged as SEVERE, noting both the * line number and message. */ private static void checkProgramError() { final GL gl = GLU.getCurrentGL(); if (gl.glGetError() == GL.GL_INVALID_OPERATION) { // retrieve the error position final IntBuffer errorloc = BufferUtils.createIntBuffer(16); gl.glGetIntegerv(GL.GL_PROGRAM_ERROR_POSITION_ARB, errorloc); // TODO Check for integer logger.severe( "Error " + gl.glGetString(GL.GL_PROGRAM_ERROR_STRING_ARB) + " in vertex program on line " + errorloc.get(0)); } }
/** * <code>setupTexture</code> initializes a new Texture object for use with TextureRenderer. * Generates a valid gl texture id for this texture and inits the data type for the texture. */ public void setupTexture(final Texture tex) { if (tex.getType() != Type.TwoDimensional) { throw new IllegalArgumentException("Unsupported type: " + tex.getType()); } final RenderContext context = ContextManager.getCurrentContext(); final TextureStateRecord record = (TextureStateRecord) context.getStateRecord(RenderState.StateType.Texture); // check if we are already setup... if so, throw error. if (tex.getTextureKey() == null) { tex.setTextureKey(TextureKey.getRTTKey(tex.getMinificationFilter())); } else if (tex.getTextureIdForContext(context.getGlContextRep()) != 0) { throw new Ardor3dException("Texture is already setup and has id."); } // Create the texture final IntBuffer ibuf = BufferUtils.createIntBuffer(1); GL11.glGenTextures(ibuf); final int textureId = ibuf.get(0); tex.setTextureIdForContext(context.getGlContextRep(), textureId); LwjglTextureStateUtil.doTextureBind(tex, 0, true); // Initialize our texture with some default data. final int internalFormat = LwjglTextureUtil.getGLInternalFormat(tex.getTextureStoreFormat()); final int dataFormat = LwjglTextureUtil.getGLPixelFormatFromStoreFormat(tex.getTextureStoreFormat()); final int pixelDataType = LwjglTextureUtil.getGLPixelDataType(tex.getRenderedTexturePixelDataType()); GL11.glTexImage2D( GL11.GL_TEXTURE_2D, 0, internalFormat, _width, _height, 0, dataFormat, pixelDataType, (ByteBuffer) null); // Setup filtering and wrap final TextureRecord texRecord = record.getTextureRecord(textureId, tex.getType()); LwjglTextureStateUtil.applyFilter(tex, texRecord, 0, record, context.getCapabilities()); LwjglTextureStateUtil.applyWrap(tex, texRecord, 0, record, context.getCapabilities()); logger.fine("setup pbuffer tex" + textureId + ": " + _width + "," + _height); }
private Spatial createLines() { final FloatBuffer verts = BufferUtils.createVector3Buffer(3); verts.put(0).put(0).put(0); verts.put(5).put(5).put(0); verts.put(0).put(5).put(0); final Line line = new Line("Lines", verts, null, null, null); // since we do not set texture coords, but we'll have a texture state applied at root, we need // to turn off // textures on this Line to prevent bleeding of texture coordinates from other shapes. line.getSceneHints().setTextureCombineMode(TextureCombineMode.Off); line.getMeshData().setIndexMode(IndexMode.LineStrip); line.setLineWidth(2); line.getSceneHints().setLightCombineMode(LightCombineMode.Off); return line; }
/** * Check for program errors. If an error is detected, program exits. * * @param compilerState the compiler state for a given shader * @param id shader's id */ private static void checkProgramError( final int compilerState, final int id, final String shaderName) { final GL gl = GLContext.getCurrentGL(); if (compilerState == GL.GL_FALSE) { final JoglRenderContext context = (JoglRenderContext) ContextManager.getCurrentContext(); final IntBuffer iVal = context.getDirectNioBuffersSet().getSingleIntBuffer(); iVal.clear(); if (gl.isGL2()) { gl.getGL2().glGetObjectParameterivARB(id, GL2.GL_OBJECT_INFO_LOG_LENGTH_ARB, iVal); } else { if (gl.isGL2ES2()) { gl.getGL2ES2().glGetProgramiv(id, GL2ES2.GL_INFO_LOG_LENGTH, iVal); } } final int length = iVal.get(0); String out = null; if (length > 0) { final ByteBuffer infoLogBuf = context.getDirectNioBuffersSet().getInfoLogBuffer(); final ByteBuffer infoLog; if (length <= infoLogBuf.capacity()) { infoLog = infoLogBuf; infoLogBuf.rewind().limit(length); } else { infoLog = BufferUtils.createByteBuffer(length); } if (gl.isGL2()) { gl.getGL2().glGetInfoLogARB(id, infoLog.limit(), iVal, infoLog); } else { if (gl.isGL2ES2()) { gl.getGL2ES2().glGetProgramInfoLog(id, infoLog.limit(), iVal, infoLog); } } final byte[] infoBytes = new byte[length]; infoLog.get(infoBytes); out = new String(infoBytes); } logger.severe(out); final String nameString = shaderName.equals("") ? "" : " [ " + shaderName + " ]"; throw new Ardor3dException("Error compiling GLSL shader " + nameString + ": " + out); } }
/** * Merges this sphere with the given OBB. * * @param volume The OBB to merge. * @return This sphere, after merging. */ private BoundingSphere mergeLocalOBB(final OrientedBoundingBox volume) { // check for infinite bounds to prevent NaN values... is so, return infinite bounds with center // at origin if (Double.isInfinite(getRadius()) || Vector3.isInfinite(volume.getExtent())) { setCenter(Vector3.ZERO); setRadius(Double.POSITIVE_INFINITY); return this; } // compute edge points from the obb if (!volume.correctCorners) { volume.computeCorners(); } final FloatBuffer mergeBuf = BufferUtils.createFloatBufferOnHeap(8 * 3); for (int i = 0; i < 8; i++) { mergeBuf.put((float) volume._vectorStore[i].getX()); mergeBuf.put((float) volume._vectorStore[i].getY()); mergeBuf.put((float) volume._vectorStore[i].getZ()); } // remember old radius and center final double oldRadius = getRadius(); final double oldCenterX = _center.getX(); final double oldCenterY = _center.getY(); final double oldCenterZ = _center.getZ(); // compute new radius and center from obb points computeFromPoints(mergeBuf); final double newCenterX = _center.getX(); final double newCenterY = _center.getY(); final double newCenterZ = _center.getZ(); final double newRadius = getRadius(); // restore old center and radius _center.set(oldCenterX, oldCenterY, oldCenterZ); setRadius(oldRadius); // merge obb points result merge(newRadius, _compVect4.set(newCenterX, newCenterY, newCenterZ), this); return this; }
private static int create(final ByteBuffer program) { final GL gl = GLU.getCurrentGL(); final IntBuffer buf = BufferUtils.createIntBuffer(1); gl.glGenProgramsARB(buf.limit(), buf); gl.glBindProgramARB(GL.GL_VERTEX_PROGRAM_ARB, buf.get(0)); final byte array[] = new byte[program.limit()]; program.rewind(); program.get(array); gl.glProgramStringARB( GL.GL_VERTEX_PROGRAM_ARB, GL.GL_PROGRAM_FORMAT_ASCII_ARB, array.length, new String(array)); checkProgramError(); return buf.get(0); }
public Arc(final String name, final int vertices) { super(name); getMeshData().setIndexMode(IndexMode.LineStrip); getMeshData().setVertexBuffer(BufferUtils.createVector3Buffer(vertices)); Util.disablePickShadowLight(this); }
public LwjglContextCapabilities(final org.lwjgl.opengl.ContextCapabilities caps) { final IntBuffer buf = BufferUtils.createIntBuffer(16); _supportsVBO = caps.GL_ARB_vertex_buffer_object; _supportsGL1_2 = caps.OpenGL12; _supportsMultisample = caps.GL_ARB_multisample; _supportsConstantColor = _supportsEq = caps.GL_ARB_imaging; _supportsSeparateFunc = caps.GL_EXT_blend_func_separate; _supportsSeparateEq = caps.GL_EXT_blend_equation_separate; _supportsMinMax = caps.GL_EXT_blend_minmax; _supportsSubtract = caps.GL_EXT_blend_subtract; _supportsFogCoords = caps.GL_EXT_fog_coord; _supportsFragmentProgram = caps.GL_ARB_fragment_program; _supportsVertexProgram = caps.GL_ARB_vertex_program; _supportsTextureLodBias = caps.GL_EXT_texture_lod_bias; if (_supportsTextureLodBias) { GL11.glGetInteger(EXTTextureLODBias.GL_MAX_TEXTURE_LOD_BIAS_EXT, buf); _maxTextureLodBias = buf.get(0); } else { _maxTextureLodBias = 0f; } _glslSupported = caps.GL_ARB_shader_objects && caps.GL_ARB_fragment_shader && caps.GL_ARB_vertex_shader && caps.GL_ARB_shading_language_100; if (_glslSupported) { GL11.glGetInteger(ARBVertexShader.GL_MAX_VERTEX_ATTRIBS_ARB, buf); _maxGLSLVertexAttribs = buf.get(0); } // Pbuffer _pbufferSupported = caps.GL_ARB_pixel_buffer_object; // FBO _fboSupported = caps.GL_EXT_framebuffer_object; if (_fboSupported) { if (caps.GL_ARB_draw_buffers) { GL11.glGetInteger(EXTFramebufferObject.GL_MAX_COLOR_ATTACHMENTS_EXT, buf); _maxFBOColorAttachments = buf.get(0); } else { _maxFBOColorAttachments = 1; } // Max multisample samples. if (caps.GL_EXT_framebuffer_multisample && caps.GL_EXT_framebuffer_blit) { GL11.glGetInteger(EXTFramebufferMultisample.GL_MAX_SAMPLES_EXT, buf); _maxFBOSamples = buf.get(0); } else { _maxFBOSamples = 0; } } else { _maxFBOColorAttachments = 0; } _twoSidedStencilSupport = caps.GL_EXT_stencil_two_side; _stencilWrapSupport = caps.GL_EXT_stencil_wrap; // number of available auxiliary draw buffers GL11.glGetInteger(GL11.GL_AUX_BUFFERS, buf); _numAuxDrawBuffers = buf.get(0); // max texture size. GL11.glGetInteger(GL11.GL_MAX_TEXTURE_SIZE, buf); _maxTextureSize = buf.get(0); // Check for support of multitextures. _supportsMultiTexture = caps.GL_ARB_multitexture; // Check for support of fixed function dot3 environment settings _supportsEnvDot3 = caps.GL_ARB_texture_env_dot3; // Check for support of fixed function dot3 environment settings _supportsEnvCombine = caps.GL_ARB_texture_env_combine; // Check for support of automatic mipmap generation _automaticMipMaps = caps.GL_SGIS_generate_mipmap; _supportsDepthTexture = caps.GL_ARB_depth_texture; _supportsShadow = caps.GL_ARB_shadow; // If we do support multitexturing, find out how many textures we // can handle. if (_supportsMultiTexture) { GL11.glGetInteger(ARBMultitexture.GL_MAX_TEXTURE_UNITS_ARB, buf); _numFixedTexUnits = buf.get(0); } else { _numFixedTexUnits = 1; } // Go on to check number of texture units supported for vertex and // fragment shaders if (caps.GL_ARB_shader_objects && caps.GL_ARB_vertex_shader && caps.GL_ARB_fragment_shader) { GL11.glGetInteger(ARBVertexShader.GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, buf); _numVertexTexUnits = buf.get(0); GL11.glGetInteger(ARBFragmentShader.GL_MAX_TEXTURE_IMAGE_UNITS_ARB, buf); _numFragmentTexUnits = buf.get(0); GL11.glGetInteger(ARBFragmentShader.GL_MAX_TEXTURE_COORDS_ARB, buf); _numFragmentTexCoordUnits = buf.get(0); } else { // based on nvidia dev doc: // http://developer.nvidia.com/object/General_FAQ.html#t6 // "For GPUs that do not support GL_ARB_fragment_program and // GL_NV_fragment_program, those two limits are set equal to // GL_MAX_TEXTURE_UNITS." _numFragmentTexCoordUnits = _numFixedTexUnits; _numFragmentTexUnits = _numFixedTexUnits; // We'll set this to 0 for now since we do not know: _numVertexTexUnits = 0; } // Now determine the maximum number of supported texture units _numTotalTexUnits = Math.max( _numFragmentTexCoordUnits, Math.max(_numFixedTexUnits, Math.max(_numFragmentTexUnits, _numVertexTexUnits))); // Check for S3 texture compression capability. _supportsS3TCCompression = caps.GL_EXT_texture_compression_s3tc; // Check for 3D texture capability. _supportsTexture3D = caps.OpenGL12; // Check for cubemap capability. _supportsTextureCubeMap = caps.GL_ARB_texture_cube_map; // See if we support anisotropic filtering _supportsAniso = caps.GL_EXT_texture_filter_anisotropic; if (_supportsAniso) { // Due to LWJGL buffer check, you can't use smaller sized // buffers (min_size = 16 for glGetFloat()). final FloatBuffer max_a = BufferUtils.createFloatBuffer(16); max_a.rewind(); // Grab the maximum anisotropic filter. GL11.glGetFloat(EXTTextureFilterAnisotropic.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, max_a); // set max. _maxAnisotropic = max_a.get(0); } // See if we support textures that are not power of 2 in size. _supportsNonPowerTwo = caps.GL_ARB_texture_non_power_of_two; // See if we support textures that do not have width == height. _supportsRectangular = caps.GL_ARB_texture_rectangle; _supportsMirroredRepeat = caps.GL_ARB_texture_mirrored_repeat; _supportsMirrorClamp = _supportsMirrorEdgeClamp = _supportsMirrorBorderClamp = caps.GL_EXT_texture_mirror_clamp; _supportsBorderClamp = caps.GL_ARB_texture_border_clamp; _supportsEdgeClamp = _supportsGL1_2; }
private void setGeometryData() { // generate geometry final double inverseRadial = 1.0 / _radialSamples; final double inverseAxisLess = 1.0 / (_closed ? _axisSamples - 3 : _axisSamples - 1); final double inverseAxisLessTexture = 1.0 / (_axisSamples - 1); final double halfHeight = 0.5 * _height; // Generate points on the unit circle to be used in computing the mesh // points on a cylinder slice. final double[] sin = new double[_radialSamples + 1]; final double[] cos = new double[_radialSamples + 1]; for (int radialCount = 0; radialCount < _radialSamples; radialCount++) { final double angle = MathUtils.TWO_PI * inverseRadial * radialCount; cos[radialCount] = MathUtils.cos(angle); sin[radialCount] = MathUtils.sin(angle); } sin[_radialSamples] = sin[0]; cos[_radialSamples] = cos[0]; // generate the cylinder itself final Vector3 tempNormal = new Vector3(); for (int axisCount = 0, i = 0; axisCount < _axisSamples; axisCount++) { double axisFraction; double axisFractionTexture; int topBottom = 0; if (!_closed) { axisFraction = axisCount * inverseAxisLess; // in [0,1] axisFractionTexture = axisFraction; } else { if (axisCount == 0) { topBottom = -1; // bottom axisFraction = 0; axisFractionTexture = inverseAxisLessTexture; } else if (axisCount == _axisSamples - 1) { topBottom = 1; // top axisFraction = 1; axisFractionTexture = 1 - inverseAxisLessTexture; } else { axisFraction = (axisCount - 1) * inverseAxisLess; axisFractionTexture = axisCount * inverseAxisLessTexture; } } final double z = -halfHeight + _height * axisFraction; // compute center of slice final Vector3 sliceCenter = new Vector3(0, 0, z); // compute slice vertices with duplication at end point final int save = i; for (int radialCount = 0; radialCount < _radialSamples; radialCount++) { final double radialFraction = radialCount * inverseRadial; // in [0,1) tempNormal.set(cos[radialCount], sin[radialCount], 0); if (topBottom == 0) { if (!_inverted) { _meshData .getNormalBuffer() .put(tempNormal.getXf()) .put(tempNormal.getYf()) .put(tempNormal.getZf()); } else { _meshData .getNormalBuffer() .put(-tempNormal.getXf()) .put(-tempNormal.getYf()) .put(-tempNormal.getZf()); } } else { _meshData.getNormalBuffer().put(0).put(0).put(topBottom * (_inverted ? -1 : 1)); } tempNormal .multiplyLocal((_radius - _radius2) * axisFraction + _radius2) .addLocal(sliceCenter); _meshData .getVertexBuffer() .put(tempNormal.getXf()) .put(tempNormal.getYf()) .put(tempNormal.getZf()); _meshData .getTextureCoords(0) .getBuffer() .put((float) (_inverted ? 1 - radialFraction : radialFraction)) .put((float) axisFractionTexture); i++; } BufferUtils.copyInternalVector3(_meshData.getVertexBuffer(), save, i); BufferUtils.copyInternalVector3(_meshData.getNormalBuffer(), save, i); _meshData .getTextureCoords(0) .getBuffer() .put((_inverted ? 0.0f : 1.0f)) .put((float) axisFractionTexture); i++; } if (_closed) { _meshData.getVertexBuffer().put(0).put(0).put((float) -halfHeight); // bottom center _meshData.getNormalBuffer().put(0).put(0).put(-1 * (_inverted ? -1 : 1)); _meshData.getTextureCoords(0).getBuffer().put(0.5f).put(0); _meshData.getVertexBuffer().put(0).put(0).put((float) halfHeight); // top center _meshData.getNormalBuffer().put(0).put(0).put(1 * (_inverted ? -1 : 1)); _meshData.getTextureCoords(0).getBuffer().put(0.5f).put(1); } }
@Override protected ByteBuffer initialValue() { return BufferUtils.createByteBufferOnHeap(tileSize * tileSize * 3); }
protected static void sendToGL(final GLSLShaderObjectsState state) { final GL gl = GLU.getCurrentGL(); if (state.getVertexShader() == null && state.getFragmentShader() == null) { logger.warning("Could not find shader resources!" + "(both inputbuffers are null)"); state._needSendShader = false; return; } if (state._programID == -1) { state._programID = gl.glCreateProgramObjectARB(); } if (state.getVertexShader() != null) { if (state._vertexShaderID != -1) { removeVertShader(state); } state._vertexShaderID = gl.glCreateShaderObjectARB(GL.GL_VERTEX_SHADER_ARB); // Create the sources final byte array[] = new byte[state.getVertexShader().limit()]; state.getVertexShader().rewind(); state.getVertexShader().get(array); gl.glShaderSourceARB( state._vertexShaderID, 1, new String[] {new String(array)}, new int[] {array.length}, 0); // Compile the vertex shader final IntBuffer compiled = BufferUtils.createIntBuffer(1); gl.glCompileShaderARB(state._vertexShaderID); gl.glGetObjectParameterivARB( state._vertexShaderID, GL.GL_OBJECT_COMPILE_STATUS_ARB, compiled); checkProgramError(compiled, state._vertexShaderID); // Attach the program gl.glAttachObjectARB(state._programID, state._vertexShaderID); } else if (state._vertexShaderID != -1) { removeVertShader(state); state._vertexShaderID = -1; } if (state.getFragmentShader() != null) { if (state._fragmentShaderID != -1) { removeFragShader(state); } state._fragmentShaderID = gl.glCreateShaderObjectARB(GL.GL_FRAGMENT_SHADER_ARB); // Create the sources final byte array[] = new byte[state.getFragmentShader().limit()]; state.getFragmentShader().rewind(); state.getFragmentShader().get(array); gl.glShaderSourceARB( state._fragmentShaderID, 1, new String[] {new String(array)}, new int[] {array.length}, 0); // Compile the fragment shader final IntBuffer compiled = BufferUtils.createIntBuffer(1); gl.glCompileShaderARB(state._fragmentShaderID); gl.glGetObjectParameterivARB( state._fragmentShaderID, GL.GL_OBJECT_COMPILE_STATUS_ARB, compiled); checkProgramError(compiled, state._fragmentShaderID); // Attach the program gl.glAttachObjectARB(state._programID, state._fragmentShaderID); } else if (state._fragmentShaderID != -1) { removeFragShader(state); state._fragmentShaderID = -1; } gl.glLinkProgramARB(state._programID); checkLinkError(state._programID); state.setNeedsRefresh(true); state._needSendShader = false; }
/** * Update the vertices for this particle, taking size, spin and viewer into consideration. In the * case of particle type ParticleType.GeomMesh, the original triangle normal is maintained rather * than rotating it to face the camera or parent vectors. * * @param cam Camera to use in determining viewer aspect. If null, or if parent is not set to * camera facing, parent's left and up vectors are used. */ public void updateVerts(final Camera cam) { final double orient = parent.getParticleOrientation() + values[VAL_CURRENT_SPIN]; final double currSize = values[VAL_CURRENT_SIZE]; if (type == ParticleSystem.ParticleType.GeomMesh || type == ParticleSystem.ParticleType.Point) {; // nothing to do } else if (cam != null && parent.isCameraFacing()) { final ReadOnlyVector3 camUp = cam.getUp(); final ReadOnlyVector3 camLeft = cam.getLeft(); final ReadOnlyVector3 camDir = cam.getDirection(); if (parent.isVelocityAligned()) { bbX.set(_velocity).normalizeLocal().multiplyLocal(currSize); camDir.cross(bbX, bbY).normalizeLocal().multiplyLocal(currSize); } else if (orient == 0) { bbX.set(camLeft).multiplyLocal(currSize); bbY.set(camUp).multiplyLocal(currSize); } else { final double cA = MathUtils.cos(orient) * currSize; final double sA = MathUtils.sin(orient) * currSize; bbX.set(camLeft) .multiplyLocal(cA) .addLocal(camUp.getX() * sA, camUp.getY() * sA, camUp.getZ() * sA); bbY.set(camLeft) .multiplyLocal(-sA) .addLocal(camUp.getX() * cA, camUp.getY() * cA, camUp.getZ() * cA); } } else { bbX.set(parent.getLeftVector()).multiplyLocal(0); bbY.set(parent.getUpVector()).multiplyLocal(0); } final Vector3 tempVec3 = Vector3.fetchTempInstance(); final FloatBuffer vertexBuffer = parent.getParticleGeometry().getMeshData().getVertexBuffer(); switch (type) { case Quad: { _position.subtract(bbX, tempVec3).subtractLocal(bbY); BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 0); _position.subtract(bbX, tempVec3).addLocal(bbY); BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 1); _position.add(bbX, tempVec3).addLocal(bbY); BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 2); _position.add(bbX, tempVec3).subtractLocal(bbY); BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 3); break; } case GeomMesh: { final Quaternion tempQuat = Quaternion.fetchTempInstance(); final ReadOnlyVector3 norm = triModel.getNormal(); if (orient != 0) { tempQuat.fromAngleNormalAxis(orient, norm); } for (int x = 0; x < 3; x++) { if (orient != 0) { tempQuat.apply(triModel.get(x), tempVec3); } else { tempVec3.set(triModel.get(x)); } tempVec3.multiplyLocal(currSize).addLocal(_position); BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + x); } Quaternion.releaseTempInstance(tempQuat); break; } case Triangle: { _position .subtract(3 * bbX.getX(), 3 * bbX.getY(), 3 * bbX.getZ(), tempVec3) .subtractLocal(bbY); BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 0); _position.add(bbX, tempVec3).addLocal(3 * bbY.getX(), 3 * bbY.getY(), 3 * bbY.getZ()); BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 1); _position.add(bbX, tempVec3).subtractLocal(bbY); BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 2); break; } case Line: { _position.subtract(bbX, tempVec3); BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex); _position.add(bbX, tempVec3); BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 1); break; } case Point: { BufferUtils.setInBuffer(_position, vertexBuffer, startIndex); break; } } Vector3.releaseTempInstance(tempVec3); }