Как просмотреть трансформацию с использованием OpenGL в моем коде - PullRequest
0 голосов
/ 04 марта 2019

Я рисую круг в opengl и пытаюсь изменить экран камеры, чтобы показать круг.

Сначала я сделал круг с размером изображения, и превратил круг в треугольник и превратил его в VBO, и мне удалось вывести его на экран.

Однако,при просмотре преобразований с использованием матрицы MVP (модель, вид, проекция) треугольники окружности продолжают ломаться.

Ниже приведен мой код, основанный на http://www.opengl -tutorial.org / ru / beginners-tutorials / tutorial-3-matrices / коде.(Базовый код находится по адресу https://github.com/opengl-tutorials/ogl)

Я не знаю причину этой проблемы и хочу получить помощь.

мой код opengl

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// Include GLEW
#include <GL/glew.h>

// Include GLFW
#include <glfw3.h>
GLFWwindow* window;

// Include GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;

#include <common/shader.hpp>

#define PI 3.141592
#define TRI_POS_NUM 3

#define CIRCLE_RADIUS 350
#define X_INDEX 0
#define Y_INDEX 1
#define Z_INDEX 2

#define FIRST_TRI   0
#define SECOND_TRI  1
#define THIRD_TRI   2

#define IMG_WIDTH  1000
#define IMG_HEIGHT 1000

GLfloat *tri_pos_array; // array[2][TRI_POS_NUM] 2 is means X,Y
GLfloat *tri_array;     // array[3][2][TRI_POS_NUM] 2 is means X,Y and 3 is means The number of coordinates that make up the triangle.
GLfloat *tri_vbo_array;

void convert_img_coord_to_vbo_coord(GLfloat *x, GLfloat *y, int cx, int cy, int img_width, int img_height);
void init_vbo_tri_pos_array(GLfloat *tri_pos_array, int circle_radius, int tri_pos_num, int img_width, int img_height);
void init_tri_array(GLfloat *tri_array, GLfloat *tri_pos_array, int tri_pos_num, int img_width, int img_height);
void init_tri_vbo_array(GLfloat *tri_array, GLfloat *tri_vbo_array, int tri_pos_num);
void set_gl_array(GLfloat *in_tri_array, GLfloat *out_gl_array, int tri_pos_num);

void convert_img_coord_to_vbo_coord(GLfloat *x, GLfloat *y, int cx, int cy, int img_width, int img_height)
{
    GLfloat tmp_x = *x;
    GLfloat tmp_y = *y;
    float scale = 1.0;
    *x = (tmp_x - cx) / img_width * scale;
    *y = (tmp_y - cy) / img_height * scale;

}

void init_vbo_tri_pos_array(GLfloat *tri_pos_array, int circle_radius, int tri_pos_num, int img_width, int img_height)
{
    GLfloat x_pos = 0;
    GLfloat y_pos = 0;

    int index = 0;
    int cx = img_width / 2;
    int cy = img_height / 2;

    for (index; index < tri_pos_num; index++)
    {
        GLfloat theta = 2.0f * PI * GLfloat(index) / GLfloat(tri_pos_num);

        x_pos = cosf(theta) * circle_radius;
        y_pos = sinf(theta) * circle_radius;

        x_pos += cx;
        y_pos += cy;

        convert_img_coord_to_vbo_coord(&x_pos, &y_pos, cx, cy, img_width, img_height);

        tri_pos_array[X_INDEX * (tri_pos_num) + index] = x_pos;
        tri_pos_array[Y_INDEX * (tri_pos_num) + index] = y_pos;

    }
}
void init_tri_array(GLfloat *tri_array, GLfloat *tri_pos_array, int tri_pos_num, int img_width, int img_height)
{
    int index = 0;
    int cx = img_width / 2;
    int cy = img_height / 2;

    float z_value = 0.0f;

    for (index; index < tri_pos_num - 1; index++)
    {

        tri_array[(FIRST_TRI * 2 * (tri_pos_num)) + (X_INDEX * (tri_pos_num)) + index ] = 0.0f; // 0.0f is mean's VBO Coordinate cx
        tri_array[(FIRST_TRI * 2 * (tri_pos_num)) + (Y_INDEX * (tri_pos_num)) + index ] = 0.0f; // 0.0f is mean's VBO Coordinate cy
        tri_array[(FIRST_TRI * 2 * (tri_pos_num)) + (Z_INDEX * (tri_pos_num)) + index ] = z_value;    // 0.0f is mean's VBO Coordinate cy

        tri_array[(SECOND_TRI * 2 * (tri_pos_num)) + (X_INDEX * (tri_pos_num)) + index] = tri_pos_array[X_INDEX * (tri_pos_num)+index];
        tri_array[(SECOND_TRI * 2 * (tri_pos_num)) + (Y_INDEX * (tri_pos_num)) + index] = tri_pos_array[Y_INDEX * (tri_pos_num)+index];
        tri_array[(SECOND_TRI * 2 * (tri_pos_num)) + (Z_INDEX * (tri_pos_num)) + index] = z_value;

        tri_array[(THIRD_TRI * 2 * (tri_pos_num)) + (X_INDEX * (tri_pos_num)) + index] = tri_pos_array[(X_INDEX * (tri_pos_num)+index) + 1];
        tri_array[(THIRD_TRI * 2 * (tri_pos_num)) + (Y_INDEX * (tri_pos_num)) + index] = tri_pos_array[(Y_INDEX * (tri_pos_num)+index) + 1];
        tri_array[(THIRD_TRI * 2 * (tri_pos_num)) + (Z_INDEX * (tri_pos_num)) + index] = z_value;
    }

    tri_array[(FIRST_TRI * 2 * (tri_pos_num)) + (X_INDEX * (tri_pos_num)) + index]  = 0.0f; // 0.0f is mean's VBO Coordinate cx
    tri_array[(FIRST_TRI * 2 * (tri_pos_num)) + (Y_INDEX * (tri_pos_num)) + index]  = 0.0f; // 0.0f is mean's VBO Coordinate cy
    tri_array[(FIRST_TRI * 2 * (tri_pos_num)) + (Z_INDEX * (tri_pos_num)) + index]  = z_value;    // 0.0f is mean's VBO Coordinate cy

    tri_array[(SECOND_TRI * 2 * (tri_pos_num)) + (X_INDEX * (tri_pos_num)) + index] = tri_pos_array[X_INDEX * (tri_pos_num)+index];
    tri_array[(SECOND_TRI * 2 * (tri_pos_num)) + (Y_INDEX * (tri_pos_num)) + index] = tri_pos_array[Y_INDEX * (tri_pos_num)+index];
    tri_array[(SECOND_TRI * 2 * (tri_pos_num)) + (Z_INDEX * (tri_pos_num)) + index] = z_value;

    tri_array[(THIRD_TRI * 2 * (tri_pos_num)) + (X_INDEX * (tri_pos_num)) + index]  = tri_pos_array[0];
    tri_array[(THIRD_TRI * 2 * (tri_pos_num)) + (Y_INDEX * (tri_pos_num)) + index]  = tri_pos_array[tri_pos_num];
    tri_array[(THIRD_TRI * 2 * (tri_pos_num)) + (Z_INDEX * (tri_pos_num)) + index]  = z_value;
}
void set_gl_array(GLfloat *in_tri_array, GLfloat *out_gl_array, int tri_pos_num)
{
    int index = 0;

    //for(index; index < tri_pos_num -1 ; index++)
    for(index; index < tri_pos_num ; index++)
    {
        out_gl_array[ (index * 9) + 0 ] = in_tri_array[(FIRST_TRI * 2 * (tri_pos_num)) + (X_INDEX * (tri_pos_num)) + index ];
        out_gl_array[ (index * 9) + 1 ] = in_tri_array[(FIRST_TRI * 2 * (tri_pos_num)) + (Y_INDEX * (tri_pos_num)) + index ];
        out_gl_array[ (index * 9) + 2 ] = in_tri_array[(FIRST_TRI * 2 * (tri_pos_num)) + (Z_INDEX * (tri_pos_num)) + index ];

        out_gl_array[ (index * 9) + 3 ] = in_tri_array[(SECOND_TRI * 2 * (tri_pos_num)) + (X_INDEX * (tri_pos_num)) + index];
        out_gl_array[ (index * 9) + 4 ] = in_tri_array[(SECOND_TRI * 2 * (tri_pos_num)) + (Y_INDEX * (tri_pos_num)) + index];
        out_gl_array[ (index * 9) + 5 ] = in_tri_array[(SECOND_TRI * 2 * (tri_pos_num)) + (Z_INDEX * (tri_pos_num)) + index];

        out_gl_array[ (index * 9) + 6 ] = in_tri_array[(THIRD_TRI * 2 * (tri_pos_num)) + (X_INDEX * (tri_pos_num)) + index];
        out_gl_array[ (index * 9) + 7 ] = in_tri_array[(THIRD_TRI * 2 * (tri_pos_num)) + (Y_INDEX * (tri_pos_num)) + index];
        out_gl_array[ (index * 9) + 8 ] = in_tri_array[(THIRD_TRI * 2 * (tri_pos_num)) + (Z_INDEX * (tri_pos_num)) + index];
    }
}

int main( void )
{
    tri_pos_array   = (GLfloat *)malloc( sizeof(GLfloat ) * 2 * TRI_POS_NUM);
    tri_array       = (GLfloat *)malloc( sizeof(GLfloat ) * 3 * 3 * TRI_POS_NUM);
    tri_vbo_array   = (GLfloat *)malloc( sizeof(GLfloat ) * 3 * 3 * TRI_POS_NUM);

    init_vbo_tri_pos_array(tri_pos_array, CIRCLE_RADIUS, TRI_POS_NUM, IMG_WIDTH, IMG_HEIGHT);
    init_tri_array(tri_array, tri_pos_array, TRI_POS_NUM, IMG_WIDTH, IMG_HEIGHT);
    set_gl_array(tri_array, tri_vbo_array, TRI_POS_NUM);


    // Initialise GLFW
    if( !glfwInit() )
    {
        fprintf( stderr, "Failed to initialize GLFW\n" );
        getchar();
        return -1;
    }
    glfwWindowHint(GLFW_SAMPLES, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);

    // Open a window and create its OpenGL context
    window = glfwCreateWindow( IMG_WIDTH, IMG_HEIGHT, "Tutorial 03 - Matrices", NULL, NULL);
    if( window == NULL ){
        fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
        getchar();
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    // Initialize GLEW
    if (glewInit() != GLEW_OK) {
        fprintf(stderr, "Failed to initialize GLEW\n");
        getchar();
        glfwTerminate();
        return -1;
    }

    // Ensure we can capture the escape key being pressed below
    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

    // Dark blue background
    glClearColor(0.0f, 0.0f, 0.4f, 0.0f);

    // Create and compile our GLSL program from the shaders
    GLuint programID = LoadShaders( "SimpleTransform.vertexshader", "SingleColor.fragmentshader" );

    // Get a handle for our "MVP" uniform
    GLuint MatrixID = glGetUniformLocation(programID, "MVP");

    // Get a handle for our buffers
    GLuint vertexPosition_modelspaceID = glGetAttribLocation(programID, "vertexPosition_modelspace");

    // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
    //glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
    glm::mat4 Projection = glm::perspective(45.0f, (float) IMG_WIDTH/IMG_HEIGHT, 0.1f, 100.0f);

    // Or, for an ortho camera :
    //glm::mat4 Projection = glm::ortho(-10.0f,10.0f,-10.0f,10.0f,0.0f,100.0f); // In world coordinates

    // Camera matrix
    glm::mat4 View       = glm::lookAt(
            glm::vec3(1.0f,1.0f,1.0f), // Camera is at (4,3,3), in World Space
            glm::vec3(0.0f,0.0f,0.0f), // and looks at the origin
            glm::vec3(0.0f,-1.0f,0.0f)  // Head is up (set to 0,-1,0 to look upside-down)
            );
    // Model matrix : an identity matrix (model will be at the origin)
    glm::mat4 Model      = glm::mat4(2.0f);
    // Our ModelViewProjection : multiplication of our 3 matrices
    glm::mat4 MVP        = Projection * View * Model; // Remember, matrix multiplication is the other way around

    static const GLfloat g_vertex_buffer_data[] = {
        -1.0f, -1.0f, 0.0f,
        1.0f, -1.0f, 0.0f,
        0.0f,  1.0f, 0.0f,
    };
    static const GLushort g_element_buffer_data[] = { 0, 1, 2 };

    GLuint vertexbuffer;
    glGenBuffers(1, &vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    //glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 3 * TRI_POS_NUM, tri_vbo_array, GL_STATIC_DRAW);

    do{

        // Clear the screen
        glClear( GL_COLOR_BUFFER_BIT );

        // Use our shader
        glUseProgram(programID);

        // Send our transformation to the currently bound shader, 
        // in the "MVP" uniform
        glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

        // 1rst attribute buffer : vertices
        glEnableVertexAttribArray(vertexPosition_modelspaceID);
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
        glVertexAttribPointer(
                vertexPosition_modelspaceID, // The attribute we want to configure
                3,                  // size
                GL_FLOAT,           // type
                GL_FALSE,           // normalized?
                0,                  // stride
                (void*)0            // array buffer offset
                );

        // Draw the triangle !
        //glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle
        glDrawArrays(GL_TRIANGLES, 0, 3 * TRI_POS_NUM); // 3 indices starting at 0 -> 1 triangle

        glDisableVertexAttribArray(vertexPosition_modelspaceID);

        // Swap buffers
        glfwSwapBuffers(window);
        glfwPollEvents();

    } // Check if the ESC key was pressed or the window was closed
    while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
            glfwWindowShouldClose(window) == 0 );

    // Cleanup VBO and shader
    glDeleteBuffers(1, &vertexbuffer);
    glDeleteProgram(programID);

    // Close OpenGL window and terminate GLFW
    glfwTerminate();

    return 0;
}

мой вершинный шейдер "SimpleTransform.vertexshader"

#version 120     

// Input vertex data, different for all executions of this shader.    
attribute vec3 vertexPosition_modelspace;    

// Values that stay constant for the whole mesh.    
uniform mat4 MVP;    

void main(){    

    // Output position of the vertex, in clip space : MVP * position    
    gl_Position =  MVP * vec4(vertexPosition_modelspace,1);    
    //gl_Position = vec4(vertexPosition_modelspace,1);    

}              

мой фрагментный шейдер "SingleColor.fragmentshader"

#version 120

// Ouput data
//out vec3 color;

void main()
{

    // Output color = red, full opacity
    gl_FragColor = vec4(1,0,0, 1);

}
...