所以我已经用我从老师那里得到的这个代码工作了 2 个晚上。我一直在寻找在JOGL上找到一些好的Javadoc,但没有取得多大成功。所以我一直在使用 try/fail 方法在这里和那里更改变量。我已经学会了如何控制旋转、距离和大小。所以我做了一个小"太阳系" - 但我的问题来了 - 我如何为我制作的不同行星实现多种纹理?这是我的代码:
public class RelativeTransformation implements GLEventListener, KeyListener {
// OpenGL window reference
private static GLWindow window;
// The animator is responsible for continuous operation
private static Animator animator;
// The program entry point
public static void main(String[] args) {
new RelativeTransformation().setup();
}
// Vertex data
private float[] vertexData;
// Triangle data
private short[] elementData;
// Light properties (4 valued vectors due to std140 see OpenGL 4.5 reference)
private float[] lightProperties = {
// Position
2f, 0f, 3f, 0f,
// Ambient Color
0.2f, 0.2f, 0.2f, 0f,
// Diffuse Color
0.5f, 0.5f, 0.5f, 0f,
// Specular Color
1f, 1f, 1f, 0f
};
private float[] materialProperties = {
// Shininess
8f
};
// Camera properties
private float[] cameraProperties = {
0f, 0f, 2f
};
// The OpenGL profile
GLProfile glProfile;
// The texture filename
private final String textureFilename = "src/relative_transformation/sun.jpg";
private final String textureFilename2 = "src/relative_transformation/earth.jpg";
// Create buffers for the names
private IntBuffer bufferNames = GLBuffers.newDirectIntBuffer(Buffer.MAX);
private IntBuffer vertexArrayName = GLBuffers.newDirectIntBuffer(1);
private IntBuffer textureNames = GLBuffers.newDirectIntBuffer(1);
// Create buffers for clear values
private FloatBuffer clearColor = GLBuffers.newDirectFloatBuffer(new float[] {0, 0, 0, 0});
private FloatBuffer clearDepth = GLBuffers.newDirectFloatBuffer(new float[] {1});
// Create references to buffers for holding the matrices
private ByteBuffer globalMatricesPointer, modelMatrixPointer1, modelMatrixPointer2, modelMatrixPointer3;
// Program instance reference
private Program program;
// Variable for storing the start time of the application
private long start;
// Application setup function
private void setup() {
// Get a OpenGL 4.x profile (x >= 0)
glProfile = GLProfile.get(GLProfile.GL4);
// Get a structure for definining the OpenGL capabilities with default values
GLCapabilities glCapabilities = new GLCapabilities(glProfile);
// Create the window with default capabilities
window = GLWindow.create(glCapabilities);
// Set the title of the window
window.setTitle("Relative Transformation");
// Set the size of the window
window.setSize(1024, 768);
// Set debug context (must be set before the window is set to visible)
window.setContextCreationFlags(GLContext.CTX_OPTION_DEBUG);
// Make the window visible
window.setVisible(true);
// Add OpenGL and keyboard event listeners
window.addGLEventListener(this);
window.addKeyListener(this);
// Create and start the animator
animator = new Animator(window);
animator.start();
// Add window event listener
window.addWindowListener(new WindowAdapter() {
// Window has been destroyed
@Override
public void windowDestroyed(WindowEvent e) {
// Stop animator and exit
animator.stop();
System.exit(1);
}
});
}
// GLEventListener.init implementation
@Override
public void init(GLAutoDrawable drawable) {
// Get OpenGL 4 reference
GL4 gl = drawable.getGL().getGL4();
// Initialize debugging
initDebug(gl);
// Initialize buffers
initBuffers(gl);
// Initialize vertex array
initVertexArray(gl);
// Initialize texture
initTexture(gl);
// Set up the program
program = new Program(gl, "relative_transformation", "shader", "shader");
// Enable Opengl depth buffer testing
gl.glEnable(GL_DEPTH_TEST);
// Store the starting time of the application
start = System.currentTimeMillis();
}
// GLEventListener.display implementation
@Override
public void display(GLAutoDrawable drawable) {
// Get OpenGL 4 reference
GL4 gl = drawable.getGL().getGL4();
// Copy the view matrix to the server
{
// Create identity matrix
float[] view = FloatUtil.makeTranslation(new float[16], 0, false, -cameraProperties[0], -cameraProperties[1], -cameraProperties[2]);
// Copy each of the values to the second of the two global matrices
for (int i = 0; i < 16; i++)
globalMatricesPointer.putFloat(16 * 4 + i * 4, view[i]);
}
// Clear the color and depth buffers
gl.glClearBufferfv(GL_COLOR, 0, clearColor);
gl.glClearBufferfv(GL_DEPTH, 0, clearDepth);
// Copy the model matrices to the server
{
// Find a time delta for the time passed since the start of execution
long now = System.currentTimeMillis();
float diff = (float) (now - start) / 2000;
// Create a rotation matrix around the z axis based on the time delta
// Lag 2 rotate inni hverandre, relater den 2. til den 1. og sett speed opp! Se Universe.java (model og modelPos?)
float[] rotate1 = FloatUtil.makeRotationAxis(new float[16], 0, 00.5f*diff, 0f, 1f, 0f, new float[3]);
float[] rotate2 = FloatUtil.makeRotationAxis(new float[16], 0, 01.0f*diff, 0f, 1f, 0f, new float[3]);
float[] rotate3 = FloatUtil.makeRotationAxis(new float[16], 0, 15.0f*diff, 0f, 1f, 0f, new float[3]);
float[] translate2 = FloatUtil.makeTranslation(new float[16], false, 1.4f, 0f, 0f);
float[] translate3 = FloatUtil.makeTranslation(new float[16], false, 0.0f, 0f, 0f);
float[] modelPos2 = FloatUtil.multMatrix(rotate1, FloatUtil.multMatrix(rotate2, translate2, new float[16]), new float[16]);
float[] model2 = FloatUtil.multMatrix(modelPos2, FloatUtil.makeScale(new float[16], false, 0.1f, 0.1f, 0.1f), new float[16]);
float[] modelPos3 = FloatUtil.multMatrix(modelPos2, FloatUtil.multMatrix(rotate3, translate3, new float[16]), new float[16]);
float[] model3 = FloatUtil.multMatrix(modelPos3, FloatUtil.makeScale(new float[16], false, 0.5f, 0.5f, 0.5f), new float[16]);
// Copy the entire matrix to the server
modelMatrixPointer1.asFloatBuffer().put(rotate1);
modelMatrixPointer2.asFloatBuffer().put(model2);
modelMatrixPointer3.asFloatBuffer().put(model3);
}
// Activate the vertex program and vertex array
gl.glUseProgram(program.name);
gl.glBindVertexArray(vertexArrayName.get(0));
gl.glBindTexture(gl.GL_TEXTURE_2D, textureNames.get(0));
// Bind the global matrices buffer to a specified index within the uniform buffers
gl.glBindBufferBase(
GL_UNIFORM_BUFFER,
Semantic.Uniform.TRANSFORM0,
bufferNames.get(Buffer.GLOBAL_MATRICES));
// Bind the light properties buffer to a specified uniform index
gl.glBindBufferBase(
GL_UNIFORM_BUFFER,
Semantic.Uniform.LIGHT0,
bufferNames.get(Buffer.LIGHT_PROPERTIES));
// Bind the light properties buffer to a specified uniform index
gl.glBindBufferBase(
GL_UNIFORM_BUFFER,
Semantic.Uniform.MATERIAL,
bufferNames.get(Buffer.MATERIAL_PROPERTIES));
// Bind the light properties buffer to a specified uniform index
gl.glBindBufferBase(
GL_UNIFORM_BUFFER,
Semantic.Uniform.CAMERA,
bufferNames.get(Buffer.CAMERA_PROPERTIES));
// Bind the model matrix buffer to a specified index within the uniform buffers
gl.glBindBufferBase(
GL_UNIFORM_BUFFER,
Semantic.Uniform.TRANSFORM1,
bufferNames.get(Buffer.MODEL_MATRIX1));
// Draw the triangle
gl.glDrawElements(
GL_TRIANGLES,
elementData.length,
GL_UNSIGNED_SHORT,
0);
// Bind the model matrix buffer to a specified index within the uniform buffers
gl.glBindBufferBase(
GL_UNIFORM_BUFFER,
Semantic.Uniform.TRANSFORM1,
bufferNames.get(Buffer.MODEL_MATRIX2));
// Draw the triangle
gl.glDrawElements(
GL_TRIANGLES,
elementData.length,
GL_UNSIGNED_SHORT,
0);
// Bind the model matrix buffer to a specified index within the uniform buffers
gl.glBindBufferBase(
GL_UNIFORM_BUFFER,
Semantic.Uniform.TRANSFORM1,
bufferNames.get(Buffer.MODEL_MATRIX3));
// Draw the triangle
gl.glDrawElements(
GL_TRIANGLES,
elementData.length,
GL_UNSIGNED_SHORT,
0);
// Deactivate the program and vertex array
gl.glUseProgram(0);
gl.glBindVertexArray(0);
gl.glBindTexture(gl.GL_TEXTURE_2D, 0);
}
// GLEventListener.reshape implementation
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
// Get OpenGL 4 reference
GL4 gl = drawable.getGL().getGL4();
// Create an orthogonal projection matrix
float[] ortho = FloatUtil.makePerspective(new float[16], 0, false, (float)Math.PI/2f, (float)width/height, 0.1f, 100f);
// Copy the projection matrix to the server
globalMatricesPointer.asFloatBuffer().put(ortho);
// Set the OpenGL viewport
gl.glViewport(x, y, width, height);
}
// GLEventListener.dispose implementation
@Override
public void dispose(GLAutoDrawable drawable) {
// Get OpenGL 4 reference
GL4 gl = drawable.getGL().getGL4();
// Delete the program
gl.glDeleteProgram(program.name);
// Delete the vertex array
gl.glDeleteVertexArrays(1, vertexArrayName);
// Delete the buffers
gl.glDeleteBuffers(Buffer.MAX, bufferNames);
gl.glDeleteTextures(1, textureNames);
}
// KeyListener.keyPressed implementation
@Override
public void keyPressed(KeyEvent e) {
// Destroy the window if the esape key is pressed
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
new Thread(() -> {
window.destroy();
}).start();
}
}
// KeyListener.keyPressed implementation
@Override
public void keyReleased(KeyEvent e) {
}
// Function for initializing OpenGL debugging
private void initDebug(GL4 gl) {
// Register a new debug listener
window.getContext().addGLDebugListener(new GLDebugListener() {
// Output any messages to standard out
@Override
public void messageSent(GLDebugMessage event) {
System.out.println(event);
}
});
// Ignore all messages
gl.glDebugMessageControl(
GL_DONT_CARE,
GL_DONT_CARE,
GL_DONT_CARE,
0,
null,
false);
// Enable messages of high severity
gl.glDebugMessageControl(
GL_DONT_CARE,
GL_DONT_CARE,
GL_DEBUG_SEVERITY_HIGH,
0,
null,
true);
// Enable messages of medium severity
gl.glDebugMessageControl(
GL_DONT_CARE,
GL_DONT_CARE,
GL_DEBUG_SEVERITY_MEDIUM,
0,
null,
true);
}
// Function fo initializing OpenGL buffers
private void initBuffers(GL4 gl) {
// Create a new float direct buffer for the vertex data
vertexData = createSphereVertices(0.5f, 16, 16);
FloatBuffer vertexBuffer = GLBuffers.newDirectFloatBuffer(vertexData);
// Create a new short direct buffer for the triangle indices
elementData = createSphereElements(16, 16);
ShortBuffer elementBuffer = GLBuffers.newDirectShortBuffer(elementData);
// Create a direct buffer for the light properties
FloatBuffer lightBuffer = GLBuffers.newDirectFloatBuffer(lightProperties);
// Create a direct buffer for the material properties
FloatBuffer materialBuffer = GLBuffers.newDirectFloatBuffer(materialProperties);
// Create a direct buffer for the light properties
FloatBuffer cameraBuffer = GLBuffers.newDirectFloatBuffer(cameraProperties);
// Create the OpenGL buffers names
gl.glCreateBuffers(Buffer.MAX, bufferNames);
// Create and initialize a buffer storage for the vertex data
gl.glBindBuffer(GL_ARRAY_BUFFER, bufferNames.get(Buffer.VERTEX));
gl.glBufferStorage(GL_ARRAY_BUFFER, vertexBuffer.capacity() * Float.BYTES, vertexBuffer, 0);
gl.glBindBuffer(GL_ARRAY_BUFFER, 0);
// Create and initialize a buffer storage for the triangle indices
gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferNames.get(Buffer.ELEMENT));
gl.glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, elementBuffer.capacity() * Short.BYTES, elementBuffer, 0);
gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// Retrieve the uniform buffer offset alignment minimum
IntBuffer uniformBufferOffset = GLBuffers.newDirectIntBuffer(1);
gl.glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, uniformBufferOffset);
// Set the required bytes for the matrices in accordance to the uniform buffer offset alignment minimum
int globalBlockSize = Math.max(16 * 4 * 2, uniformBufferOffset.get(0));
int modelBlockSize = Math.max(16 * 4, uniformBufferOffset.get(0));
int lightBlockSize = Math.max(12 * Float.BYTES, uniformBufferOffset.get(0));
int materialBlockSize = Math.max(3 * Float.BYTES, uniformBufferOffset.get(0));
int cameraBlockSize = Math.max(3 * Float.BYTES, uniformBufferOffset.get(0));
// Create and initialize a named storage for the global matrices
gl.glBindBuffer(GL_UNIFORM_BUFFER, bufferNames.get(Buffer.GLOBAL_MATRICES));
gl.glBufferStorage(GL_UNIFORM_BUFFER, globalBlockSize, null, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
gl.glBindBuffer(GL_UNIFORM_BUFFER, 0);
// Create and initialize a named storage for the model matrix
// NUMERO 1
gl.glBindBuffer(GL_UNIFORM_BUFFER, bufferNames.get(Buffer.MODEL_MATRIX1));
gl.glBufferStorage(GL_UNIFORM_BUFFER, modelBlockSize, null, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
gl.glBindBuffer(GL_UNIFORM_BUFFER, 0);
// NUMERO 2
gl.glBindBuffer(GL_UNIFORM_BUFFER, bufferNames.get(Buffer.MODEL_MATRIX2));
gl.glBufferStorage(GL_UNIFORM_BUFFER, modelBlockSize, null, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
gl.glBindBuffer(GL_UNIFORM_BUFFER, 0);
// NUMERO 3
gl.glBindBuffer(GL_UNIFORM_BUFFER, bufferNames.get(Buffer.MODEL_MATRIX3));
gl.glBufferStorage(GL_UNIFORM_BUFFER, modelBlockSize, null, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
gl.glBindBuffer(GL_UNIFORM_BUFFER, 0);
// Create and initialize a named buffer storage for the light properties
gl.glBindBuffer(GL_UNIFORM_BUFFER, bufferNames.get(Buffer.LIGHT_PROPERTIES));
gl.glBufferStorage(GL_UNIFORM_BUFFER, lightBlockSize, lightBuffer, 0);
gl.glBindBuffer(GL_UNIFORM_BUFFER, 0);
// Create and initialize a named buffer storage for the camera properties
gl.glBindBuffer(GL_UNIFORM_BUFFER, bufferNames.get(Buffer.MATERIAL_PROPERTIES));
gl.glBufferStorage(GL_UNIFORM_BUFFER, materialBlockSize, materialBuffer, 0);
gl.glBindBuffer(GL_UNIFORM_BUFFER, 0);
// Create and initialize a named buffer storage for the camera properties
gl.glBindBuffer(GL_UNIFORM_BUFFER, bufferNames.get(Buffer.CAMERA_PROPERTIES));
gl.glBufferStorage(GL_UNIFORM_BUFFER, cameraBlockSize, cameraBuffer, 0);
gl.glBindBuffer(GL_UNIFORM_BUFFER, 0);
// map the global matrices buffer into the client space
// NUMERO 1
globalMatricesPointer = gl.glMapNamedBufferRange(
bufferNames.get(Buffer.GLOBAL_MATRICES),
0,
16 * 4 * 2,
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
// NUMERO 2
modelMatrixPointer1 = gl.glMapNamedBufferRange(
bufferNames.get(Buffer.MODEL_MATRIX1),
0,
16 * 4,
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
// NUMERO 3
modelMatrixPointer2 = gl.glMapNamedBufferRange(
bufferNames.get(Buffer.MODEL_MATRIX2),
0,
16 * 4,
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
// NUMERO 4
modelMatrixPointer3 = gl.glMapNamedBufferRange(
bufferNames.get(Buffer.MODEL_MATRIX3),
0,
16 * 4,
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
// Function for initializing the vertex array
private void initVertexArray(GL4 gl) {
// Create a single vertex array object
gl.glCreateVertexArrays(1, vertexArrayName);
// Associate the vertex attributes in the vertex array object with the vertex buffer
gl.glVertexArrayAttribBinding(vertexArrayName.get(0), Semantic.Attr.POSITION, Semantic.Stream.A);
gl.glVertexArrayAttribBinding(vertexArrayName.get(0), Semantic.Attr.NORMAL, Semantic.Stream.A);
gl.glVertexArrayAttribBinding(vertexArrayName.get(0), Semantic.Attr.TEXCOORD, Semantic.Stream.A);
// Set the format of the vertex attributes in the vertex array object
gl.glVertexArrayAttribFormat(vertexArrayName.get(0), Semantic.Attr.POSITION, 3, GL_FLOAT, false, 0);
gl.glVertexArrayAttribFormat(vertexArrayName.get(0), Semantic.Attr.NORMAL, 3, GL_FLOAT, false, 3 * 4);
gl.glVertexArrayAttribFormat(vertexArrayName.get(0), Semantic.Attr.TEXCOORD, 2, GL_FLOAT, false, 6 * 4);
// Enable the vertex attributes in the vertex object
gl.glEnableVertexArrayAttrib(vertexArrayName.get(0), Semantic.Attr.POSITION);
gl.glEnableVertexArrayAttrib(vertexArrayName.get(0), Semantic.Attr.NORMAL);
gl.glEnableVertexArrayAttrib(vertexArrayName.get(0), Semantic.Attr.TEXCOORD);
// Bind the triangle indices in the vertex array object the triangle indices buffer
gl.glVertexArrayElementBuffer(vertexArrayName.get(0), bufferNames.get(Buffer.ELEMENT));
// Bind the vertex array object to the vertex buffer
gl.glVertexArrayVertexBuffer(vertexArrayName.get(0), Semantic.Stream.A, bufferNames.get(Buffer.VERTEX), 0, (3+3+2) * 4);
}
private void initTexture(GL4 gl) {
try {
// Load texture
TextureData textureData = TextureIO.newTextureData(glProfile, new File(textureFilename), false, TextureIO.JPG);
// Generate texture name
gl.glGenTextures(1, textureNames);
// Bind the texture
gl.glBindTexture(gl.GL_TEXTURE_2D, textureNames.get(0));
// Specify the format of the texture
gl.glTexImage2D(gl.GL_TEXTURE_2D,
0,
textureData.getInternalFormat(),
textureData.getWidth(),
textureData.getHeight(),
textureData.getBorder(),
textureData.getPixelFormat(),
textureData.getPixelType(),
textureData.getBuffer());
// Set the sampler parameters
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Generate mip maps
gl.glGenerateMipmap(GL_TEXTURE_2D);
// Deactivate texture
gl.glBindTexture(GL_TEXTURE_2D, 0);
}
catch (IOException io) {
io.printStackTrace();
}
}
private float[] createSphereVertices(float radius, int numH, int numV) {
// Variables needed for the calculations
float t1, t2;
float pi = (float)Math.PI;
float pi2 = (float)Math.PI*2f;
float d1 = pi2/numH;
float d2 = pi/numV;
// Allocate the data needed to store the necessary positions, normals and texture coordinates
int numVertices = (numH*(numV-1)+2);
int numFloats = (3+3+2);
float[] data = new float[numVertices*numFloats];
data[0] = 0f; data[1] = radius; data[2] = 0f;
data[3] = 0f; data[4] = 1f; data[5] = 0f;
data[6] = 0.5f; data[7] = 1f;
for (int j=0; j<numV-1; j++) {
for (int i=0; i<numH; i++) {
// Position
data[(j*numH+i+1)*numFloats] = radius*(float)(Math.sin(i*d1)*Math.sin((j+1)*d2));
data[(j*numH+i+1)*numFloats+1] = radius*(float)Math.cos((j+1)*d2);
data[(j*numH+i+1)*numFloats+2] = radius*(float)(Math.cos(i*d1)*Math.sin((j+1)*d2));
// Normal
data[(j*numH+i+1)*numFloats+3] = (float)(Math.sin(i*d1)*Math.sin((j+1)*d2));
data[(j*numH+i+1)*numFloats+4] = (float)Math.cos((j+1)*d2);
data[(j*numH+i+1)*numFloats+5] = (float)(Math.cos(i*d1)*Math.sin((j+1)*d2));
// UV
data[(j*numH+i+1)*numFloats+6] = (float)(Math.asin(data[(j*numH+i+1)*numFloats+3])/Math.PI) + 0.5f;
data[(j*numH+i+1)*numFloats+7] = (float)(Math.asin(data[(j*numH+i+1)*numFloats+4])/Math.PI) + 0.5f;
}
}
data[(numVertices-1)*numFloats] = 0f; data[(numVertices-1)*numFloats+1] = -radius; data[(numVertices-1)*numFloats+2] = 0f;
data[(numVertices-1)*numFloats+3] = 0f; data[(numVertices-1)*numFloats+4] = -1f; data[(numVertices-1)*numFloats+5] = 0f;
data[(numVertices-1)*numFloats+6] = 0.5f; data[(numVertices-1)*numFloats+7] = 0f;
return data;
}
private short[] createSphereElements(int numH, int numV) {
// Allocate the data needed to store the necessary elements
int numTriangles = (numH*(numV-1)*2);
short[] data = new short[numTriangles*3];
for (int i=0; i<numH; i++) {
data[i*3] = 0; data[i*3+1] = (short)(i+1); data[i*3+2] = (short)((i+1)%numH+1);
}
for (int j=0; j<numV-2; j++) {
for (int i=0; i<numH; i++) {
data[((j*numH+i)*2+numH)*3] = (short)(j*numH+i+1);
data[((j*numH+i)*2+numH)*3+1] = (short)((j+1)*numH+i+1);
data[((j*numH+i)*2+numH)*3+2] = (short)((j+1)*numH+(i+1)%numH+1);
data[((j*numH+i)*2+numH)*3+3] = (short)((j+1)*numH+(i+1)%numH+1);
data[((j*numH+i)*2+numH)*3+4] = (short)(j*numH+(i+1)%numH+1);
data[((j*numH+i)*2+numH)*3+5] = (short)(j*numH+i+1);
}
}
int trianglIndex = (numTriangles-numH);
int vertIndex = (numV-2)*numH+1;
for (short i=0; i<numH; i++) {
data[(trianglIndex+i)*3] = (short)(vertIndex+i);
data[(trianglIndex+i)*3+1] = (short)((numH*(numV-1)+1));
data[(trianglIndex+i)*3+2] = (short)(vertIndex+(i+1)%numH);
}
return data;
}
// Private class representing a vertex program
private class Program {
// The name of the program
public int name = 0;
// Constructor
public Program(GL4 gl, String root, String vertex, String fragment) {
// Instantiate a complete vertex shader
ShaderCode vertShader = ShaderCode.create(gl, GL_VERTEX_SHADER, this.getClass(), root, null, vertex,
"vert", null, true);
// Instantiate a complete fragment shader
ShaderCode fragShader = ShaderCode.create(gl, GL_FRAGMENT_SHADER, this.getClass(), root, null, fragment,
"frag", null, true);
// Create the shader program
ShaderProgram shaderProgram = new ShaderProgram();
// Add the vertex and fragment shader
shaderProgram.add(vertShader);
shaderProgram.add(fragShader);
// Initialize the program
shaderProgram.init(gl);
// Store the program name (nonzero if valid)
name = shaderProgram.program();
// Compile and link the program
shaderProgram.link(gl, System.out);
}
}
// Interface for creating final static variables for defining the buffers
private interface Buffer {
int VERTEX = 0;
int ELEMENT = 1;
int GLOBAL_MATRICES = 2;
int MODEL_MATRIX1 = 3;
int MODEL_MATRIX2 = 4;
int MODEL_MATRIX3 = 5;
int LIGHT_PROPERTIES = 6;
int MATERIAL_PROPERTIES = 7;
int CAMERA_PROPERTIES = 8;
int MAX = 9;
}
// Private class to provide an semantic interface between Java and GLSL
private static class Semantic {
public interface Attr {
int POSITION = 0;
int NORMAL = 1;
int TEXCOORD = 2;
}
public interface Uniform {
int TRANSFORM0 = 1;
int TRANSFORM1 = 2;
int LIGHT0 = 3;
int MATERIAL = 4;
int CAMERA = 5;
}
public interface Stream {
int A = 0;
}
}
}
每个纹理都需要一个纹理对象。为此,您必须创建一个具有适当大小的容器。
private IntBuffer textureNames = GLBuffers.newDirectIntBuffer( noOfTextures );
并且您必须创建纹理对象并且必须加载纹理:
gl.glGenTextures( noOfTextures , textureNames);
for (int i=0; i<noOfTextures; i++) {
TextureData textureData = TextureIO.newTextureData(glProfile,
new File( textureFilename[i] ), false, TextureIO.JPG);
gl.glBindTexture(gl.GL_TEXTURE_2D, textureNames.get(i));
gl.glTexImage2D( ..... );
.....
}
最后,您必须在绘制网格之前绑定正确的纹理:
gl.glBindTexture(gl.GL_TEXTURE_2D, textureNames.get( texture_index1 ));
gl.glDrawElements( ..... );
.....
gl.glBindTexture(gl.GL_TEXTURE_2D, textureNames.get( texture_index2 ));
gl.glDrawElements( ..... );
删除纹理时,请注意生成的纹理数量:
gl.glDeleteTextures( noOfTextures , textureNames);