OpenGl, как переместить два круга - PullRequest
0 голосов
/ 25 апреля 2020

Я новичок в OpenGl, сейчас мой код может перемещать большой круг с маленьким внутри него вокруг окна. Подскажите, пожалуйста, как переместить маленький круг отдельно от большого, а также как вытащить его из большого круга.

И когда, например: маленький круг находится внутри большого, когда они движутся, они движутся вместе, и есть линия, которая соединяет центр окна с маленьким вихрем.

Вот мой код:

    #include <GL/glew.h>
#include <GLFW/glfw3.h>

#include "glm/glm.hpp"

#include <array>
#include <iostream>
#include <string>
#include <fstream>

#define PI 3.14159265359

using namespace std;

#define numVAOs 1

GLuint VBO;
GLuint VAO;

GLfloat radius = 0.2;
GLfloat centerx = 0.3;
GLfloat centery = 0;

GLfloat novX = 0.009;
GLfloat novY = 0.005;

GLdouble updateFrequency = 0.01, lastUpdate;

GLfloat s_vertices[600];

void updateVertexData()
{
    for (int i = 0; i < 100; i++)
    {
        s_vertices[3 * i] = centerx + radius * cos(i * (2 * PI / 100));
        s_vertices[3 * i + 1] = centery + radius * sin(i * (2 * PI / 100));
        s_vertices[3 * i + 2] = 0;
    }

}

void updateVertexData1()
{

    for (int j = 100; j < 200; j++) {
        s_vertices[3 * j] = centerx + radius * (cos(j * (2 * PI / 100))) / 5;
        s_vertices[3 * j + 1] = centery + radius * (sin(j * (2 * PI / 100))) / 5;
        s_vertices[3 * j + 2] = 0;


    }
}


void updateVBO() {
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(s_vertices), s_vertices, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}



GLuint renderingProgram;
GLuint vao[numVAOs];

bool checkOpenGLError() {
    bool foundError = false;
    int glErr = glGetError();
    while (glErr != GL_NO_ERROR) {
        cout << "glError: " << glErr << endl;
        foundError = true;
        glErr = glGetError();
    }
    return foundError;
}

void printShaderLog(GLuint shader) {
    int len = 0;
    int chWrittn = 0;
    char* log;
    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
    if (len > 0) {
        log = (char*)malloc(len);
        glGetShaderInfoLog(shader, len, &chWrittn, log);
        cout << "Shader Info Log: " << log << endl;
        free(log);
    }
}

void printProgramLog(int prog) {
    int len = 0;
    int chWrittn = 0;
    char* log;
    glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
    if (len > 0) {
        log = (char*)malloc(len);
        glGetProgramInfoLog(prog, len, &chWrittn, log);
        cout << "Program Info Log: " << log << endl;
        free(log);
    }
}

string readShaderSource(const char* filePath) {
    string content;
    ifstream fileStream(filePath, ios::in);
    string line = "";

    while (!fileStream.eof()) {
        getline(fileStream, line);
        content.append(line + "\n");
    }
    fileStream.close();
    return content;
}

GLuint createShaderProgram() {

    GLint vertCompiled;
    GLint fragCompiled;
    GLint linked;

    string vertShaderStr = readShaderSource("vertexShader.glsl");
    string fragShaderStr = readShaderSource("fragmentShader.glsl");

    GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
    GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);

    const char* vertShaderSrc = vertShaderStr.c_str();
    const char* fragShaderSrc = fragShaderStr.c_str();

    glShaderSource(vShader, 1, &vertShaderSrc, NULL);
    glShaderSource(fShader, 1, &fragShaderSrc, NULL);

    glCompileShader(vShader);
    checkOpenGLError();
    glGetShaderiv(vShader, GL_COMPILE_STATUS, &vertCompiled);
    if (vertCompiled != 1) {
        cout << "vertex compilation failed" << endl;
        printShaderLog(vShader);
    }

    glCompileShader(fShader);
    checkOpenGLError();
    glGetShaderiv(vShader, GL_COMPILE_STATUS, &fragCompiled);
    if (fragCompiled != 1) {
        cout << "fragment compilation failed" << endl;
        printShaderLog(fShader);
    }

    GLuint vfProgram = glCreateProgram();
    glAttachShader(vfProgram, vShader);
    glAttachShader(vfProgram, fShader);

    glLinkProgram(vfProgram);
    checkOpenGLError();
    glGetProgramiv(vfProgram, GL_LINK_STATUS, &linked);
    if (linked != 1) {
        cout << "linking failed" << endl;
        printProgramLog(vfProgram);
    }

    glDeleteShader(vShader);
    glDeleteShader(fShader);

    return vfProgram;
}

void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if (action == GLFW_PRESS)
    {
        switch (key) {
        case GLFW_KEY_ESCAPE:
            glfwSetWindowShouldClose(window, GLFW_TRUE);
            break;
        case GLFW_KEY_L:
            novX *= -1;
            break;
        case GLFW_KEY_R:
            radius += 0.01;
            updateVertexData();
            updateVertexData1();
            updateVBO();
            break;
        }
    }
}

void cursorPosCallback(GLFWwindow* window, double xPos, double yPos)
{

}

void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
{

}

void init() {
    renderingProgram = createShaderProgram();

    glGenBuffers(1, &VBO);
    glGenVertexArrays(1, &VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);

    glBufferData(GL_ARRAY_BUFFER, sizeof(s_vertices), s_vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);

    glEnableVertexAttribArray(0);

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void cleanUpScene()
{
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteProgram(renderingProgram);
}

void display(GLFWwindow* window, double currentTime) {
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT); // fontos lehet minden egyes alkalommal törölni!
    glUseProgram(renderingProgram);
    glBindVertexArray(VAO);

    glPointSize(8.0);
    glDrawArrays(GL_LINE_LOOP, 0, 99);
    glDrawArrays(GL_LINE_LOOP, 100, 200);


    if (currentTime - lastUpdate >= updateFrequency) {
        centerx += novX;
        centery += novY;
        if (centerx + radius > 1 - abs(novX) || centerx - radius < -1 + abs(novX))
            novX *= -1;
        if (centery + radius > 1 - abs(novY) || centery - radius < -1 + abs(novY))
            novY *= -1;
        lastUpdate = currentTime;
        updateVertexData();
        updateVertexData1();
        updateVBO();
    }
    glBindVertexArray(0);
}

int main(void) {
    updateVertexData();
    updateVertexData1();
    if (!glfwInit()) { exit(EXIT_FAILURE); }

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

    GLFWwindow* window = glfwCreateWindow(600, 600, "VAO VBO", NULL, NULL);

    glfwMakeContextCurrent(window);

    glfwSetKeyCallback(window, keyCallback);

    if (glewInit() != GLEW_OK) { exit(EXIT_FAILURE); }
    glfwSwapInterval(1);

    init();

    lastUpdate = glfwGetTime();

    while (!glfwWindowShouldClose(window)) {
        display(window, glfwGetTime());
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwDestroyWindow(window);

    cleanUpScene();

    glfwTerminate();
    exit(EXIT_SUCCESS);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...