我有一个NetBeans项目(请参阅下面的zip文件链接),我试图从我的Visual Studio项目(C#)转换。 我正在使用LWJGL和JOML(对于Matrix类)的库,但无论我放置对象的哪个位置,它们都不会在屏幕上呈现。
这是init方法:
private void init() {
// Setup an error callback. The default implementation
// will print the error message in System.err.
GLFWErrorCallback.createPrint(System.err).set();
// Initialize GLFW. Most GLFW functions will not work before doing this.
if (!glfwInit()) {
throw new IllegalStateException("Unable to initialize GLFW");
}
// Configure GLFW
glfwDefaultWindowHints(); // optional, the current window hints are already the default
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
// Create the window
window = glfwCreateWindow(800, 600, "Hello World!", NULL, NULL);
if (window == NULL) {
throw new RuntimeException("Failed to create the GLFW window");
}
// Setup a key callback. It will be called every time a key is pressed, repeated or released.
glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) {
glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
}
});
int width = 0;
int height = 0;
// Get the thread stack and push a new frame
try (MemoryStack stack = stackPush()) {
IntBuffer pWidth = stack.mallocInt(1); // int*
IntBuffer pHeight = stack.mallocInt(1); // int*
// Get the window size passed to glfwCreateWindow
glfwGetWindowSize(window, pWidth, pHeight);
// Get the resolution of the primary monitor
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
width = pWidth.get(0);
height = pHeight.get(0);
// Center the window
glfwSetWindowPos(
window,
(vidmode.width() - pWidth.get(0)) / 2,
(vidmode.height() - pHeight.get(0)) / 2
);
} // the stack frame is popped automatically
// Make the OpenGL context current
glfwMakeContextCurrent(window);
// Enable v-sync
glfwSwapInterval(1);
GLCapabilities caps = GL.createCapabilities();
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glCullFace(GL11.GL_BACK);
initRenderPrograms();
float ratio = (float)width / height;
mViewMatrix = new Matrix4f();
mViewMatrix = mViewMatrix.lookAt(mCameraX, mCameraY, mCameraZ, mTargetX, mTargetY, mTargetZ,0,1,0 );
mProjectionMatrix = new Matrix4f();
mProjectionMatrix = mProjectionMatrix.frustum(-ratio, ratio, -1f, 1f, 1.0f, 1000f);
World.prepare(this);
// Make the window visible
glfwShowWindow(window);
}
...和渲染循环:
private void loop() {
// Set the clear color
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// Run the rendering loop until the user has attempted to close
// the window or has pressed the ESCAPE key.
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
for (Cube c : World.getGeometryObjects()) {
c.draw(mViewMatrix, mProjectionMatrix);
}
glfwSwapBuffers(window); // swap the color buffers
// Poll for window events. The key callback above will only be
// invoked during this call.
glfwPollEvents();
}
}
...和多维数据集实例的render方法:
public void draw(Matrix4f pViewMatrix, Matrix4f pProjectionMatrix) {
//System.out.println("program id: " + mRenderer.getProgramId());
GL20.glUseProgram(mRenderer.getProgramId());
int error = GL11.glGetError();
//System.out.println("Program: " + error);
Matrix4f modelMatrix = new Matrix4f();
modelMatrix.translate(new Vector3f(mXLL, mYLL, mZLL));
// Calculate mvp and mv matrix from translation matrix and view/projection matrix
Matrix4f mvMatrix = new Matrix4f();
//pViewMatrix.mul(modelMatrix, mvMatrix);
modelMatrix.mul(pViewMatrix, mvMatrix);
Matrix4f mvpMatrix = new Matrix4f();
//pProjectionMatrix.mul(mvMatrix, mvpMatrix);
mvMatrix.mul(pProjectionMatrix, mvpMatrix);
// Generate normal matrix by first inverting, then transposing the model matrix:
Matrix4f normalMatrixTemp = new Matrix4f();
mvMatrix.invert(normalMatrixTemp);
Matrix4f normalMatrix = new Matrix4f();
normalMatrixTemp.transpose(normalMatrix);
// Pass through the light's position in world space (if there is any light):
if (World.getLightObjects().size() > 0 && World.getLightObjects().get(0) != null && mRenderer.getUniformHandleLightPos() != -1) {
LightPoint currentLight = World.getLightObjects().get(0);
GL20.glUniform3f(mRenderer.getUniformHandleLightPos(), currentLight.getPosition().x, currentLight.getPosition().y, currentLight.getPosition().z);
error = GL11.glGetError();
//System.out.println("Lighting: " + error);
}
// Apply vertex data:
if (mRenderer.getAttributeHandlePosition() != -1) {
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, mRenderer.getBufferHandlePosition());
//GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, getVertexBuffer(), GL15.GL_STATIC_DRAW); //Send up the data and specify usage hint.
GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0);
GL20.glVertexAttribPointer(mRenderer.getAttributeHandlePosition(), 3, GL11.GL_FLOAT, false, 0, 0);
GL20.glEnableVertexAttribArray(mRenderer.getAttributeHandlePosition());
error = GL11.glGetError();
//System.out.println("Position: " + error);
}
// Apply color data:
if (mRenderer.getAttributeHandleColor() != -1) {
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, mRenderer.getBufferHandleColor());
//GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, getColorBuffer(), GL15.GL_STATIC_DRAW); //Send up the data and specify usage hint.
GL11.glColorPointer(3, GL11.GL_FLOAT, 0, 0);
GL20.glVertexAttribPointer(mRenderer.getAttributeHandleColor(), 3, GL11.GL_FLOAT, true, 0, 0);
GL20.glEnableVertexAttribArray(mRenderer.getAttributeHandleColor());
error = GL11.glGetError();
//System.out.println("Color: " + error);
}
// Apply normal data:
if (mRenderer.getAttributeHandleNormals() != -1) {
//GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, mRenderer.getBufferHandleNormals());
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, getNormalBuffer(), GL15.GL_STATIC_DRAW); //Send up the data and specify usage hint.
GL11.glColorPointer(3, GL11.GL_FLOAT, 0, 0);
GL20.glVertexAttribPointer(mRenderer.getAttributeHandleNormals(), 3, GL11.GL_FLOAT, true, 0, 0);
GL20.glEnableVertexAttribArray(mRenderer.getAttributeHandleNormals());
error = GL11.glGetError();
//System.out.println("Normals: " + error);
}
// Apply the texture:
if (mRenderer.getAttributeHandleTexture() != -1) {
GL13.glActiveTexture(GL13.GL_TEXTURE0 + 1); // Texture0 might (later) be used for depth map (dynamic shadows)
GL11.glBindTexture(GL11.GL_TEXTURE_2D, mTextureHandle);
GL20.glUniform1i(mRenderer.getUniformHandleTexture(), 1); // "1" because the active texture is texture unit 1
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, mRenderer.getBufferHandleTexture());
//GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, getTextureBuffer(), GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(mRenderer.getAttributeHandleTexture(), 2, GL11.GL_FLOAT, true, 0, 0);
GL20.glEnableVertexAttribArray(mRenderer.getAttributeHandleTexture());
error = GL11.glGetError();
//System.out.println("Texture: " + error);
}
// Pass mvp matrix as uniform to the shader:
FloatBuffer bufferMVP = BufferUtils.createFloatBuffer(16);
GL20.glUniformMatrix4fv(mRenderer.getUniformHandleMVP(), true, mvpMatrix.get(bufferMVP));
error = GL11.glGetError();
//System.out.println("MVP: " + error);
// Pass model matrix as uniform to the shader (for lighting):
if (mRenderer.getUniformHandleModelMatrix() != -1) {
FloatBuffer bufferM = BufferUtils.createFloatBuffer(16);
modelMatrix.get(bufferM);
GL20.glUniformMatrix4fv(mRenderer.getUniformHandleModelMatrix(), false, bufferM);
error = GL11.glGetError();
//System.out.println("ModelMatrix: " + error);
}
// Pass normal matrix as uniform to the shader:
if (mRenderer.getUniformHandleNormalMatrix() != -1){
FloatBuffer bufferNormals = BufferUtils.createFloatBuffer(16);
normalMatrix.get(bufferNormals);
GL20.glUniformMatrix4fv(mRenderer.getUniformHandleNormalMatrix(), false, bufferNormals);
error = GL11.glGetError();
//System.out.println("NormalMatrix: " + error);
}
// Finally draw the primitives:
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, mVertexCount);
error = GL11.glGetError();
//System.out.println("DrawArrays: " + error);
// Release all buffers for this object:
GL20.glDisableVertexAttribArray(mRenderer.getAttributeHandlePosition());
GL20.glDisableVertexAttribArray(mRenderer.getAttributeHandleColor());
GL20.glDisableVertexAttribArray(mRenderer.getAttributeHandleTexture());
GL20.glDisableVertexAttribArray(mRenderer.getAttributeHandleNormals());
error = GL11.glGetError();
//System.out.println("DisableArrays: " + error);
}
顶点和片段着色器:
attribute vec3 aPosition;
attribute vec3 aColor;
attribute vec2 aTexture;
attribute vec3 aNormal;
varying vec4 vPosition;
varying vec4 vColor;
varying vec2 vTexture;
varying vec3 vNormal;
uniform mat4 uMVP;
uniform mat4 uM;
uniform mat4 uNormalMatrix;
void main()
{
// Pass through the vertex position in world space (for measuring lighting angle and intensity)
vPosition = uM * vec4(aPosition, 1.0);
// Pass through object color adding an alpha of 1.0 (1.0 = visible, 0.0 = invisible)
vColor = vec4(aColor, 1.0);
// Pass through texture coordinate
vTexture = aTexture;
// Calculate normal vector in world space by multiplying normal matrix by normal vector
vNormal = vec3(uNormalMatrix * vec4(aNormal, 0.0));
// Calculate final vertex position on screen by multiplying the vertex
// coordinate by the model-view-projection matrix
gl_Position = uMVP * vec4(aPosition, 1.0);
}
varying vec4 vPosition;
varying vec4 vColor;
varying vec3 vNormal;
varying vec2 vTexture;
uniform sampler2D uTexture;
uniform vec3 uLightPos;
out vec4 gl_FragColor;
void main()
{
//Calculate the lighting vector (direction from light to fragment)
vec3 lightVec = normalize(uLightPos - vec3(vPosition));
//Calculate the lighting vector distance
float distance = length(uLightPos - vec3(vPosition));
// Calculate the dot product of normal vector and light vector and take the distance into account
float diffuseComponent = max(dot(vNormal, lightVec), 0.0) * (1.0 / (1.0 + (0.01 * distance * distance)));
// Create ambient light (if needed), otherwise everything that is not hit by light would be pitch black:
float ambientComponent = 1.0;
// Calculate the final fragment color (including the object's texture)
gl_FragColor = (diffuseComponent + ambientComponent) * vColor * texture2D(uTexture, vTexture);
}
我不知道错误可能在哪里。我认为它与Matrix类或我使用缓冲区的方式有关。似乎与C#中需要设置的方式有很大不同......
https://www.dropbox.com/s/gyr9pcm1ewtqy3l/JavaOpenGL.zip?dl=0(44MB)
如果有人看了我的项目并把我推向了正确的方向,那就太棒了。
提前致谢!