/** * A mapped data store must be unmapped with unmap before its buffer object is used. Otherwise an * error will be generated by any GL command that attempts to dereference the buffer object's data * store. When a data store is unmapped, the pointer to its data store becomes invalid. unmap * returns <code>true</code> unless the data store contents have become corrupt during the time * the data store was mapped. This can occur for system-specific reasons that affect the * availability of graphics memory, such as screen mode changes. In such situations, <code>false * </code> is returned and the data store contents are undefined. An application must detect this * rare condition and reinitialize the data store. * * <p>A buffer object's mapped data store is automatically unmapped when the buffer object is * deleted or its data store is recreated with data. * * @return */ public boolean unmap() { bind(); GL4 gl = GLGraphics.currentGL(); boolean myResult = gl.glUnmapBuffer(_myTarget.glID); unbind(); return myResult; }
public void writeCaps(GL4 gl, int capsArrayBuffer, int count) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(debugDir, "caps.txt")))) { // write counts and planes gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, capsArrayBuffer); ByteBuffer capsArray = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); for (int i = 0; i < count; i++) { Vector4f position = getVec4(capsArray, i * Scene.SIZEOF_CAP); Vector4f plane = getVec4(capsArray, i * Scene.SIZEOF_CAP + 16); int atomIdx = capsArray.getInt(i * Scene.SIZEOF_CAP + 32); int label = capsArray.getInt(i * Scene.SIZEOF_CAP + 36); int padding0 = capsArray.getInt(i * Scene.SIZEOF_CAP + 40); int padding1 = capsArray.getInt(i * Scene.SIZEOF_CAP + 44); writer.append(String.format("%4d: ", i)); writer.append( String.format( "position: [%f %f %f %f], ", position.x, position.y, position.z, position.w)); writer.append(String.format("plane: [%f %f %f %f], ", plane.x, plane.y, plane.z, plane.w)); writer.append(String.format("atomIdx: %d, label: %d", atomIdx, label)); writer.append(String.format(", padding0: %d, padding1: %d", padding0, padding1)); writer.newLine(); } // unbind buffers gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); } }
public void writeTori(GL4 gl, int toriArrayBuffer, int count) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(debugDir, "tori.txt")))) { // write tori gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, toriArrayBuffer); ByteBuffer toriArray = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); for (int i = 0; i < count; i++) { Vector4f position = getVec4(toriArray, i * Scene.SIZEOF_TORUS); float operation = toriArray.getFloat(i * Scene.SIZEOF_TORUS + 28); String op = (operation > 0f) ? "AND" : (operation < 0f) ? "OR " : "ISOLATED"; Vector4f plane1 = getVec4(toriArray, i * Scene.SIZEOF_TORUS + 48); Vector4f plane2 = getVec4(toriArray, i * Scene.SIZEOF_TORUS + 64); writer.append(String.format("%4d: ", i)); writer.append( String.format( "center: [%f %f %f], R: %f, ", position.x, position.y, position.z, position.w)); writer.append(String.format("op: %s, ", op)); writer.append( String.format("plane1: [%f %f %f %f], ", plane1.x, plane1.y, plane1.z, plane1.w)); writer.append( String.format("plane2: [%f %f %f %f]", plane2.x, plane2.y, plane2.z, plane2.w)); writer.newLine(); } gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); } }
/** * maps to the client's address space the entire data store of this buffer. The data can then be * directly read and/or written relative to the returned Buffer, depending on the specified access * policy. If the GL is unable to map the buffer object's data store, map generates an error and * returns <code>null</code>. This may occur for system-specific reasons, such as low virtual * memory availability. If no error occurs, the returned pointer will have an alignment of at * least GL_MIN_MAP_BUFFER_ALIGNMENT basic machine units. The value of GL_MIN_MAP_BUFFER_ALIGNMENT * can be retrieved by calling glGet with pname set to GL_MIN_MAP_BUFFER_ALIGNMENT and must be a * power of two that is at least 64. * * <p>If a mapped data store is accessed in a way inconsistent with the specified access policy, * no error is generated, but performance may be negatively impacted and system errors, including * program termination, may result. Unlike the usage parameter of data, access is not a hint, and * does in fact constrain the usage of the mapped data store on some GL implementations. In order * to achieve the highest performance available, a buffer object's data store should be used in * ways consistent with both its specified usage and access parameters. * * <p>A mapped data store must be unmapped with glUnmapBuffer before its buffer object is used. * Otherwise an error will be generated by any GL command that attempts to dereference the buffer * object's data store. When a data store is unmapped, the pointer to its data store becomes * invalid. unmap returns <code>true</code> unless the data store contents have become corrupt * during the time the data store was mapped. This can occur for system-specific reasons that * affect the availability of graphics memory, such as screen mode changes. In such situations, * <code>false</code> is returned and the data store contents are undefined. An application must * detect this rare condition and reinitialize the data store. * * <p>A buffer object's mapped data store is automatically unmapped when the buffer object is * deleted or its data store is recreated with data . * * @param theAccesMode * @return */ public ByteBuffer map(GLAccesMode theAccesMode) { bind(); GL4 gl = GLGraphics.currentGL(); ByteBuffer myResult = gl.glMapBuffer(_myTarget.glID, theAccesMode.glID()); // unbind(); return myResult; }
/** * maps all or part of the data store of a buffer object into the client's address space. offset * and length indicate the range of data in the buffer object that is to be mapped, in terms of * basic machine units. access is a bitfield containing flags which describe the requested * mapping. These flags are described below. * * <p>If no error occurs, a pointer to the beginning of the mapped range is returned once all * pending operations on that buffer have completed, and may be used to modify and/or query the * corresponding range of the buffer, according to the following flag bits set in access: * * <ul> * <li>{@linkplain #MAP_READ_BIT} * <li>{@linkplain #MAP_WRITE_BIT} * </ul> * * Furthermore, the following optional flag bits in access may be used to modify the mapping: * * <ul> * <li>{@linkplain #MAP_INVALIDATE_RANGE_BIT} * <li>{@linkplain #MAP_INVALIDATE_BUFFER_BIT} * <li>{@linkplain #MAP_FLUSH_EXPLICIT_BIT} * <li>{@linkplain #MAP_UNSYNCHRONIZED_BIT} * </ul> * * <p>If an error occurs, glMapBufferRange returns a NULL pointer. If no error occurs, the * returned pointer will reflect an alignment of at least GL_MIN_MAP_BUFFER_ALIGNMENT basic * machine units. The value of GL_MIN_MAP_BUFFER_ALIGNMENT can be retrieved by calling glGet with * pname set to GL_MIN_MAP_BUFFER_ALIGNMENT and must be a power of two that is at least 64. * Subtracting offset from this returned pointed will always produce a multiple of * GL_MIN_MAP_BUFFER_ALINMENT. */ public ByteBuffer mapRange(int theOffset, int theLength, int theAccess) { bind(); GL4 gl = GLGraphics.currentGL(); ByteBuffer myResult = gl.glMapBufferRange(_myTarget.glID, theOffset, theLength, theAccess); // unbind(); return myResult; }
public GLBuffer(GLBufferTarget theTarget) { GL4 gl = GLGraphics.currentGL(); gl.glGenBuffers(1, GLBufferUtil.intBuffer()); _myID = GLBufferUtil.intBuffer().get(0); _myTarget = theTarget; bind(); unbind(); }
public void allocate( long theBytes, GLDataAccesFrequency theAccessFrequency, GLDataAccesNature theAccessNature) { GL4 gl = GLGraphics.currentGL(); gl.glBufferData( GL.GL_ARRAY_BUFFER, theBytes, null, getAcessFrequencyNature(theAccessFrequency, theAccessNature)); }
/** * @param theOffset * @param theSize * @return */ public ByteBuffer getData(int theOffset, long theSize) { bind(); GL4 gl = GLGraphics.currentGL(); ByteBuffer myResult = ByteBuffer.allocate((int) theSize); gl.glGetBufferSubData(_myTarget.glID, theOffset, theSize, myResult); unbind(); return myResult; }
private boolean initProgram(GL4 gl4) { boolean validated = true; // Create program if (validated) { ShaderCode vertShaderCode = ShaderCode.create( gl4, GL_VERTEX_SHADER, this.getClass(), SHADERS_ROOT, null, SHADERS_SOURCE, "vert", null, true); ShaderCode fragShaderCode = ShaderCode.create( gl4, GL_FRAGMENT_SHADER, this.getClass(), SHADERS_ROOT, null, SHADERS_SOURCE, "frag", null, true); ShaderProgram shaderProgram = new ShaderProgram(); shaderProgram.init(gl4); programName[Program.VERTEX] = shaderProgram.program(); gl4.glProgramParameteri(programName[Program.VERTEX], GL_PROGRAM_SEPARABLE, GL_TRUE); shaderProgram.add(vertShaderCode); shaderProgram.link(gl4, System.out); shaderProgram = new ShaderProgram(); shaderProgram.init(gl4); programName[Program.FRAGMENT] = shaderProgram.program(); gl4.glProgramParameteri(programName[Program.FRAGMENT], GL_PROGRAM_SEPARABLE, GL_TRUE); shaderProgram.add(fragShaderCode); shaderProgram.link(gl4, System.out); } if (validated) { gl4.glGenProgramPipelines(1, pipelineName); gl4.glUseProgramStages( pipelineName.get(0), GL_VERTEX_SHADER_BIT, programName[Program.VERTEX]); gl4.glUseProgramStages( pipelineName.get(0), GL_FRAGMENT_SHADER_BIT, programName[Program.FRAGMENT]); } return validated & checkError(gl4, "initProgram"); }
/** * Creates and initializes a buffer object's data store. Creates a new data store for the buffer * object currently bound to target. Any pre-existing data store is deleted. The new data store is * created with the specified size in bytes and usage. If data is not <code>null</code>, the data * store is initialized with data from this Buffer. In its initial state, the new data store is * not mapped, it has a <code>null</code> mapped pointer, and its mapped access is GL_READ_WRITE. * * <p>usage is a hint to the GL implementation as to how a buffer object's data store will be * accessed. This enables the GL implementation to make more intelligent decisions that may * significantly impact buffer object performance. It does not, however, constrain the actual * usage of the data store. usage can be broken down into two parts: first, the frequency of * access (modification and usage), and second, the nature of that access. * * @param theSize Specifies the size in bytes of the buffer object's new data store. * @param theData Specifies a Buffer with data that will be copied into the data store for * initialization, or null if no data is to be copied. * @param theAccessFrequency The frequency of gl data access * @param theAccessNature The nature of gl data access */ public void data( long theSize, Buffer theData, GLDataAccesFrequency theAccessFrequency, GLDataAccesNature theAccessNature) { GL4 gl = GLGraphics.currentGL(); gl.glBufferData( _myTarget.glID, theSize, theData, getAcessFrequencyNature(theAccessFrequency, theAccessNature)); _mySize = theSize; }
public void writeDebugi(GL4 gl, int buffer, int count) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(debugDir, "debug.txt")))) { // write debug gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); IntBuffer debug = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY).asIntBuffer(); for (int i = 0; i < count; i++) { writer.append(String.format("%4d: %8d", i, debug.get(i))); writer.newLine(); } gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); } }
public void writeDebug4f(GL4 gl, int buffer, int count) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(debugDir, "debug.txt")))) { // write debug gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); ByteBuffer debug = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); for (int i = 0; i < count; i++) { Vector4f v = getVec4(debug, i * 16); writer.append(String.format("%4d: [%f %f %f %f]", i, v.x, v.y, v.z, v.w)); writer.newLine(); } gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); } }
/** * Binds the buffer object buffer to the binding point at index index of the array of targets * specified by target. Each target represents an indexed array of buffer binding points, as well * as a single general binding point that can be used by other buffer manipulation functions such * as glBindBuffer or glMapBuffer. In addition to binding buffer to the indexed buffer binding * target, glBindBufferBase also binds buffer to the generic buffer binding point specified by * target. * * @param theTarget * @param theIndex */ public void bindBufferBase(GLBufferTarget theTarget, int theIndex) { switch (theTarget) { case ATOMIC_COUNTER: case TRANSFORM_FEEDBACK: case UNIFORM: case SHADER_STORAGE: break; default: throw new GLException("Unsupported target for bindBufferBase"); } bind(); GL4 gl = GLGraphics.currentGL(); gl.glBindBufferBase(theTarget.glID, theIndex, _myID); unbind(); }
private boolean initProgram(GL4 gl4) { boolean validated = true; try { if (validated) { String[] vertexSourceContent = new String[] { new Scanner(new File(SHADERS_ROOT + "/" + SHADERS_SOURCE + ".vert")) .useDelimiter("\\A") .next() }; programName[Program.VERT.ordinal()] = gl4.glCreateShaderProgramv(GL_VERTEX_SHADER, 1, vertexSourceContent); } if (validated) { String[] fragmentSourceContent = new String[] { new Scanner(new File(SHADERS_ROOT + "/" + SHADERS_SOURCE + ".frag")) .useDelimiter("\\A") .next() }; programName[Program.FRAG.ordinal()] = gl4.glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, fragmentSourceContent); } if (validated) { validated = validated && checkProgram(gl4, programName[Program.VERT.ordinal()]); validated = validated && checkProgram(gl4, programName[Program.FRAG.ordinal()]); } if (validated) { uniformMvp = gl4.glGetUniformLocation(programName[Program.VERT.ordinal()], "mvp"); uniformDiffuse = gl4.glGetUniformLocation(programName[Program.FRAG.ordinal()], "diffuse"); } if (validated) { gl4.glGenProgramPipelines(1, pipelineName, 0); gl4.glBindProgramPipeline(pipelineName[0]); gl4.glUseProgramStages( pipelineName[0], GL_VERTEX_SHADER_BIT, programName[Program.VERT.ordinal()]); gl4.glUseProgramStages( pipelineName[0], GL_FRAGMENT_SHADER_BIT, programName[Program.FRAG.ordinal()]); } } catch (FileNotFoundException ex) { Logger.getLogger(Gl_410_program_64.class.getName()).log(Level.SEVERE, null, ex); } return validated && checkError(gl4, "initProgram"); }
public void writeAtomsVisible(GL4 gl, int atomsVisibleBuffer, int atomCount) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(debugDir, "atoms.txt")))) { // write tori gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, atomsVisibleBuffer); IntBuffer atomsVisible = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY).asIntBuffer(); for (int i = 0; i < atomCount; i++) { int visible = atomsVisible.get(i); writer.append(String.format("%4d: ", i)); if (visible == 1) { writer.append("1"); } writer.newLine(); } gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); } }
public void writeTriangles(GL4 gl, int trianglesArrayBuffer, int count) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(debugDir, "triangles.txt")))) { // write triangles gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, trianglesArrayBuffer); ByteBuffer triangleArray = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); for (int i = 0; i < count; i++) { Vector4f position = getVec4(triangleArray, i * Scene.SIZEOF_TRIANGLE); writer.append(String.format("%4d: ", i)); writer.append( String.format( "position: [%f %f %f %f]", position.x, position.y, position.z, position.w)); writer.newLine(); } gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); } }
public static void checkGridOverflow( GL4 gl, int gridCountsBuffer, int cellCount, int maxCellAtomCount) { // read counts gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, gridCountsBuffer); ByteBuffer data = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); int counts[] = new int[cellCount]; data.asIntBuffer().get(counts); gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); // check counts for (int c = 0; c < cellCount; c++) { if (counts[c] >= maxCellAtomCount) { System.err.println( "Warning: possible grid cell overflow. Cell: " + c + ", atom count: " + counts[c]); } } }
public void writePolygons(GL4 gl, int spheresArrayBuffer, int count) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(debugDir, "polygons.txt")))) { // write polygons gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, spheresArrayBuffer); ByteBuffer polygonsArray = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); for (int i = 0; i < count; i++) { int index = polygonsArray.getInt(i * Scene.SIZEOF_POLYGON + 16); int label = polygonsArray.getInt(i * Scene.SIZEOF_POLYGON + 20); int circleStart = polygonsArray.getInt(i * Scene.SIZEOF_POLYGON + 24); int circleLength = polygonsArray.getInt(i * Scene.SIZEOF_POLYGON + 28); writer.append(String.format("%4d: ", i)); writer.append(String.format("index: %4d, ", index)); writer.append(String.format("label: %4d, ", label)); writer.append(String.format("circle: [%6d, %2d]", circleStart, circleLength)); writer.newLine(); } gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); } }
public static void checkNeighborsOverflow( GL4 gl, int neighborCountsBuffer, int sphereCount, int maxNeighborCount) { // read counts gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, neighborCountsBuffer); ByteBuffer data = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); int counts[] = new int[sphereCount]; data.asIntBuffer().get(counts); gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); // check counts for (int s = 0; s < sphereCount; s++) { if (counts[s] >= maxNeighborCount) { System.err.println( "Warning: possible neighbors overflow. Sphere: " + s + ", neighbor count: " + counts[s]); } } }
public void setupBuffers(GL4 gl, int[] vbo, int index) { this.vbo = vbo; this.index = index; Vertex3D[] vertices = myShape.getVertices(); int[] indices = myShape.getIndices(); float[] fvalues = new float[indices.length * 3]; float[] tvalues = new float[indices.length * 2]; float[] nvalues = new float[indices.length * 3]; for (int i = 0; i < indices.length; i++) { fvalues[i * 3] = (float) (vertices[indices[i]]).getX(); fvalues[i * 3 + 1] = (float) (vertices[indices[i]]).getY(); fvalues[i * 3 + 2] = (float) (vertices[indices[i]]).getZ(); tvalues[i * 2] = (float) (vertices[indices[i]]).getS(); tvalues[i * 2 + 1] = (float) (vertices[indices[i]]).getT(); nvalues[i * 3] = (float) (vertices[indices[i]]).getNormalX(); nvalues[i * 3 + 1] = (float) (vertices[indices[i]]).getNormalY(); nvalues[i * 3 + 2] = (float) (vertices[indices[i]]).getNormalZ(); } gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo[index++]); FloatBuffer vertBuf = FloatBuffer.wrap(fvalues); gl.glBufferData(GL.GL_ARRAY_BUFFER, vertBuf.limit() * 4, vertBuf, GL.GL_STATIC_DRAW); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo[index++]); FloatBuffer texBuf = FloatBuffer.wrap(tvalues); gl.glBufferData(GL.GL_ARRAY_BUFFER, texBuf.limit() * 4, texBuf, GL.GL_STATIC_DRAW); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo[index++]); FloatBuffer norBuf = FloatBuffer.wrap(nvalues); gl.glBufferData(GL.GL_ARRAY_BUFFER, norBuf.limit() * 4, norBuf, GL.GL_STATIC_DRAW); }
public void writeArcs(GL4 gl, int neighborsCountBuffer, int atomCount, int arcsCountBuffer) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(debugDir, "arcs.txt")))) { // read counts gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, neighborsCountBuffer); ByteBuffer data = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); int neighborCounts[] = new int[atomCount]; data.asIntBuffer().get(neighborCounts); gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); // write arcs gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, arcsCountBuffer); IntBuffer arcsCounts = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY).asIntBuffer(); for (int i = 0; i < atomCount; i++) { int totalArcs = 0; List<Integer> counts = new ArrayList<>(); for (int j = 0; j < neighborCounts[i]; j++) { int count = arcsCounts.get(i * Scene.MAX_NEIGHBORS + j); counts.add(count); totalArcs += count; } writer.append(String.format("%4d (%2d): ", i, totalArcs)); for (int count : counts) { writer.append(String.format("%3d", count)); } writer.newLine(); } gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); } }
public void writeSphereIsolated( GL4 gl, int sphereIsolatedCountsBuffer, int sphereIsolatedVSBuffer, int atomCount) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(debugDir, "sphere-isolated.txt")))) { // read counts gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, sphereIsolatedCountsBuffer); ByteBuffer data = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); int counts[] = new int[atomCount]; data.asIntBuffer().get(counts); gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); // write counts and indices gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, sphereIsolatedVSBuffer); ByteBuffer vsData = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); for (int i = 0; i < counts.length; i++) { writer.append(String.format("%4d (%2d): ", i, counts[i])); for (int j = 0; j < counts[i]; j++) { Vector4f vs = getVec4(vsData, (i * Scene.MAX_SPHERE_ISOLATED_TORI + j) * Scene.SIZEOF_VEC4); writer.append(String.format("vs: [%f %f %f %f], ", vs.x, vs.y, vs.z, vs.w)); } writer.newLine(); } gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); } }
public void writeSphereCapPlanes( GL4 gl, int sphereCapCountsBuffer, int sphereCapPlanesBuffer, int atomCount) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(debugDir, "sphere-caps.txt")))) { // read counts gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, sphereCapCountsBuffer); ByteBuffer data = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); int counts[] = new int[atomCount]; data.asIntBuffer().get(counts); gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); // write counts and planes gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, sphereCapPlanesBuffer); ByteBuffer planesData = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); for (int i = 0; i < counts.length; i++) { writer.append(String.format("%4d (%2d): ", i, counts[i])); for (int j = 0; j < counts[i]; j++) { Vector4f plane = getVec4(planesData, (i * GPUGraph.MAX_SPHERE_POLYGON_COUNT + j) * Scene.SIZEOF_VEC4); writer.append( String.format("plane: [%f %f %f %f], ", plane.x, plane.y, plane.z, plane.w)); } writer.newLine(); } // unbind buffers gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); } }
public void writeNeighbors( GL4 gl, int neighborsBuffer, int neighborCountsBuffer, int sphereCount, String filename) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(debugDir, filename)))) { // read counts gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, neighborCountsBuffer); ByteBuffer data = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); int counts[] = new int[sphereCount]; data.asIntBuffer().get(counts); gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); // write counts and indices gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, neighborsBuffer); IntBuffer neighbors = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY).asIntBuffer(); Set<Integer> neighborIndices = new LinkedHashSet<>(); for (int i = 0; i < sphereCount; i++) { if (counts[i] > 0) { writer.append(String.format("%4d (%2d): ", i, counts[i])); neighborIndices.clear(); for (int j = 0; j < counts[i]; j++) { neighborIndices.add(neighbors.get(Scene.MAX_NEIGHBORS * i + j)); } for (Integer index : neighborIndices) { writer.append(String.format("%6d", index)); } writer.newLine(); } } gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); } }
public void writeGrid(String filename, GL4 gl, int gridCountsBuffer, int gridIndicesBuffer) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(new File(debugDir, filename)))) { // read counts gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, gridCountsBuffer); ByteBuffer data = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); int counts[] = new int[Scene.CELL_COUNT]; data.asIntBuffer().get(counts); gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); // write counts and indices gl.glBindBuffer(GL_SHADER_STORAGE_BUFFER, gridIndicesBuffer); IntBuffer indices = gl.glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY).asIntBuffer(); Set<Integer> cellIndices = new TreeSet<>(); for (int i = 0; i < Scene.CELL_COUNT; i++) { if (counts[i] > 0) { int x = i / Scene.GRID_SIZE / Scene.GRID_SIZE; int y = (i / Scene.GRID_SIZE) % Scene.GRID_SIZE; int z = i % Scene.GRID_SIZE; writer.append(String.format("[%2d,%2d,%2d] (%2d): ", x, y, z, counts[i])); cellIndices.clear(); for (int j = 0; j < counts[i]; j++) { cellIndices.add(indices.get(Scene.MAX_CELL_ATOMS * i + j)); } for (Integer index : cellIndices) { writer.append(String.format("%6d", index)); } writer.newLine(); } } gl.glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); } }
@Override protected boolean render(GL gl) { GL4 gl4 = (GL4) gl; FloatUtil.makePerspective( projection, 0, true, (float) Math.PI * 0.25f, (float) windowSize.x / windowSize.y, 0.1f, 100.0f); view = view(); FloatUtil.makeIdentity(model); FloatUtil.multMatrix(projection, view); FloatUtil.multMatrix(projection, model); for (int i = 0; i < projection.length; i++) { mvp[i] = projection[i]; } gl4.glProgramUniformMatrix4dv( programName[Program.VERT.ordinal()], uniformMvp, 1, false, mvp, 0); gl4.glProgramUniform4dv( programName[Program.FRAG.ordinal()], uniformDiffuse, 1, new double[] {1.0f, 0.5f, 0.0f, 1.0f}, 0); gl4.glViewportIndexedfv(0, new float[] {0, 0, windowSize.x, windowSize.y}, 0); gl4.glClearBufferfv(GL_COLOR, 0, new float[] {0.0f, 0.0f, 0.0f, 0.0f}, 0); gl4.glBindProgramPipeline(pipelineName[0]); gl4.glBindVertexArray(vertexArrayName[0]); gl4.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferName[Buffer.ELEMENT.ordinal()]); gl4.glDrawElementsInstancedBaseVertex(GL_TRIANGLES, elementCount, GL_UNSIGNED_SHORT, 0, 1, 0); return true; }
@Override protected boolean begin(GL gl) { GL4 gl4 = (GL4) gl; boolean validated = true; validated = validated && gl4.isExtensionAvailable("GL_ARB_internalformat_query2"); long[] query_COMPRESSED_RGB8_ETC2 = {0}; gl4.glGetInternalformati64v( GL_TEXTURE_2D, GL_RGB4, GL_INTERNALFORMAT_PREFERRED, Long.BYTES, query_COMPRESSED_RGB8_ETC2, 0); long[] query_RGBA8 = {0}; gl4.glGetInternalformati64v(GL_TEXTURE_2D, GL_RGBA8, GL_FILTER, Long.BYTES, query_RGBA8, 0); long[] query_COMPRESSED_RGBA_BPTC_UNORM = {0}; gl4.glGetInternalformati64v( GL_TEXTURE_2D, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, Long.BYTES, query_COMPRESSED_RGBA_BPTC_UNORM, 0); if (query_COMPRESSED_RGBA_BPTC_UNORM[0] > 0) { long[] query_SamplesCOMPRESSED_RGBA_BPTC_UNORM = new long[(int) query_COMPRESSED_RGBA_BPTC_UNORM[0]]; gl4.glGetInternalformati64v( GL_TEXTURE_2D, GL_RGBA8, GL_SAMPLES, Long.BYTES, query_SamplesCOMPRESSED_RGBA_BPTC_UNORM, 0); } if (validated) { validated = initProgram(gl4); } if (validated) { validated = initBuffer(gl4); } if (validated) { validated = initVertexArray(gl4); } if (validated) { validated = initTexture(gl4); } return validated; }
private boolean initVertexArray(GL4 gl4) { boolean validated = true; gl4.glGenVertexArrays(1, vertexArrayName); gl4.glBindVertexArray(vertexArrayName.get(0)); { gl4.glBindBuffer(GL_ARRAY_BUFFER, bufferName.get(Buffer.VERTEX)); gl4.glVertexAttribPointer(Semantic.Attr.POSITION, 2, GL_FLOAT, false, 2 * Vec2.SIZE, 0); gl4.glVertexAttribPointer( Semantic.Attr.TEXCOORD, 2, GL_FLOAT, false, 2 * Vec2.SIZE, Vec2.SIZE); gl4.glBindBuffer(GL_ARRAY_BUFFER, 0); gl4.glEnableVertexAttribArray(Semantic.Attr.POSITION); gl4.glEnableVertexAttribArray(Semantic.Attr.TEXCOORD); gl4.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferName.get(Buffer.ELEMENT)); } gl4.glBindVertexArray(0); return validated; }
private boolean initVertexBuffer(GL4 gl4) { gl4.glGenBuffers(Buffer.MAX.ordinal(), bufferName, 0); gl4.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferName[Buffer.ELEMENT.ordinal()]); ShortBuffer elementBuffer = GLBuffers.newDirectShortBuffer(elementData); gl4.glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementSize, elementBuffer, GL_STATIC_DRAW); gl4.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); gl4.glBindBuffer(GL_ARRAY_BUFFER, bufferName[Buffer.F64.ordinal()]); DoubleBuffer positionBuffer = GLBuffers.newDirectDoubleBuffer(positionData); gl4.glBufferData(GL_ARRAY_BUFFER, positionSize, positionBuffer, GL_STATIC_DRAW); gl4.glBindBuffer(GL_ARRAY_BUFFER, 0); return checkError(gl4, "initArrayBuffer"); }
private boolean initVertexArray(GL4 gl4) { gl4.glGenVertexArrays(1, vertexArrayName, 0); gl4.glBindVertexArray(vertexArrayName[0]); { gl4.glBindBuffer(GL_ARRAY_BUFFER, bufferName[Buffer.F64.ordinal()]); gl4.glVertexAttribLPointer(Semantic.Attr.POSITION, 3, GL_DOUBLE, 3 * Double.BYTES, 0); gl4.glBindBuffer(GL_ARRAY_BUFFER, 0); gl4.glEnableVertexAttribArray(Semantic.Attr.POSITION); } gl4.glBindVertexArray(0); return checkError(gl4, "initVertexArray"); }