Java 如何在不修改元素的情况下将数据关联到集合中的元素?
通常,当我进行OpenGL编程时,我有一个网格类,如下所示:Java 如何在不修改元素的情况下将数据关联到集合中的元素?,java,design-patterns,Java,Design Patterns,通常,当我进行OpenGL编程时,我有一个网格类,如下所示: public class Mesh { // General 3D stuff List<Vector3f> vertices = new ArrayList<>(); List<Vector3f> normals = new ArrayList<>(); List<Vector2f> texCoords = new ArrayList<
public class Mesh {
// General 3D stuff
List<Vector3f> vertices = new ArrayList<>();
List<Vector3f> normals = new ArrayList<>();
List<Vector2f> texCoords = new ArrayList<>();
// OpenGL-specific stuff
protected int vertices;
protected boolean dirty;
protected int vertexArrayID = -1;
protected int vertexBufferID = -1;
...
}
public class Mesh {
// General 3D stuff
List<Vector3f> vertices = new ArrayList<>();
List<Vector3f> normals = new ArrayList<>();
List<Vector2f> texCoords = new ArrayList<>();
}
public class GlMesh {
// OpenGL-specific stuff
protected int vertices;
protected boolean dirty;
protected int vertexArrayID = -1;
protected int vertexBufferID = -1;
}
Map<Mesh, GlMesh> meshToGlMesh = (whatever)
public class Mesh implements GlMeshSupplier{
private final List<Vector3f> vertices = new ArrayList<>();
private final List<Vector3f> normals = new ArrayList<>();
private final List<Vector2f> texCoords = new ArrayList<>();
private GlMesh glMesh;
@Override
public GlMesh getGlMesh() {
return glMesh;
}
public void createGlMesh(){
glMesh = new GlMesh();
}
public List<Vector3f> getVertices() {
return vertices;
}
public List<Vector3f> getNormals() {
return normals;
}
public List<Vector2f> getTexCoords() {
return texCoords;
}
public class GlMesh extends Mesh{
// OpenGL-specific stuff
protected int ivertices;
protected boolean dirty;
protected int vertexArrayID = -1;
protected int vertexBufferID = -1;
private GlMesh(){}
@Override
public List<Vector3f> getVertices() {
return Mesh.this.vertices;
}
@Override
public List<Vector3f> getNormals() {
return Mesh.this.normals;
}
@Override
public List<Vector2f> getTexCoords() {
return Mesh.this.texCoords;
}
}
}
public interface GlMeshSupplier {
public GlMesh getGlMesh();
}
但是,现在渲染系统必须做大量的簿记,以将网格映射到相应的GlMesh,这只是自找麻烦
有什么好方法可以解决我所缺少的问题吗?我不是OpenGL程序员,所以我不知道这方面的所有问题,因此可能会让你误入歧途,但根据你所描述的,听起来你在寻找工厂模式 如果您的
GLMesh
对象需要像使用Mesh
一样使用,那么它显然需要扩展Mesh
(或者需要在GLMesh
前面有一个facade类,使其看起来像Mesh
)
同时,您编写的代码知道需要使用GLMesh
。该代码可以将GLMesh工厂
传递给不知道要使用GLMesh
但知道需要使用Mesh
的代码。它将从MeshFactory
获取其Mesh
实例,通常是一个名为getInstance()
的方法,使用您期望的任何MeshFactory
参数返回实例(你需要提前考虑-最坏的情况是,你在最后传递一个贴图
,除了你知道任何网格
都需要的数据之外,还有任何额外的数据)
MeshFactory
可以生成Mesh
实例,无论您现在以何种方式进行操作。GLMeshFactory
只需反复返回相同的实例即可(您在注释中暗示,它们的创建成本很高)工厂通常被理解为在适当的时候返回共享实例。类似这样的情况如何:
public class Mesh {
// General 3D stuff
List<Vector3f> vertices = new ArrayList<>();
List<Vector3f> normals = new ArrayList<>();
List<Vector2f> texCoords = new ArrayList<>();
// OpenGL-specific stuff
protected int vertices;
protected boolean dirty;
protected int vertexArrayID = -1;
protected int vertexBufferID = -1;
...
}
public class Mesh {
// General 3D stuff
List<Vector3f> vertices = new ArrayList<>();
List<Vector3f> normals = new ArrayList<>();
List<Vector2f> texCoords = new ArrayList<>();
}
public class GlMesh {
// OpenGL-specific stuff
protected int vertices;
protected boolean dirty;
protected int vertexArrayID = -1;
protected int vertexBufferID = -1;
}
Map<Mesh, GlMesh> meshToGlMesh = (whatever)
public class Mesh implements GlMeshSupplier{
private final List<Vector3f> vertices = new ArrayList<>();
private final List<Vector3f> normals = new ArrayList<>();
private final List<Vector2f> texCoords = new ArrayList<>();
private GlMesh glMesh;
@Override
public GlMesh getGlMesh() {
return glMesh;
}
public void createGlMesh(){
glMesh = new GlMesh();
}
public List<Vector3f> getVertices() {
return vertices;
}
public List<Vector3f> getNormals() {
return normals;
}
public List<Vector2f> getTexCoords() {
return texCoords;
}
public class GlMesh extends Mesh{
// OpenGL-specific stuff
protected int ivertices;
protected boolean dirty;
protected int vertexArrayID = -1;
protected int vertexBufferID = -1;
private GlMesh(){}
@Override
public List<Vector3f> getVertices() {
return Mesh.this.vertices;
}
@Override
public List<Vector3f> getNormals() {
return Mesh.this.normals;
}
@Override
public List<Vector2f> getTexCoords() {
return Mesh.this.texCoords;
}
}
}
public interface GlMeshSupplier {
public GlMesh getGlMesh();
}
公共类Mesh实现GlMeshSupplier{
私有最终列表顶点=新ArrayList();
私有最终列表法线=新ArrayList();
私有最终列表texCoords=newarraylist();
私人GlMesh GlMesh;
@凌驾
公共GlMesh getGlMesh(){
返回网格;
}
public void createGlMesh(){
glMesh=新glMesh();
}
公共列表getVertices(){
返回顶点;
}
公共列表getNormals(){
回归常态;
}
公共列表getTexCoords(){
返回texCoords;
}
公共类GlMesh扩展了Mesh{
//OpenGL特有的东西
受保护的国际河流;
保护布尔脏;
受保护的整数vertexArrayID=-1;
受保护的int vertexBufferID=-1;
私有GlMesh(){}
@凌驾
公共列表getVertices(){
返回Mesh.this.vertices;
}
@凌驾
公共列表getNormals(){
返回Mesh.this.normals;
}
@凌驾
公共列表getTexCoords(){
返回Mesh.this.texCoords;
}
}
}
公共接口供应商{
公共GlMesh getGlMesh();
}
网格和GlMesh之间的替代映射:
//class Mesh
public Mesh(){
this.vertices = new ArrayList<>();
this.normals = new ArrayList<>();
this.texCoords = new ArrayList<>();
}
private Mesh(List<Vector3f> vertices, List<Vector3f> normals, List<Vector2f> texCoords){
this.vertices = vertices;
this.normals = normals;
this.texCoords = texCoords;
}
//class GlMesh
private GlMesh(){
super(Mesh.this.vertices, Mesh.this.normals, Mesh.this.texCoords);
}
//类网格
公共网格(){
this.vertices=新的ArrayList();
this.normals=新的ArrayList();
this.texCoords=new ArrayList();
}
私有网格(列出顶点、列出法线、列出纹理坐标){
这个。顶点=顶点;
this.normals=法线;
this.texCoords=texCoords;
}
//类GlMesh
私有GlMesh(){
超级(Mesh.this.vertices、Mesh.this.normals、Mesh.this.texCoords);
}
您的Mesh
和GlMesh
似乎彼此紧密相关,这可以证明这样的合成是合理的。Mesh
可以独立于其GlMesh
创建。创建GlMesh
后,它将映射(也是Mesh
)到封闭网格的属性
方法getVertices()
、getNormals()
和getExcoords()
只是通过网格方法从Mesh
及其GlMesh
访问相同属性的示例
如果要隐藏
Mesh
中不应映射到GlMesh
中的功能,也可以使用供应商界面(如GlMeshSupplier
)来屏蔽Mesh
,那么在GlMesh构造函数中传递网格如何?这不太有效。渲染器会获得一个网格列表作为输入,并且必须找到GLMesh与其中的每个元素一起使用,以避免反复创建GLMesh。然而,您的建议是反向的,它允许您轻松找到网格。有趣的方法,我一定会尝试。是的,场景图中确实不可避免地包含某种GLMesh对象,但Factory似乎是最不坏的sol对它的理解。