【问题标题】:Matrices not working in openGL矩阵在 openGL 中不起作用
【发布时间】:2016-01-03 22:40:05
【问题描述】:

我正在尝试创建一个正交矩阵,以及一个适当的模型和视图矩阵来查看一个简单的三角形,只是为了测试矩阵。我一直得到一个空白屏幕,我不知道发生了什么。我使用的是 LWJGL,而对于顶点和矩阵,我使用的是一个名为 JOML 的库。

主类(唯一的类):

import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.system.MemoryUtil.NULL;

import java.io.*;
import java.nio.*;

import org.joml.*;
import org.lwjgl.*;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;

public class Main {

    private GLFWErrorCallback errorCallback;
    private GLFWKeyCallback keyCallback;

    private long window;

    int WIDTH = 800, HEIGHT = 600;

    public void run() {
        System.out.println("Hello LWJGL " + Version.getVersion() + "!");

        try {
            init();
            loop();

            glfwDestroyWindow(window);
            keyCallback.release();
        } finally {
            glfwTerminate();
            errorCallback.release();
        }
    }

    private void init() {
        //initializes window
        glfwSetErrorCallback(errorCallback =                                                         GLFWErrorCallback.createPrint(System.err));

    if (glfwInit() != GLFW_TRUE)
        throw new IllegalStateException("Unable to initialize GLFW");

    glfwDefaultWindowHints(); 
    glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); 
    glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);

    window = glfwCreateWindow(WIDTH, HEIGHT, "Hello World!", NULL, NULL);
    if (window == NULL)
        throw new RuntimeException("Failed to create the GLFW window");

    glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() {
        @Override
        public void invoke(long window, int key, int scancode, int action, int mods) {
            if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
                glfwSetWindowShouldClose(window, GLFW_TRUE); 
        }
    });

    GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
    glfwSetWindowPos(window, (vidmode.width() - WIDTH) / 2, (vidmode.height() - HEIGHT) / 2);
    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);

    glfwShowWindow(window);
}

private void loop() {
    //Loads and initializes shaders
    GL.createCapabilities();
    //glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    int shaderProgram = glCreateProgram();
    int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

    StringBuilder vertexShaderSource = new StringBuilder();
    StringBuilder fragmentShaderSource = new StringBuilder();

    BufferedReader reader = null;
    try {
        reader = new BufferedReader(new FileReader("src/test/com/shader.vert"));

        String line;
        while((line = reader.readLine()) != null) {
            vertexShaderSource.append(line).append('\n');
        }

        reader.close();
    } catch(IOException e) {
        System.err.println("Vertex shader not loaded properly!");
        e.printStackTrace();
    }

    BufferedReader reader2 = null;
    try {
        reader2 = new BufferedReader(new FileReader("src/test/com/shader.frag"));

        String line;
        while((line = reader2.readLine()) != null) {
            fragmentShaderSource.append(line).append('\n');
        }

        reader2.close();
    } catch(IOException e) {
        System.err.println("Fragment shader not loaded properly!");
        e.printStackTrace();
    }

    glShaderSource(vertexShader, vertexShaderSource);
    glCompileShader(vertexShader);
    if(glGetShaderi(vertexShader, GL_COMPILE_STATUS) == GL_FALSE) {
        System.err.println("Vertex shader not compiled correctly!");
    }

    glShaderSource(fragmentShader, fragmentShaderSource);
    glCompileShader(fragmentShader);
    if(glGetShaderi(fragmentShader, GL_COMPILE_STATUS) == GL_FALSE) {
        System.err.println("Fragment Shader not compiled correctly!");
    }

    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    glValidateProgram(shaderProgram);

    //Matrices setup
    FloatBuffer projectionFloat = BufferUtils.createFloatBuffer(16);
    getProjectionMatrix(0, 800, 0, 600, -1, 1).get(projectionFloat);
    glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), false, projectionFloat);



    FloatBuffer viewFloat = BufferUtils.createFloatBuffer(16);
    getViewMatrix(new Vector3f(0, 0, 1), new Vector3f(0, 0, 0), new Vector3f(0, 1, 0)).get(viewFloat);
    glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), false, viewFloat);



    FloatBuffer modelFloat = BufferUtils.createFloatBuffer(16);
    getModelMatrix().get(modelFloat);
    glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), false, modelFloat);

    //Main loop
    while (glfwWindowShouldClose(window) == GLFW_FALSE) {
        glClear(GL_COLOR_BUFFER_BIT);

        glUseProgram(shaderProgram);

        glBegin(GL_TRIANGLES);
        {
            glVertex3f(100, 100, 50);
            glVertex3f(100, 400, 50);
            glVertex3f(400, 400, 50);
        }
        glEnd();

        glUseProgram(0);

        glfwSwapBuffers(window); 
        glfwPollEvents();
    }
}

public Matrix4f getModelMatrix() {
    return new Matrix4f(
            1, 0, 0, 0,
            0, 1, 0, 0,
            0, 0, 1, 0,
            0, 0, 0, 1
            );
}

public Matrix4f getProjectionMatrix(float bottom, float top, float left, float right, float near, float far) {
    return new Matrix4f(
            (2 / (right - left)), 0,                  0,                              -((right + left) / (right - left)),
            0,                    (2/(top - bottom)), 0,                              -((top + bottom) / (top - bottom)),
            0,                    0,                  (2 / (far - near)),             -((far + near) / (far - near)),
            0,                    0,                  0,                              1
            );
}

public Matrix4f getViewMatrix(Vector3f eye, Vector3f target, Vector3f up) {
    Vector3f zAxis = eye.sub(target);
    Vector3f xAxis = up.cross(zAxis);
    Vector3f yAxis = zAxis.cross(xAxis);

    return new Matrix4f(
            xAxis.x,         yAxis.x,         zAxis.x,        0,
            xAxis.y,         yAxis.y,         zAxis.y,        0,
            xAxis.z,         yAxis.z,         zAxis.z,        0,
           -xAxis.dot(eye), -yAxis.dot(eye), -zAxis.dot(eye), 1
           );
}

public static void main(String[] args) {
    new Main().run();
}
}

顶点着色器:

varying vec3 color;

in vec4 position;

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;

void main() {
    color = gl_Color.rgb;
    gl_Position = projection * view * model * position;
}

片段着色器:

varying vec3 color;

void main() {
    gl_FragColor = vec4(color, 1);
}

【问题讨论】:

  • glUniform*() 适用于当前程序。您需要在这些电话之前致电glUseProgram()
  • 我不是 opengl 专家,但我从未见过有人将旧的 opengl 函数(如(glBegin、glVertex、glEnd 等)与现代 opengl(如着色器)混合在一起)。我认为要解决您需要使用顶点缓冲区对象和 glDrawArrays 来实际使用着色器进行渲染的问题。
  • @jas 你可以结合 GLSL 和旧的 GL glBegin()/glEnd() 但在这种情况下你不能使用 core 配置文件,因为没有布局等...compatibility 个人资料是你的朋友

标签: java opengl lwjgl


【解决方案1】:

尝试将片段着色器更改为:

varying vec3 color;

out vec4 out_color;

void main() {
    out_color = vec4(color, 1);
}

片段着色器应该在处理顶点着色器的输出后输出颜色。

【讨论】:

  • @JosephBarton 另外,您应该将 Main 类分成几个其他小类,因为现在任何人都很难阅读 :)
  • 除非 OP 编辑​​了他的答案,否则 gl_FragColor = vec4(color, 1); 会做同样的事情。
【解决方案2】:

要使用glUniformMatrix4fv,您需要先调用glUseProgram,或者在opengl 4.1 及更高版本中,您可以使用glProgramUniformMatrix4fv 并将其传递给shaderProgram。

您还应该使用glGetProgramiv 检查着色器链接和验证错误。那里可能会失败。

你的顶点也被剪掉了,getProjectionMatrix(0, 800, 0, 600, -1, 1).get(projectionFloat); 在这里你说“深度”为 1,如果超出了它就不会被渲染。没关系,但在这里: glVertex3f(100, 100, 50); glVertex3f(100, 400, 50); glVertex3f(400, 400, 50); 您将通过它 50。如果您将投影矩阵更改为高于 50 的值,您将不得不通过它 -50,因为这是“前进”方向。否则它会“在你身后”。

你应该真正使用顶点缓冲区,而不是旧的固定 opengl 管道。

【讨论】:

    【解决方案3】:

    我认为您创建正交投影矩阵的函数不正确。

    我强烈建议阅读并理解这篇关于如何推导投影矩阵的文章:deriving projection matrices

    作为奖励,这里有一个不同的实现,您可以适应您的个人课程:

    Matrix4 orthographic_matrix(float width, float height, float z_near, float z_far)
    {
        float x_right = width * 0.5f;
        float x_left = width * -0.5f;
        float y_top = height * 0.5f;
        float y_bottom = height * -0.5f;
    
        float one_delta_x = 1.0f / (x_right - x_left);
        float one_delta_y = 1.0f / (y_top - y_bottom);
        float one_delta_z = 1.0f / (z_far - z_near);
    
        Matrix4 proj;
    
        proj(0, 0) = 2.0f * one_delta_x;
        proj(1, 1) = 2.0f * one_delta_y;
        proj(2, 2) = -2.0f * one_delta_z;
    
        proj(3, 0) = -1.0f * (x_right + x_left) * one_delta_x;
        proj(3, 1) = -1.0f * (y_top + y_bottom) * one_delta_y;
        proj(3, 2) = 1.0f * (z_far + z_near) * one_delta_z;
        proj(3, 3) = 1.0f;
    
        return proj;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多