All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.dabasan.joglf.gl.draw.DrawFunctions3D Maven / Gradle / Ivy

There is a newer version: 11.7.0
Show newest version
package com.github.dabasan.joglf.gl.draw;

import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;

import com.github.dabasan.basis.coloru8.ColorU8;
import com.github.dabasan.basis.coloru8.ColorU8Functions;
import com.github.dabasan.basis.matrix.Matrix;
import com.github.dabasan.basis.matrix.MatrixFunctions;
import com.github.dabasan.basis.vector.Vector;
import com.github.dabasan.basis.vector.VectorFunctions;
import com.github.dabasan.joglf.gl.shader.ShaderProgram;
import com.github.dabasan.joglf.gl.shape.Quadrangle;
import com.github.dabasan.joglf.gl.shape.Triangle;
import com.github.dabasan.joglf.gl.shape.Vertex3D;
import com.github.dabasan.joglf.gl.wrapper.GLWrapper;
import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.GL;

/**
 * Draw functions for 3D primitives
 * 
 * @author Daba
 *
 */
public class DrawFunctions3D {
	private static ShaderProgram color_program;
	private static ShaderProgram texture_program;

	/**
	 * Initialization
* You don't have to call this method by yourself. */ public static void Initialize() { color_program = new ShaderProgram("color"); texture_program = new ShaderProgram("texture"); } /** * Draws a line. * * @param line_pos_1 * Start pos * @param line_pos_2 * End pos * @param color_1 * Start color * @param color_2 * End color */ public static void DrawLine3D(Vector line_pos_1, Vector line_pos_2, ColorU8 color_1, ColorU8 color_2) { final IntBuffer pos_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer color_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer vao = Buffers.newDirectIntBuffer(1); final FloatBuffer pos_buffer = Buffers.newDirectFloatBuffer(6); final FloatBuffer color_buffer = Buffers.newDirectFloatBuffer(8); pos_buffer.put(line_pos_1.GetX()); pos_buffer.put(line_pos_1.GetY()); pos_buffer.put(line_pos_1.GetZ()); pos_buffer.put(line_pos_2.GetX()); pos_buffer.put(line_pos_2.GetY()); pos_buffer.put(line_pos_2.GetZ()); color_buffer.put(color_1.GetR()); color_buffer.put(color_1.GetG()); color_buffer.put(color_1.GetB()); color_buffer.put(color_1.GetA()); color_buffer.put(color_2.GetR()); color_buffer.put(color_2.GetG()); color_buffer.put(color_2.GetB()); color_buffer.put(color_2.GetA()); pos_buffer.flip(); color_buffer.flip(); GLWrapper.glGenBuffers(1, pos_vbo); GLWrapper.glGenBuffers(1, color_vbo); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, pos_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT * pos_buffer.capacity(), pos_buffer, GL.GL_STATIC_DRAW); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, color_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT * color_buffer.capacity(), color_buffer, GL.GL_STATIC_DRAW); GLWrapper.glGenVertexArrays(1, vao); GLWrapper.glBindVertexArray(vao.get(0)); // Position attribute GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, pos_vbo.get(0)); GLWrapper.glEnableVertexAttribArray(0); GLWrapper.glVertexAttribPointer(0, 3, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * 3, 0); // Color attribute GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, color_vbo.get(0)); GLWrapper.glEnableVertexAttribArray(1); GLWrapper.glVertexAttribPointer(1, 4, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * 4, 0); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); GLWrapper.glBindVertexArray(0); // Draw GLWrapper.glBindVertexArray(vao.get(0)); GLWrapper.glEnable(GL.GL_BLEND); color_program.Enable(); GLWrapper.glDrawArrays(GL.GL_LINES, 0, 2); color_program.Disable(); GLWrapper.glDisable(GL.GL_BLEND); GLWrapper.glBindVertexArray(0); // Delete buffers GLWrapper.glDeleteBuffers(1, pos_vbo); GLWrapper.glDeleteBuffers(1, color_vbo); GLWrapper.glDeleteVertexArrays(1, vao); } /** * Draws a line. * * @param line_pos_1 * Start pos * @param line_pos_2 * End pos * @param color * Color */ public static void DrawLine3D(Vector line_pos_1, Vector line_pos_2, ColorU8 color) { DrawLine3D(line_pos_1, line_pos_2, color, color); } /** * Draw the axes (X, Y and Z). * * @param length * Length of each axis (starting from the origin) */ public static void DrawAxes(float length) { DrawLine3D(VectorFunctions.VGet(-length, 0.0f, 0.0f), VectorFunctions.VGet(length, 0.0f, 0.0f), ColorU8Functions.GetColorU8(1.0f, 0.0f, 0.0f, 1.0f)); DrawLine3D(VectorFunctions.VGet(0.0f, -length, 0.0f), VectorFunctions.VGet(0.0f, length, 0.0f), ColorU8Functions.GetColorU8(0.0f, 1.0f, 0.0f, 1.0f)); DrawLine3D(VectorFunctions.VGet(0.0f, 0.0f, -length), VectorFunctions.VGet(0.0f, 0.0f, length), ColorU8Functions.GetColorU8(0.0f, 0.0f, 1.0f, 1.0f)); } /** * Draws the axes in the positive directions (X+, Y+ and Z+). * * @param length * Length of each axis (starting from the origin) */ public static void DrawAxes_Positive(float length) { DrawLine3D(VectorFunctions.VGet(0.0f, 0.0f, 0.0f), VectorFunctions.VGet(length, 0.0f, 0.0f), ColorU8Functions.GetColorU8(1.0f, 0.0f, 0.0f, 1.0f)); DrawLine3D(VectorFunctions.VGet(0.0f, 0.0f, 0.0f), VectorFunctions.VGet(0.0f, length, 0.0f), ColorU8Functions.GetColorU8(0.0f, 1.0f, 0.0f, 1.0f)); DrawLine3D(VectorFunctions.VGet(0.0f, 0.0f, 0.0f), VectorFunctions.VGet(0.0f, 0.0f, length), ColorU8Functions.GetColorU8(0.0f, 0.0f, 1.0f, 1.0f)); } /** * Draws the axes in the negative directions (X-, Y- and Z-). * * @param length * Length of each axis (starting from the origin) */ public static void DrawAxes_Negative(float length) { DrawLine3D(VectorFunctions.VGet(-length, 0.0f, 0.0f), VectorFunctions.VGet(0.0f, 0.0f, 0.0f), ColorU8Functions.GetColorU8(1.0f, 0.0f, 0.0f, 1.0f)); DrawLine3D(VectorFunctions.VGet(0.0f, -length, 0.0f), VectorFunctions.VGet(0.0f, 0.0f, 0.0f), ColorU8Functions.GetColorU8(0.0f, 1.0f, 0.0f, 1.0f)); DrawLine3D(VectorFunctions.VGet(0.0f, 0.0f, -length), VectorFunctions.VGet(0.0f, 0.0f, 0.0f), ColorU8Functions.GetColorU8(0.0f, 0.0f, 1.0f, 1.0f)); } /** * Draws a triangle. * * @param triangle * Triangle */ public static void DrawTriangle3D(Triangle triangle) { final IntBuffer pos_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer color_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer vao = Buffers.newDirectIntBuffer(1); final Vertex3D[] vertices = triangle.GetVertices(); final FloatBuffer pos_buffer = Buffers.newDirectFloatBuffer(9); final FloatBuffer color_buffer = Buffers.newDirectFloatBuffer(12); for (int i = 0; i < 3; i++) { final Vector pos = vertices[i].GetPos(); final ColorU8 dif = vertices[i].GetDif(); pos_buffer.put(pos.GetX()); pos_buffer.put(pos.GetY()); pos_buffer.put(pos.GetZ()); color_buffer.put(dif.GetR()); color_buffer.put(dif.GetG()); color_buffer.put(dif.GetB()); color_buffer.put(dif.GetA()); } pos_buffer.flip(); color_buffer.flip(); GLWrapper.glGenBuffers(1, pos_vbo); GLWrapper.glGenBuffers(1, color_vbo); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, pos_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT * pos_buffer.capacity(), pos_buffer, GL.GL_STATIC_DRAW); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, color_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT * color_buffer.capacity(), color_buffer, GL.GL_STATIC_DRAW); GLWrapper.glGenVertexArrays(1, vao); GLWrapper.glBindVertexArray(vao.get(0)); // Position attribute GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, pos_vbo.get(0)); GLWrapper.glEnableVertexAttribArray(0); GLWrapper.glVertexAttribPointer(0, 3, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * 3, 0); // Color attribute GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, color_vbo.get(0)); GLWrapper.glEnableVertexAttribArray(1); GLWrapper.glVertexAttribPointer(1, 4, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * 4, 0); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); GLWrapper.glBindVertexArray(0); // Draw GLWrapper.glBindVertexArray(vao.get(0)); GLWrapper.glEnable(GL.GL_BLEND); color_program.Enable(); GLWrapper.glDrawArrays(GL.GL_LINE_LOOP, 0, 3); color_program.Disable(); GLWrapper.glDisable(GL.GL_BLEND); GLWrapper.glBindVertexArray(0); // Delete buffers GLWrapper.glDeleteBuffers(1, pos_vbo); GLWrapper.glDeleteBuffers(1, color_vbo); GLWrapper.glDeleteVertexArrays(1, vao); } /** * Draws a triangle. * * @param triangle_pos_1 * Vertex 1 * @param triangle_pos_2 * Vertex 2 * @param triangle_pos_3 * Vertex 3 * @param color * Color */ public static void DrawTriangle3D(Vector triangle_pos_1, Vector triangle_pos_2, Vector triangle_pos_3, ColorU8 color) { final Triangle triangle = new Triangle(); triangle.GetVertex(0).SetPos(triangle_pos_1); triangle.GetVertex(1).SetPos(triangle_pos_2); triangle.GetVertex(2).SetPos(triangle_pos_3); for (int i = 0; i < 3; i++) { triangle.GetVertex(i).SetDif(color); } DrawTriangle3D(triangle); } /** * Draws a quadrangle. * * @param quadrangle * Quadrangle */ public static void DrawQuadrangle3D(Quadrangle quadrangle) { final IntBuffer pos_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer color_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer vao = Buffers.newDirectIntBuffer(1); final Vertex3D[] vertices = quadrangle.GetVertices(); final FloatBuffer pos_buffer = Buffers.newDirectFloatBuffer(12); final FloatBuffer color_buffer = Buffers.newDirectFloatBuffer(16); for (int i = 0; i < 4; i++) { final Vector pos = vertices[i].GetPos(); final ColorU8 dif = vertices[i].GetDif(); pos_buffer.put(pos.GetX()); pos_buffer.put(pos.GetY()); pos_buffer.put(pos.GetZ()); color_buffer.put(dif.GetR()); color_buffer.put(dif.GetG()); color_buffer.put(dif.GetB()); color_buffer.put(dif.GetA()); } pos_buffer.flip(); color_buffer.flip(); GLWrapper.glGenBuffers(1, pos_vbo); GLWrapper.glGenBuffers(1, color_vbo); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, pos_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT * pos_buffer.capacity(), pos_buffer, GL.GL_STATIC_DRAW); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, color_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT * color_buffer.capacity(), color_buffer, GL.GL_STATIC_DRAW); GLWrapper.glGenVertexArrays(1, vao); GLWrapper.glBindVertexArray(vao.get(0)); // Position attribute GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, pos_vbo.get(0)); GLWrapper.glEnableVertexAttribArray(0); GLWrapper.glVertexAttribPointer(0, 3, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * 3, 0); // Color attribute GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, color_vbo.get(0)); GLWrapper.glEnableVertexAttribArray(1); GLWrapper.glVertexAttribPointer(1, 4, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * 4, 0); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); GLWrapper.glBindVertexArray(0); // Draw GLWrapper.glBindVertexArray(vao.get(0)); GLWrapper.glEnable(GL.GL_BLEND); color_program.Enable(); GLWrapper.glDrawArrays(GL.GL_LINE_LOOP, 0, 4); color_program.Disable(); GLWrapper.glDisable(GL.GL_BLEND); GLWrapper.glBindVertexArray(0); // Delete buffers GLWrapper.glDeleteBuffers(1, pos_vbo); GLWrapper.glDeleteBuffers(1, color_vbo); GLWrapper.glDeleteVertexArrays(1, vao); } /** * Draws a quadrangle. * * @param quadrangle_pos_1 * Vertex 1 * @param quadrangle_pos_2 * Vertex 2 * @param quadrangle_pos_3 * Vertex 3 * @param quadrangle_pos_4 * Vertex 4 * @param color * Color */ public static void DrawQuadrangle3D(Vector quadrangle_pos_1, Vector quadrangle_pos_2, Vector quadrangle_pos_3, Vector quadrangle_pos_4, ColorU8 color) { final Quadrangle quadrangle = new Quadrangle(); quadrangle.GetVertex(0).SetPos(quadrangle_pos_1); quadrangle.GetVertex(1).SetPos(quadrangle_pos_2); quadrangle.GetVertex(2).SetPos(quadrangle_pos_3); quadrangle.GetVertex(3).SetPos(quadrangle_pos_4); for (int i = 0; i < 4; i++) { quadrangle.GetVertex(i).SetDif(color); } DrawQuadrangle3D(quadrangle); } /** * Draws a sphere. * * @param center * Center * @param radius * Radius * @param slice_num * Number of divisions in the longitudinal direction * @param stack_num * Number of divisions in the latitudinal direction * @param color * Color */ public static void DrawSphere3D(Vector center, float radius, int slice_num, int stack_num, ColorU8 color) { final List vertices = new ArrayList<>(); final List indices = new ArrayList<>(); final int vertex_num = slice_num * (stack_num - 1) + 2; // North pole vertices.add(VectorFunctions.VGet(0.0f, 1.0f, 0.0f)); // Middle for (int i = 1; i < stack_num; i++) { final float ph = (float) Math.PI * i / stack_num; final float y = (float) Math.cos(ph); final float r = (float) Math.sin(ph); for (int j = 0; j < slice_num; j++) { final float th = 2.0f * (float) Math.PI * j / slice_num; final float x = r * (float) Math.cos(th); final float z = r * (float) Math.sin(th); vertices.add(VectorFunctions.VGet(x, y, z)); } } // South pole vertices.add(VectorFunctions.VGet(0.0f, -1.0f, 0.0f)); for (int i = 0; i < vertex_num; i++) { Vector vertex = vertices.get(i); vertex = VectorFunctions.VScale(vertex, radius); vertex = VectorFunctions.VAdd(vertex, center); vertices.set(i, vertex); } // Ridgelines around the north pole for (int i = 1; i <= slice_num; i++) { indices.add(0); indices.add(i); } // Ridgelines in the middle int count = 1; for (int i = 2; i < stack_num; i++) { for (int j = 1; j < slice_num; j++) { indices.add(count); indices.add(count + 1); indices.add(count); indices.add(count + slice_num); count++; } indices.add(count); indices.add(count - slice_num + 1); indices.add(count); indices.add(count + slice_num); count++; } // Ridgelines in the bottom for (int i = 1; i < slice_num; i++) { indices.add(count); indices.add(count + 1); indices.add(count); indices.add(vertex_num - 1); count++; } indices.add(count); indices.add(count - slice_num + 1); indices.add(count); indices.add(vertex_num - 1); // Make buffers. final IntBuffer indices_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer pos_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer color_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer vao = Buffers.newDirectIntBuffer(1); final IntBuffer indices_buffer = Buffers.newDirectIntBuffer(indices.size()); final FloatBuffer pos_buffer = Buffers.newDirectFloatBuffer(vertices.size() * 3); final FloatBuffer color_buffer = Buffers.newDirectFloatBuffer(indices.size() * 4); final int indices_size = indices.size(); for (int i = 0; i < indices_size; i++) { indices_buffer.put(indices.get(i)); } for (int i = 0; i < vertex_num; i++) { final Vector vertex = vertices.get(i); pos_buffer.put(vertex.GetX()); pos_buffer.put(vertex.GetY()); pos_buffer.put(vertex.GetZ()); } final float color_r = color.GetR(); final float color_g = color.GetG(); final float color_b = color.GetB(); final float color_a = color.GetA(); for (int i = 0; i < indices_size; i++) { color_buffer.put(color_r); color_buffer.put(color_g); color_buffer.put(color_b); color_buffer.put(color_a); } indices_buffer.flip(); pos_buffer.flip(); color_buffer.flip(); GLWrapper.glGenBuffers(1, indices_vbo); GLWrapper.glGenBuffers(1, pos_vbo); GLWrapper.glGenBuffers(1, color_vbo); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, pos_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT * pos_buffer.capacity(), pos_buffer, GL.GL_STATIC_DRAW); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, color_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT * color_buffer.capacity(), color_buffer, GL.GL_STATIC_DRAW); GLWrapper.glGenVertexArrays(1, vao); GLWrapper.glBindVertexArray(vao.get(0)); // Indices GLWrapper.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, indices_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, Buffers.SIZEOF_INT * indices_buffer.capacity(), indices_buffer, GL.GL_STATIC_DRAW); // Position attribute GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, pos_vbo.get(0)); GLWrapper.glEnableVertexAttribArray(0); GLWrapper.glVertexAttribPointer(0, 3, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * 3, 0); // Color attribute GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, color_vbo.get(0)); GLWrapper.glEnableVertexAttribArray(1); GLWrapper.glVertexAttribPointer(1, 4, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * 4, 0); GLWrapper.glEnable(GL.GL_BLEND); color_program.Enable(); GLWrapper.glDrawElements(GL.GL_LINES, indices_size, GL.GL_UNSIGNED_INT, 0); color_program.Disable(); GLWrapper.glDisable(GL.GL_BLEND); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); GLWrapper.glBindVertexArray(0); GLWrapper.glDeleteBuffers(1, indices_vbo); GLWrapper.glDeleteBuffers(1, pos_vbo); GLWrapper.glDeleteBuffers(1, color_vbo); GLWrapper.glDeleteVertexArrays(1, vao); } /** * Draws a capsule. * * @param capsule_pos_1 * Start pos of the capsule axis * @param capsule_pos_2 * End pos of the capsule axis * @param radius * Radius * @param slice_num * Number of divisions in the longitudinal direction * @param stack_num * Number of divisions in the latitudinal direction * @param color * Color */ public static void DrawCapsule3D(Vector capsule_pos_1, Vector capsule_pos_2, float radius, int slice_num, int stack_num, ColorU8 color) { final Vector capsule_axis = VectorFunctions.VSub(capsule_pos_2, capsule_pos_1); final float d = VectorFunctions.VSize(capsule_axis); final float half_d = d / 2.0f; final float th_v = VectorFunctions.VAngleV(capsule_axis); final float th_h = VectorFunctions.VAngleH(capsule_axis); Vector center_pos = VectorFunctions.VAdd(capsule_pos_1, capsule_pos_2); center_pos = VectorFunctions.VScale(center_pos, 0.5f); final List vertices = new ArrayList<>(); final List indices = new ArrayList<>(); final int vertex_num = slice_num * (stack_num - 1) + 2; // North pole vertices.add(VectorFunctions.VGet(0.0f, radius + half_d, 0.0f)); // Middle for (int i = 1; i < stack_num / 2; i++) { final float ph = (float) Math.PI * i / stack_num; final float y = radius * (float) Math.cos(ph) + half_d; final float r = radius * (float) Math.sin(ph); for (int j = 0; j < slice_num; j++) { final float th = 2.0f * (float) Math.PI * j / slice_num; final float x = r * (float) Math.cos(th); final float z = r * (float) Math.sin(th); vertices.add(VectorFunctions.VGet(x, y, z)); } } for (int i = stack_num / 2; i < stack_num; i++) { final float ph = (float) Math.PI * i / stack_num; final float y = radius * (float) Math.cos(ph) - half_d; final float r = radius * (float) Math.sin(ph); for (int j = 0; j < slice_num; j++) { final float th = 2.0f * (float) Math.PI * j / slice_num; final float x = r * (float) Math.cos(th); final float z = r * (float) Math.sin(th); vertices.add(VectorFunctions.VGet(x, y, z)); } } // South pole vertices.add(VectorFunctions.VGet(0.0f, -radius - half_d, 0.0f)); final Matrix rot_z = MatrixFunctions.MGetRotZ(th_v - (float) Math.PI / 2.0f); final Matrix rot_y = MatrixFunctions.MGetRotY(-th_h); for (int i = 0; i < vertex_num; i++) { Vector vertex = vertices.get(i); vertex = MatrixFunctions.VTransform(vertex, rot_z); vertex = MatrixFunctions.VTransform(vertex, rot_y); vertex = VectorFunctions.VAdd(vertex, center_pos); vertices.set(i, vertex); } // Ridgelines around the north pole for (int i = 1; i <= slice_num; i++) { indices.add(0); indices.add(i); } // Ridgelines in the middle int count = 1; for (int i = 2; i < stack_num; i++) { for (int j = 1; j < slice_num; j++) { indices.add(count); indices.add(count + 1); indices.add(count); indices.add(count + slice_num); count++; } indices.add(count); indices.add(count - slice_num + 1); indices.add(count); indices.add(count + slice_num); count++; } // Ridgelines in the bottom for (int i = 1; i < slice_num; i++) { indices.add(count); indices.add(count + 1); indices.add(count); indices.add(vertex_num - 1); count++; } indices.add(count); indices.add(count - slice_num + 1); indices.add(count); indices.add(vertex_num - 1); // Make buffers. final IntBuffer indices_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer pos_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer color_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer vao = Buffers.newDirectIntBuffer(1); final IntBuffer indices_buffer = Buffers.newDirectIntBuffer(indices.size()); final FloatBuffer pos_buffer = Buffers.newDirectFloatBuffer(vertices.size() * 3); final FloatBuffer color_buffer = Buffers.newDirectFloatBuffer(indices.size() * 4); final int indices_size = indices.size(); for (int i = 0; i < indices_size; i++) { indices_buffer.put(indices.get(i)); } for (int i = 0; i < vertex_num; i++) { final Vector vertex = vertices.get(i); pos_buffer.put(vertex.GetX()); pos_buffer.put(vertex.GetY()); pos_buffer.put(vertex.GetZ()); } final float color_r = color.GetR(); final float color_g = color.GetG(); final float color_b = color.GetB(); final float color_a = color.GetA(); for (int i = 0; i < indices_size; i++) { color_buffer.put(color_r); color_buffer.put(color_g); color_buffer.put(color_b); color_buffer.put(color_a); } indices_buffer.flip(); pos_buffer.flip(); color_buffer.flip(); GLWrapper.glGenBuffers(1, indices_vbo); GLWrapper.glGenBuffers(1, pos_vbo); GLWrapper.glGenBuffers(1, color_vbo); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, pos_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT * pos_buffer.capacity(), pos_buffer, GL.GL_STATIC_DRAW); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, color_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT * color_buffer.capacity(), color_buffer, GL.GL_STATIC_DRAW); GLWrapper.glGenVertexArrays(1, vao); GLWrapper.glBindVertexArray(vao.get(0)); // Indices GLWrapper.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, indices_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, Buffers.SIZEOF_INT * indices_buffer.capacity(), indices_buffer, GL.GL_STATIC_DRAW); // Position attribute GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, pos_vbo.get(0)); GLWrapper.glEnableVertexAttribArray(0); GLWrapper.glVertexAttribPointer(0, 3, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * 3, 0); // Color attribute GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, color_vbo.get(0)); GLWrapper.glEnableVertexAttribArray(1); GLWrapper.glVertexAttribPointer(1, 4, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * 4, 0); GLWrapper.glEnable(GL.GL_BLEND); color_program.Enable(); GLWrapper.glDrawElements(GL.GL_LINES, indices_size, GL.GL_UNSIGNED_INT, 0); color_program.Disable(); GLWrapper.glDisable(GL.GL_BLEND); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); GLWrapper.glBindVertexArray(0); GLWrapper.glDeleteBuffers(1, indices_vbo); GLWrapper.glDeleteBuffers(1, pos_vbo); GLWrapper.glDeleteBuffers(1, color_vbo); GLWrapper.glDeleteVertexArrays(1, vao); } /** * Draws a textured triangle. * * @param triangle * Triangle * @param texture_handle * Texture handle * @param use_face_normal_flag * Use a face normal instead of vertex normals */ public static void DrawTexturedTriangle3D(Triangle triangle, int texture_handle, boolean use_face_normal_flag) { final IntBuffer pos_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer uv_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer norm_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer vao = Buffers.newDirectIntBuffer(1); final Vertex3D[] vertices = triangle.GetVertices(); final FloatBuffer pos_buffer = Buffers.newDirectFloatBuffer(9); final FloatBuffer uv_buffer = Buffers.newDirectFloatBuffer(6); final FloatBuffer norm_buffer = Buffers.newDirectFloatBuffer(9); // Calculate the face normal. final Vector v1 = VectorFunctions.VSub(vertices[1].GetPos(), vertices[0].GetPos()); final Vector v2 = VectorFunctions.VSub(vertices[2].GetPos(), vertices[0].GetPos()); Vector face_norm = VectorFunctions.VCross(v1, v2); face_norm = VectorFunctions.VNorm(face_norm); for (int i = 0; i < 3; i++) { final Vector pos = vertices[i].GetPos(); final float u = vertices[i].GetU(); final float v = vertices[i].GetV(); pos_buffer.put(pos.GetX()); pos_buffer.put(pos.GetY()); pos_buffer.put(pos.GetZ()); uv_buffer.put(u); uv_buffer.put(v); if (use_face_normal_flag == true) { norm_buffer.put(face_norm.GetX()); norm_buffer.put(face_norm.GetY()); norm_buffer.put(face_norm.GetZ()); } else { final Vector norm = vertices[i].GetNorm(); norm_buffer.put(norm.GetX()); norm_buffer.put(norm.GetY()); norm_buffer.put(norm.GetZ()); } } pos_buffer.flip(); uv_buffer.flip(); norm_buffer.flip(); GLWrapper.glGenBuffers(1, pos_vbo); GLWrapper.glGenBuffers(1, uv_vbo); GLWrapper.glGenBuffers(1, norm_vbo); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, pos_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT * pos_buffer.capacity(), pos_buffer, GL.GL_STATIC_DRAW); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, uv_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT * uv_buffer.capacity(), uv_buffer, GL.GL_STATIC_DRAW); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, norm_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT * norm_buffer.capacity(), norm_buffer, GL.GL_STATIC_DRAW); GLWrapper.glGenVertexArrays(1, vao); GLWrapper.glBindVertexArray(vao.get(0)); // Position attribute GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, pos_vbo.get(0)); GLWrapper.glEnableVertexAttribArray(0); GLWrapper.glVertexAttribPointer(0, 3, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * 3, 0); // UV attribute GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, uv_vbo.get(0)); GLWrapper.glEnableVertexAttribArray(1); GLWrapper.glVertexAttribPointer(1, 2, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * 2, 0); // Normal attribute GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, norm_vbo.get(0)); GLWrapper.glEnableVertexAttribArray(2); GLWrapper.glVertexAttribPointer(2, 3, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * 3, 0); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); GLWrapper.glBindVertexArray(0); GLWrapper.glBindVertexArray(vao.get(0)); // Draw texture_program.Enable(); texture_program.SetTexture("texture_sampler", 0, texture_handle); GLWrapper.glEnable(GL.GL_BLEND); GLWrapper.glDrawArrays(GL.GL_TRIANGLES, 0, 3); GLWrapper.glDisable(GL.GL_BLEND); texture_program.Disable(); GLWrapper.glBindVertexArray(0); // Delete buffers GLWrapper.glDeleteBuffers(1, pos_vbo); GLWrapper.glDeleteBuffers(1, uv_vbo); GLWrapper.glDeleteBuffers(1, norm_vbo); GLWrapper.glDeleteVertexArrays(1, vao); } /** * Draws a quadrangle. * * @param quadrangle * Quadrangle * @param texture_handle * Texture handle * @param use_face_normal_flag * Use a face normal instead of vertex normals */ public static void DrawTexturedQuadrangle(Quadrangle quadrangle, int texture_handle, boolean use_face_normal_flag) { final IntBuffer indices_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer pos_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer uv_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer norm_vbo = Buffers.newDirectIntBuffer(1); final IntBuffer vao = Buffers.newDirectIntBuffer(1); final Vertex3D[] vertices = quadrangle.GetVertices(); final IntBuffer indices_buffer = Buffers.newDirectIntBuffer(6); final FloatBuffer pos_buffer = Buffers.newDirectFloatBuffer(12); final FloatBuffer uv_buffer = Buffers.newDirectFloatBuffer(8); final FloatBuffer norm_buffer = Buffers.newDirectFloatBuffer(12); indices_buffer.put(0); indices_buffer.put(1); indices_buffer.put(2); indices_buffer.put(2); indices_buffer.put(3); indices_buffer.put(0); indices_buffer.flip(); // Calculate the face normal. final Vector v1 = VectorFunctions.VSub(vertices[1].GetPos(), vertices[0].GetPos()); final Vector v2 = VectorFunctions.VSub(vertices[3].GetPos(), vertices[0].GetPos()); Vector face_norm = VectorFunctions.VCross(v1, v2); face_norm = VectorFunctions.VNorm(face_norm); for (int i = 0; i < 4; i++) { final Vector pos = vertices[i].GetPos(); final float u = vertices[i].GetU(); final float v = vertices[i].GetV(); pos_buffer.put(pos.GetX()); pos_buffer.put(pos.GetY()); pos_buffer.put(pos.GetZ()); uv_buffer.put(u); uv_buffer.put(v); if (use_face_normal_flag == true) { norm_buffer.put(face_norm.GetX()); norm_buffer.put(face_norm.GetY()); norm_buffer.put(face_norm.GetZ()); } else { final Vector norm = vertices[i].GetNorm(); norm_buffer.put(norm.GetX()); norm_buffer.put(norm.GetY()); norm_buffer.put(norm.GetZ()); } } pos_buffer.flip(); uv_buffer.flip(); norm_buffer.flip(); GLWrapper.glGenBuffers(1, indices_vbo); GLWrapper.glGenBuffers(1, pos_vbo); GLWrapper.glGenBuffers(1, uv_vbo); GLWrapper.glGenBuffers(1, norm_vbo); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, pos_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT * pos_buffer.capacity(), pos_buffer, GL.GL_STATIC_DRAW); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, uv_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT * uv_buffer.capacity(), uv_buffer, GL.GL_STATIC_DRAW); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, norm_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ARRAY_BUFFER, Buffers.SIZEOF_FLOAT * norm_buffer.capacity(), norm_buffer, GL.GL_STATIC_DRAW); GLWrapper.glGenVertexArrays(1, vao); GLWrapper.glBindVertexArray(vao.get(0)); // Indices GLWrapper.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, indices_vbo.get(0)); GLWrapper.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, Buffers.SIZEOF_INT * indices_buffer.capacity(), indices_buffer, GL.GL_STATIC_DRAW); // Position attribute GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, pos_vbo.get(0)); GLWrapper.glEnableVertexAttribArray(0); GLWrapper.glVertexAttribPointer(0, 3, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * 3, 0); // UV attribute GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, uv_vbo.get(0)); GLWrapper.glEnableVertexAttribArray(1); GLWrapper.glVertexAttribPointer(1, 2, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * 2, 0); // Normal attribute GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, norm_vbo.get(0)); GLWrapper.glEnableVertexAttribArray(2); GLWrapper.glVertexAttribPointer(2, 3, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * 3, 0); GLWrapper.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); GLWrapper.glBindVertexArray(0); GLWrapper.glBindVertexArray(vao.get(0)); // Draw texture_program.Enable(); texture_program.SetTexture("texture_sampler", 0, texture_handle); GLWrapper.glEnable(GL.GL_BLEND); GLWrapper.glDrawElements(GL.GL_TRIANGLES, 6, GL.GL_UNSIGNED_INT, 0); GLWrapper.glDisable(GL.GL_BLEND); texture_program.Disable(); GLWrapper.glBindVertexArray(0); // Delete buffers GLWrapper.glDeleteBuffers(1, indices_vbo); GLWrapper.glDeleteBuffers(1, pos_vbo); GLWrapper.glDeleteBuffers(1, uv_vbo); GLWrapper.glDeleteBuffers(1, norm_vbo); GLWrapper.glDeleteVertexArrays(1, vao); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy