use of org.joml.sampling.Callback2d in project lwjgl3-demos by LWJGL.
the class GrassDemo method generateGrassPatchVao.
private void generateGrassPatchVao() {
int n = NUM_FACES_PER_PATCH;
// Generate the model attributes of a single grass patch
FloatBuffer fb = BufferUtils.createFloatBuffer(NUM_FACES_PER_PATCH * 6 * (3 + 2));
for (int i = 0; i < n; i++) {
float x0 = (float) (Math.cos((double) i / n * Math.PI)) * 0.5f;
float z0 = (float) (Math.sin((double) i / n * Math.PI)) * 0.5f;
float x1 = (float) (Math.cos((double) i / n * Math.PI + Math.PI)) * 0.5f;
float z1 = (float) (Math.sin((double) i / n * Math.PI + Math.PI)) * 0.5f;
fb.put(x0).put(0.0f).put(z0).put(0).put(1);
fb.put(x1).put(0.0f).put(z1).put(1).put(1);
fb.put(x1).put(1.0f).put(z1).put(1).put(0);
fb.put(x1).put(1.0f).put(z1).put(1).put(0);
fb.put(x0).put(1.0f).put(z0).put(0).put(0);
fb.put(x0).put(0.0f).put(z0).put(0).put(1);
}
fb.flip();
// Generate the world-space positions of each patch
final FloatBuffer pb = BufferUtils.createFloatBuffer(NUM_GRASS_PATCHES * 4);
new BestCandidateSampling.Quad().numSamples(NUM_GRASS_PATCHES).numCandidates(20).generate(new Callback2d() {
final Random rnd = new Random(0L);
int index = 0;
public void onNewSample(float x, float y) {
float px = x * MEADOW_SIZE;
float py = y * MEADOW_SIZE;
grassPatchPositions[index++] = new Vector2f(px, py);
pb.put(x * MEADOW_SIZE).put(y * MEADOW_SIZE).put(rnd.nextFloat() * 0.2f + 0.9f).put((SimplexNoise.noise(x * 2.342f, y * 2.0352f) + 1.0f) * 0.5f);
}
});
pb.flip();
// Generate the random rotations for each grass patch
FloatBuffer rb = BufferUtils.createFloatBuffer(NUM_GRASS_PATCHES * 4);
Random rnd = new Random();
Matrix3x2f m = new Matrix3x2f();
for (int i = 0; i < NUM_GRASS_PATCHES; i++) {
float angle = 2.0f * (float) Math.PI * rnd.nextFloat();
m.rotation(angle);
rb.put(m.m00).put(m.m01).put(m.m10).put(m.m11);
}
rb.flip();
grassVao = ARBVertexArrayObject.glGenVertexArrays();
ARBVertexArrayObject.glBindVertexArray(grassVao);
int modelBuffer = glGenBuffers();
int grassBladesPositionsVbo = glGenBuffers();
grassDisplacementVbo = glGenBuffers();
int grassRotationVbo = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, modelBuffer);
glBufferData(GL_ARRAY_BUFFER, fb, GL_STATIC_DRAW);
glVertexAttribPointer(grassPositionAttribute, 3, GL_FLOAT, false, 4 * (3 + 2), 0L);
glVertexAttribPointer(grassTexCoordAttribute, 2, GL_FLOAT, false, 4 * (3 + 2), 4 * 3L);
glEnableVertexAttribArray(grassPositionAttribute);
glEnableVertexAttribArray(grassTexCoordAttribute);
glBindBuffer(GL_ARRAY_BUFFER, grassBladesPositionsVbo);
glBufferData(GL_ARRAY_BUFFER, pb, GL_STATIC_DRAW);
glVertexAttribPointer(grassWorldPositionAttribute, 4, GL_FLOAT, false, 0, 0L);
ARBInstancedArrays.glVertexAttribDivisorARB(grassWorldPositionAttribute, 1);
glEnableVertexAttribArray(grassWorldPositionAttribute);
glBindBuffer(GL_ARRAY_BUFFER, grassDisplacementVbo);
glBufferData(GL_ARRAY_BUFFER, 4 * 2 * NUM_GRASS_PATCHES, GL_STATIC_DRAW);
glVertexAttribPointer(grassDisplacementAttribute, 2, GL_FLOAT, false, 0, 0L);
ARBInstancedArrays.glVertexAttribDivisorARB(grassDisplacementAttribute, 1);
glEnableVertexAttribArray(grassDisplacementAttribute);
glBindBuffer(GL_ARRAY_BUFFER, grassRotationVbo);
glBufferData(GL_ARRAY_BUFFER, rb, GL_STATIC_DRAW);
glVertexAttribPointer(grassRotationAttribute, 4, GL_FLOAT, false, 0, 0L);
ARBInstancedArrays.glVertexAttribDivisorARB(grassRotationAttribute, 1);
glEnableVertexAttribArray(grassRotationAttribute);
glBindBuffer(GL_ARRAY_BUFFER, 0);
ARBVertexArrayObject.glBindVertexArray(0);
}
Aggregations