EOS 2  1.1.0
Einfache Objektbasierte Sprache
VertexBufferObject.java
gehe zur Dokumentation dieser Datei
1 package de.lathanda.eos.robot.gui;
2 
3 import java.awt.Color;
4 import java.nio.FloatBuffer;
5 import java.util.LinkedList;
6 import java.util.Map.Entry;
7 import java.util.TreeMap;
8 
9 import com.jogamp.common.nio.Buffers;
10 import com.jogamp.opengl.GL;
11 import com.jogamp.opengl.GL2;
12 
13 import de.lathanda.eos.robot.geom3d.Face;
14 import de.lathanda.eos.robot.geom3d.Material;
15 import de.lathanda.eos.robot.geom3d.Polyhedron;
16 
17 public class VertexBufferObject implements GLRenderObject{
18  private volatile boolean vboReady = false;
19  private Material m;
20  FloatBuffer vertices;
21  FloatBuffer normals;
22  FloatBuffer texCoords;
23  private int vboId;
24  private int vOff, tOff, nOff, size;
25  private int vCount;
26  private VBORenderer renderer;
27  public static LinkedList<GLRenderObject> create(Polyhedron poly) {
28  TreeMap<Material, LinkedList<Face> > faceGroups = new TreeMap<>();
29  for(Face f: poly.faces) {
30  LinkedList<Face> group;
31  if ( faceGroups.containsKey(f.m)) {
32  group = faceGroups.get(f.m);
33  } else {
34  group = new LinkedList<Face>();
35  faceGroups.put(f.m, group);
36  }
37  group.add(f);
38  }
39 
40  LinkedList<GLRenderObject> buffers = new LinkedList<>();
41  for (Entry<Material, LinkedList<Face> > entry : faceGroups.entrySet()) {
42  buffers.add(new VertexBufferObject(entry.getValue(), entry.getKey()));
43  }
44  return buffers;
45  }
46  private VertexBufferObject(LinkedList<Face> faces, Material m) {
47  this.m = m;
48  this.vCount = faces.size() * 3;
49  this.vertices = Buffers.newDirectFloatBuffer(vCount * 3);
50  this.normals = Buffers.newDirectFloatBuffer(vCount * 3);
51  for(Face face: faces) {
52  for(int i = 0; i < 3; i++) {
53  vertices.put(face.v[i].x);
54  vertices.put(face.v[i].y);
55  vertices.put(face.v[i].z);
56  normals.put(face.vn[i].dx);
57  normals.put(face.vn[i].dy);
58  normals.put(face.vn[i].dz);
59  }
60  }
61 
62  if (m.image == null) {
63  this.renderer = new NoTextureRenderer();
64  this.texCoords = null;
65  } else {
66  this.texCoords = Buffers.newDirectFloatBuffer(vCount * 2);
67  for(Face face: faces) {
68  for(int i = 0; i < 3; i++) {
69  texCoords.put(face.vt[i].u);
70  texCoords.put(1 - face.vt[i].v); //Jogamp has inverted coords, i don't know why
71  }
72  }
73  this.renderer = new TextureRenderer();
74  }
75  }
76 
77  private void setupVBO(GL2 gl) {
78  vertices.rewind();
79  normals.rewind();
80  int vSize = vertices.capacity() * 4;
81  int nSize = normals.capacity() * 4;
82  int tSize;
83  if (texCoords != null) {
84  texCoords.rewind();
85  tSize = texCoords.capacity() * 4;
86  } else {
87  tSize = 0;
88  }
89  vOff = 0;
90  tOff = vOff + vSize;
91  nOff = tOff + tSize;
92  size = nOff + nSize;
93 
94  int[] bufferId = new int[1];
95  gl.glGenBuffers(1, bufferId, 0);
96  vboId = bufferId[0];
97  if (vboId < 1) {
98  throw new RuntimeException("aquiring VBO id failed!");
99  }
100  gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vboId);
101  gl.glBufferData(GL2.GL_ARRAY_BUFFER, size, null, GL2.GL_STATIC_DRAW);
102  gl.glBufferSubData(GL2.GL_ARRAY_BUFFER, vOff, vSize, vertices);
103  if (texCoords != null) {
104  gl.glBufferSubData(GL2.GL_ARRAY_BUFFER, tOff, tSize, texCoords);
105  }
106  gl.glBufferSubData(GL2.GL_ARRAY_BUFFER, nOff, nSize, normals);
107  gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
108  vboReady = true;
109  }
110  public void render(GL2 gl, Color base) {
111  renderer.render(gl, base);
112  }
113  private static interface VBORenderer {
114  void render(GL2 gl, Color base);
115  }
116  private class TextureRenderer implements VBORenderer {
117  @Override
118  public void render(GL2 gl, Color base) {
119  if (!vboReady) {
120  setupVBO(gl);
121  }
122  gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboId);
123  gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
124  gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
125  gl.glEnableClientState(GL2.GL_NORMAL_ARRAY);
126  gl.glVertexPointer(3, GL.GL_FLOAT, 0, vOff);
127  gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, tOff);
128  gl.glNormalPointer(GL.GL_FLOAT,0 , nOff);
129  GLTextureBuffer texture = GLTextureBuffer.get(m, gl);
130  texture.openMaterial(base, gl);
131  gl.glDrawArrays(GL.GL_TRIANGLES,0, vCount);
132  texture.closeMaterial(gl);
133  gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
134  }
135  }
136  private class NoTextureRenderer implements VBORenderer {
137  @Override
138  public void render(GL2 gl, Color base) {
139  if (!vboReady) {
140  setupVBO(gl);
141  }
142  gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboId);
143  gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
144  gl.glEnableClientState(GL2.GL_NORMAL_ARRAY);
145  gl.glVertexPointer(3, GL.GL_FLOAT, 0, vOff);
146  gl.glNormalPointer(GL.GL_FLOAT,0 , nOff);
147  GLTextureBuffer texture = GLTextureBuffer.get(m, gl);
148  texture.openMaterial(base, gl);
149  gl.glDrawArrays(GL.GL_TRIANGLES,0, vCount);
150  texture.closeMaterial(gl);
151  gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
152  }
153  }
154  @Override
155  public void destroy(GL gl) {
156  //free vbo ?
157  vboReady = false;
158  }
159 
160 }
final LinkedList< Face > faces
Definition: Polyhedron.java:12
static LinkedList< GLRenderObject > create(Polyhedron poly)
Impressum