От координаты пикселя до координаты OpenGL - PullRequest
0 голосов
/ 14 сентября 2018

Как я вижу в opengl, координаты находятся между -1 и 1, я хочу визуализировать объект, используя opengl, у меня есть первая позиция, где визуализировать объект в пиксельных координатах, но я не знаю, как преобразоватьпиксельные координаты в координаты opengl.Я работаю над приложением для Android с использованием Java.

открытый класс FirstOpenGLProjectRenderer реализует GLSurfaceView.Renderer {

private static final String A_POSITION = "a_Position";
private static final String A_COLOR = "a_Color";
private static final int POSITION_COMPONENT_COUNT = 4;
private static final int COLOR_COMPONENT_COUNT = 3;
private static final int BYTES_PER_FLOAT = 4;
private static final int STRIDE =
        (POSITION_COMPONENT_COUNT + COLOR_COMPONENT_COUNT) * BYTES_PER_FLOAT;

private final FloatBuffer vertexData;
private final Context context;

private int program;
private int aPositionLocation;
private int aColorLocation;

private static final String U_MATRIX = "u_Matrix";
private final float[] projectionMatrix = new float[16];
private int uMatrixLocation;
private final float[] modelMatrix = new float[16];



public FirstOpenGLProjectRenderer(Context context) {
    this.context = context;


 //
    // Vertex data is stored in the following manner:
    //
    // The first two numbers are part of the position: X, Y
    // The next three numbers are part of the color: R, G, B
    //
    float[] tableVerticesWithTriangles = {
            // Order of coordinates: X, Y, R, G, B


            // Triangle Fan
            0f, 0f, 0f, 1.5f, 1f, 1f, 1f,
            -0.5f, -0.8f, 0f, 1f, 0.7f, 0.7f, 0.7f,
            0.5f, -0.8f, 0f, 1f, 0.7f, 0.7f, 0.7f,
            0.5f, 0.8f, 0f, 2f, 0.7f, 0.7f, 0.7f,
            -0.5f, 0.8f, 0f, 2f, 0.7f, 0.7f, 0.7f,
            -0.5f, -0.8f, 0f, 1f, 0.7f, 0.7f, 0.7f,
        // Line 1
            -0.5f, 0f, 0f, 1.5f, 1f, 0f, 0f,
            0.5f, 0f, 0f, 1.5f, 1f, 0f, 0f,
        // Mallets
            0f, -0.4f, 0f, 1.25f, 0f, 0f, 1f,
            0f, 0.4f, 0f, 1.75f, 1f, 0f, 0f

    };

    vertexData = ByteBuffer
            .allocateDirect(tableVerticesWithTriangles.length * BYTES_PER_FLOAT)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();

    vertexData.put(tableVerticesWithTriangles);
}

@Override
public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    String vertexShaderSource = TextResourceReader
            .readTextFileFromResource(context, R.raw.imple_vertex_shader);
    String fragmentShaderSource = TextResourceReader
            .readTextFileFromResource(context, R.raw.simple_fragment_shader);

    int vertexShader = ShaderHelper.compileVertexShader(vertexShaderSource);
    int fragmentShader = ShaderHelper
            .compileFragmentShader(fragmentShaderSource);

    program = ShaderHelper.linkProgram(vertexShader, fragmentShader);

    if (LoggerConfig.ON) {
        ShaderHelper.validateProgram(program);
    }

    glUseProgram(program);

    uMatrixLocation = glGetUniformLocation(program, U_MATRIX);

    aPositionLocation = glGetAttribLocation(program, A_POSITION);
    aColorLocation = glGetAttribLocation(program, A_COLOR);

    // Bind our data, specified by the variable vertexData, to the vertex
    // attribute at location A_POSITION_LOCATION.
    vertexData.position(0);
    glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT,
            false, STRIDE, vertexData);

    glEnableVertexAttribArray(aPositionLocation);

    // Bind our data, specified by the variable vertexData, to the vertex
    // attribute at location A_COLOR_LOCATION.
    vertexData.position(POSITION_COMPONENT_COUNT);
    glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GL_FLOAT,
            false, STRIDE, vertexData);

    glEnableVertexAttribArray(aColorLocation);

}


@Override
public void onSurfaceChanged(GL10 glUnused, int width, int height) {
    // Set the OpenGL viewport to fill the entire surface.
    glViewport(0, 0, width, height);

    MatrixHelper.perspectiveM(projectionMatrix, 45, (float) width
            / (float) height, 1f, 10f);



    setIdentityM(modelMatrix, 0);

    translateM(modelMatrix, 0, 0f, 0f, -2.5f);
    rotateM(modelMatrix, 0, -60f, 1f, 0f, 0f);

    final float[] temp = new float[16];
    multiplyMM(temp, 0, projectionMatrix, 0, modelMatrix, 0);
    System.arraycopy(temp, 0, projectionMatrix, 0, temp.length);

/}

@Override
public void onDrawFrame(GL10 glUnused) {
    // Clear the rendering surface.
    glClear(GL_COLOR_BUFFER_BIT);

    // Assign the matrix
    glUniformMatrix4fv(uMatrixLocation, 1, false, projectionMatrix, 0);

    // Draw the table.
    glDrawArrays(GL_TRIANGLE_FAN, 0, 6);

    // Draw the center dividing line.
    glDrawArrays(GL_LINES, 6, 2);

    // Draw the first mallet.
    glDrawArrays(GL_POINTS, 8, 1);

    // Draw the second mallet.
    glDrawArrays(GL_POINTS, 9, 1);
}

}

1 Ответ

0 голосов
/ 14 сентября 2018

Прежде всего, если вы просто хотите нарисовать 2D примитивы на экране, вы хотите , а не применить любую 3D-модель, вид или матрицы проекции (т.е. использовать шейдер, который просто передает позицию черезнеизменным, или установить эти матрицы на идентичность).Затем вы в основном можете указать координаты материала для рисования непосредственно в пространстве клипа.clip-space - это на самом деле проективное пространство , а clip-space на самом деле - это четырехмерные однородные координаты , но сейчас вам не нужно об этом беспокоиться.Пока вы устанавливаете четвертую координату w на 1, координаты пространства клипа будут напрямую соответствовать нормализованным координатам устройства, то есть с этой системой координат от -1 до 1, с которой вы уже знакомы.

Итак, как мы можем перейти от пиксельных координат к нормализованным координатам устройства?Что нам нужно сделать, так это отобразить диапазон [0 .. w ) и [0 .. h ) x и y индексы пикселей для позиций в диапазоне [-1, 1] (где w и h - это количество пикселей окна / экрана в x и y направление соответственно).Здесь важно отметить, что расположение пикселей в OpenGL соответствует центрам ячеек сетки выборки.Это означает, что пиксель (0, 0) не попадает в левый нижний угол, а смещается на «1/2 пикселя».Если вы извините меня за искусство ASCII:

    |     |     |     |   
    +-----+-----+-----+---
    |  o  |  o  |  o  |   
    +-----+-----+-----+---
    |  o  |  o  |  o  |   
    +-----+-----+-----+---
    |  X  |  o  |  o  |   
    +-----+-----+-----+---
(-1, -1)

Расстояние между точками пикселей составляет 1 / w в x и 1 / h в направлении y .Таким образом, расположение пикселя ( x , y ) в нормализованных координатах устройства составляет:

x_ndc = 2.0f * (x + 0.5f) / w - 1.0f;
y_ndc = 2.0f * (y + 0.5f) / h - 1.0f;

И однородные координаты для вершины, которая должна быть размещена в этомточка будет (x_ndc, y_ndc, -1.0f, 1.0f).Обратите внимание, что координата z может быть любой глубиной, на которую вы хотите поместить 2D-элемент (-1 соответствует ближней плоскости, +1 - дальней).

...