Zolly
Zolly

Reputation: 317

Trying to integrate 2 OpenGL programs. My circle does not appear in my other program the way I want

I am trying to integrate 2 programs together.

I want to get the red circle to display in the "planet system". It is not supposed to move. I have tried integrating the code, but the circle does not appear as I want it to.

I noticed that when I uncomment these sections of code (below), the circle appears, but it moves around just like a planet.

static void init(GLFWwindow* window){
    /*------------------------Circle----------------------*/

        //// generate vertices of triangle fan
        //generate_circle();

        //// create VBO and buffer the data
        //glGenBuffers(1, &g_VBO[1]);
        //glBindBuffer(GL_ARRAY_BUFFER, g_VBO[1]);
        //glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * (g_slices + 2), g_vertices_circle, GL_STATIC_DRAW);

        //glGenBuffers(1, &g_VBO[2]);
        //glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]);
        //glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * (g_slices + 2), g_colors_circle, GL_STATIC_DRAW);

        //// create VAO and specify VBO data
        //glGenVertexArrays(1, &g_VAO[1]);
        //glBindVertexArray(g_VAO[1]);
        //glBindBuffer(GL_ARRAY_BUFFER, g_VBO[1]);
        //glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);    // specify the form of the data
        //glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]);
        //glVertexAttribPointer(colorIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);   // specify the form of the data

        /*----------------------------------------------------*/
}


static void render_scene(){
    //  glBindVertexArray(g_VAO[1]);            // make VAO active
    //
    ////Circle 1
    //  glDrawArrays(GL_LINE_LOOP, 0, g_slices + 2);    // display the vertices based on the primitive type
    //
    //  glBindVertexArray(g_VAO[0]);        // make VAO active
}

And also, my planet system disappears. I'm pretty sure this has something to do with my vertices being multiplied by the matrix in the vertex shader. How can I place the circle without it moving and making my "planets" disappear?

Here is my vertex shader

#version 330 core

// input data (different for all executions of this shader)
in vec3 aPosition;
in vec3 aColor;

// ModelViewProjection matrix
uniform mat4 uModelViewProjectionMatrix;

// output data (will be interpolated for each fragment)
out vec3 vColor;

void main()
{
    // set vertex position
    gl_Position = uModelViewProjectionMatrix * vec4(aPosition, 1.0);

    // the color of each vertex will be interpolated
    // to produce the color of each fragment
    vColor = aColor;
}

Here is my main program:

#include <cstdio>       // for C++ i/o
#include <iostream>
#include <string>
#include <cstddef>
using namespace std;    // to avoid having to use std::

#define GLEW_STATIC     // include GLEW as a static library
#include <GLEW/glew.h>  // include GLEW
#include <GLFW/glfw3.h> // include GLFW (which includes the OpenGL header)
#include <glm/glm.hpp>  // include GLM (ideally should only use the GLM headers that are actually used)
#include <glm/gtx/transform.hpp>
using namespace glm;    // to avoid having to use glm::

#include "shader.h"

#define PI 3.14159265
#define MAX_SLICES 50
#define MIN_SLICES 8
#define MAX_VERTICES (MAX_SLICES+2)*3   // a triangle fan should have a minimum of 3 vertices
#define CIRCLE_RADIUS 1.0
#define WINDOW_WIDTH 1500
#define WINDOW_HEIGHT 800

// struct for vertex attributes
struct Vertex
{
    GLfloat position[3];
    GLfloat color[3];
};

// global variables

GLfloat g_vertices_circle[MAX_VERTICES] = {
    0.0f, 0.0f, 0.0f,       // try adjusting this value to get rid of red line
    0.0f, 0.0f, 0.0f
};

GLfloat g_colors_circle[MAX_VERTICES] = {
    1.0f, 0.0f, 0.0f,
    1.0f, 0.0f, 0.0f
};

GLuint g_slices = MAX_SLICES;   // number of circle slices

Vertex g_vertices[] = {
    // vertex 1
    -0.5f, 0.5f, 0.5f,  // position
    1.0f, 0.0f, 1.0f,   // colour
    // vertex 2
    -0.5f, -0.5f, 0.5f, // position
    1.0f, 0.0f, 0.0f,   // colour
    // vertex 3
    0.5f, 0.5f, 0.5f,   // position
    1.0f, 1.0f, 1.0f,   // colour
    // vertex 4
    0.5f, -0.5f, 0.5f,  // position
    1.0f, 1.0f, 0.0f,   // colour
    // vertex 5
    -0.5f, 0.5f, -0.5f, // position
    0.0f, 0.0f, 1.0f,   // colour
    // vertex 6
    -0.5f, -0.5f, -0.5f,// position
    0.0f, 0.0f, 0.0f,   // colour
    // vertex 7
    0.5f, 0.5f, -0.5f,  // position
    0.0f, 1.0f, 1.0f,   // colour
    // vertex 8
    0.5f, -0.5f, -0.5f, // position
    0.0f, 1.0f, 0.0f,   // colour
};

GLuint g_indices[] = {
    0, 1, 2,    // triangle 1
    2, 1, 3,    // triangle 2
    4, 5, 0,    // triangle 3
    0, 5, 1,    // ...
    2, 3, 6,
    6, 3, 7,
    4, 0, 6,
    6, 0, 2,
    1, 5, 3,
    3, 5, 7,
    5, 4, 7,
    7, 4, 6,    // triangle 12
};

GLuint g_IBO = 0;               // index buffer object identifier
GLuint g_VBO[3];                // vertex buffer object identifier
GLuint g_VAO[2];                // vertex array object identifier
GLuint g_shaderProgramID = 0;   // shader program identifier
GLuint g_MVP_Index = 0;         // location in shader
glm::mat4 g_modelMatrix[5];     // object model matrices
glm::mat4 g_viewMatrix;         // view matrix
glm::mat4 g_projectionMatrix;   // projection matrix

float g_orbitSpeed[5] = { 0.3f, 1.0f, 0.7f, 0.9f, 1.2f };       // for speed of rotation around sun
float g_rotationSpeed[5] = { 0.07f, 0.7f, 3.0f, 5.0f, 1.0f };   // for speed of rotation on own axis
float g_scaleSize[5] = { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f };        // for scaling the orbiting planets
float g_axisOfRotation[5] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, };  // for offsetting the axis of rotation

void generate_circle()
{
    float angle = PI * 2 / static_cast<float>(g_slices);    // used to generate x and y coordinates
    float scale_factor = static_cast<float>(WINDOW_HEIGHT) / WINDOW_WIDTH;  // scale to make it a circle instead of an elipse
    int index = 0;  // vertex index

    g_vertices_circle[3] = CIRCLE_RADIUS * scale_factor;    // set x coordinate of vertex 1

                                                            // generate vertex coordinates for triangle fan
    for (int i = 2; i < g_slices + 2; i++)
    {
        // multiply by 3 because a vertex has x, y, z coordinates
        index = i * 3;

        g_vertices_circle[index] = CIRCLE_RADIUS * cos(angle) * scale_factor;
        g_vertices_circle[index + 1] = CIRCLE_RADIUS * sin(angle);
        g_vertices_circle[index + 2] = 0.0f;

        //Color for edges. See stackoverflow
        g_colors_circle[index] = 1.0f;
        g_colors_circle[index + 1] = 0.0f;
        g_colors_circle[index + 2] = 0.0f;

        // update to next angle
        angle += PI * 2 / static_cast<float>(g_slices);
    }

    // Gets rid of line from middle of circle
    g_vertices_circle[0] = g_vertices_circle[3];
    g_vertices_circle[1] = g_vertices_circle[4];
    g_vertices_circle[2] = g_vertices_circle[5];
}

static void init(GLFWwindow* window)
{
    glClearColor(0.0, 0.0, 0.0, 1.0);   // set clear background colour

    glEnable(GL_DEPTH_TEST);    // enable depth buffer test

    // create and compile our GLSL program from the shader files
    g_shaderProgramID = loadShaders("MVP_VS.vert", "ColorFS.frag");

    // enable point size
    glEnable(GL_PROGRAM_POINT_SIZE);
    // set line width
    glLineWidth(5.0);

    // find the location of shader variables
    GLuint positionIndex = glGetAttribLocation(g_shaderProgramID, "aPosition");
    GLuint colorIndex = glGetAttribLocation(g_shaderProgramID, "aColor");
    g_MVP_Index = glGetUniformLocation(g_shaderProgramID, "uModelViewProjectionMatrix");

    // initialise model matrix to the identity matrix
    g_modelMatrix[0] = g_modelMatrix[1] = g_modelMatrix[2] = g_modelMatrix[3] = g_modelMatrix[4] = glm::mat4(1.0f);

    // initialise view matrix
    g_viewMatrix = glm::lookAt(glm::vec3(10, 3, 8), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));    //perspective

    int width, height;
    glfwGetFramebufferSize(window, &width, &height);
    float aspectRatio = static_cast<float>(width) / height;

    // initialise projection matrix
    g_projectionMatrix = glm::perspective(45.0f, aspectRatio, 0.1f, 100.0f);

    // generate identifier for VBO and copy data to GPU
    glGenBuffers(1, &g_VBO[0]);
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertices), g_vertices, GL_STATIC_DRAW);

    // generate identifier for IBO and copy data to GPU
    glGenBuffers(1, &g_IBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(g_indices), g_indices, GL_STATIC_DRAW);

    // generate identifiers for VAO
    glGenVertexArrays(1, &g_VAO[0]);

    // create VAO and specify VBO data
    glBindVertexArray(g_VAO[0]);
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[0]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO);
    // interleaved attributes
    glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, position)));
    glVertexAttribPointer(colorIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, color)));

    /*------------------------Circle----------------------*/

    //// generate vertices of triangle fan
    //generate_circle();

    //// create VBO and buffer the data
    //glGenBuffers(1, &g_VBO[1]);
    //glBindBuffer(GL_ARRAY_BUFFER, g_VBO[1]);
    //glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * (g_slices + 2), g_vertices_circle, GL_STATIC_DRAW);

    //glGenBuffers(1, &g_VBO[2]);
    //glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]);
    //glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * (g_slices + 2), g_colors_circle, GL_STATIC_DRAW);

    //// create VAO and specify VBO data
    //glGenVertexArrays(1, &g_VAO[1]);
    //glBindVertexArray(g_VAO[1]);
    //glBindBuffer(GL_ARRAY_BUFFER, g_VBO[1]);
    //glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);    // specify the form of the data
    //glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]);
    //glVertexAttribPointer(colorIndex, 3, GL_FLOAT, GL_FALSE, 0, 0);   // specify the form of the data

    /*----------------------------------------------------*/

    glEnableVertexAttribArray(positionIndex);   // enable vertex attributes
    glEnableVertexAttribArray(colorIndex);
}

//Generates a random value between 0.1 and 0.9
double generateRandomFloat(float min, float max) 
{
    return min + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (max - min)));
}

// function used to update the scene
static void update_scene()
{
    // static variables for rotation angles
    static float orbitAngle[5] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, };
    static float rotationAngle[5] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
    float scaleFactor = 0.05;

    orbitAngle[0] += g_orbitSpeed[0] * scaleFactor;
    orbitAngle[1] += g_orbitSpeed[1] * scaleFactor;
    orbitAngle[2] += g_orbitSpeed[2] * scaleFactor;
    orbitAngle[3] += g_orbitSpeed[3] * scaleFactor;
    orbitAngle[4] += g_orbitSpeed[4] * scaleFactor;

    // update rotation angles
    rotationAngle[0] += g_rotationSpeed[0] * scaleFactor;
    rotationAngle[1] += g_rotationSpeed[1] * scaleFactor;
    rotationAngle[2] += g_rotationSpeed[2] * scaleFactor;
    rotationAngle[3] += g_rotationSpeed[3] * scaleFactor;
    rotationAngle[4] += g_rotationSpeed[4] * scaleFactor;

    // update model matrix
    g_modelMatrix[0] = glm::rotate(rotationAngle[0], glm::vec3(0.0f, 1.0f, 0.0f));

    g_modelMatrix[1] = glm::translate(glm::vec3(g_axisOfRotation[1], 0.0f, 0.0f))   //moves the axis of rotation along x-axis
        * glm::rotate(orbitAngle[1], glm::vec3(0.0f, 1.0f, 0.0f))
        * glm::translate(glm::vec3(2.0f, 0.0f, 0.0f))
        * glm::rotate(rotationAngle[1], glm::vec3(0.0f, -1.0f, 0.0f))       //enables rotation on own axis. try comment
        * glm::rotate(glm::radians(45.0f), glm::vec3(1.0f, 0.0f, 0.0f))     //rotates into a diamond shape
        * glm::rotate(glm::radians(45.0f), glm::vec3(0.0f, 0.0f, 1.0f))     //rotates into a diamond shape
        * glm::scale(glm::vec3(g_scaleSize[1], g_scaleSize[1], g_scaleSize[1]));

    g_modelMatrix[2] = glm::translate(glm::vec3(g_axisOfRotation[2], 0.0f, 0.0f))
        * glm::rotate(orbitAngle[2], glm::vec3(0.0f, -1.0f, 0.0f))
        * glm::translate(glm::vec3(4.0f, 0.0f, 0.0f))
        * glm::rotate(rotationAngle[2], glm::vec3(0.0f, 1.0f, 0.0f))
        * glm::scale(glm::vec3(g_scaleSize[2], g_scaleSize[2], g_scaleSize[2]));

    g_modelMatrix[3] = glm::translate(glm::vec3(g_axisOfRotation[3], 0.0f, 0.0f))
        * glm::rotate(orbitAngle[3], glm::vec3(0.0f, 1.0f, 0.0f))
        * glm::translate(glm::vec3(6.0f, 0.0f, 0.0f))
        * glm::rotate(rotationAngle[3], glm::vec3(0.0f, 1.0f, 0.0f))
        * glm::scale(glm::vec3(g_scaleSize[3], g_scaleSize[3], g_scaleSize[3]));

    g_modelMatrix[4] = glm::translate(glm::vec3(g_axisOfRotation[4], 0.0f, 0.0f))
        * glm::rotate(orbitAngle[4], glm::vec3(0.0f, -1.0f, 0.0f))  // -y changes orbit to clock-wise
        * glm::translate(glm::vec3(8.0f, 0.0f, 0.0f))
        * glm::rotate(rotationAngle[4], glm::vec3(0.0f, -1.0f, 0.0f))
        * glm::scale(glm::vec3(g_scaleSize[4], g_scaleSize[4], g_scaleSize[4]));
}

// function used to render the scene
static void render_scene()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear colour buffer and depth buffer

    glUseProgram(g_shaderProgramID);    // use the shaders associated with the shader program

//  glBindVertexArray(g_VAO[1]);            // make VAO active
//
////Circle 1
//  glDrawArrays(GL_LINE_LOOP, 0, g_slices + 2);    // display the vertices based on the primitive type
//
//  glBindVertexArray(g_VAO[0]);        // make VAO active

// Object 1
    glm::mat4 MVP = g_projectionMatrix * g_viewMatrix * g_modelMatrix[0];
    // set uniform model transformation matrix
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);

    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);   // display the vertices based on their indices and primitive type

// Object 2
    MVP = g_projectionMatrix * g_viewMatrix * g_modelMatrix[1];
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);   // display the vertices based on their indices and primitive type

// Object 3
    MVP = g_projectionMatrix * g_viewMatrix * g_modelMatrix[2];
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);   // display the vertices based on their indices and primitive type

// Object 4
    MVP = g_projectionMatrix * g_viewMatrix * g_modelMatrix[3];
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);   // display the vertices based on their indices and primitive type

// Object 5
    MVP = g_projectionMatrix * g_viewMatrix * g_modelMatrix[4];
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);   // display the vertices based on their indices and primitive type

    glFlush();  // flush the pipeline
}

int main(void)
{
    GLFWwindow* window = NULL;  // pointer to a GLFW window handle

    glfwSetErrorCallback(error_callback);   // set error callback function

    // initialise GLFW
    if (!glfwInit())
    {
        // if failed to initialise GLFW
        exit(EXIT_FAILURE);
    }

    // minimum OpenGL version 3.3
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

    // create a window and its OpenGL context
    window = glfwCreateWindow(1500, 1000, "Assignment 2", NULL, NULL);

    // if failed to create window
    if (window == NULL)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }

    glfwMakeContextCurrent(window); // set window context as the current context
    glfwSwapInterval(1);            // swap buffer interval

    // initialise GLEW
    if (glewInit() != GLEW_OK)
    {
        // if failed to initialise GLEW
        cerr << "GLEW initialisation failed" << endl;
        exit(EXIT_FAILURE);
    }

    // set key callback function
    glfwSetKeyCallback(window, key_callback);

    // initialise rendering states
    init(window);

    // variables for simple time management
    float lastUpdateTime = glfwGetTime();
    float currentTime = lastUpdateTime;

    // the rendering loop
    while (!glfwWindowShouldClose(window))
    {
        currentTime = glfwGetTime();

        // only update if more than 0.02 seconds since last update
        if (currentTime - lastUpdateTime > 0.02)
        {
            update_scene();     // update the scene
            render_scene();     // render the scene

            glfwSwapBuffers(window);    // swap buffers
            glfwPollEvents();           // poll for events

            lastUpdateTime = currentTime;   // update last update time
        }
    }

    // clean up
    glDeleteProgram(g_shaderProgramID);
    glDeleteBuffers(1, &g_IBO);
    glDeleteBuffers(1, &g_VBO[0]);
    glDeleteBuffers(1, &g_VBO[1]);
    glDeleteVertexArrays(1, &g_VAO[0]);
    glDeleteVertexArrays(1, &g_VAO[1]);

    // close the window and terminate GLFW
    glfwDestroyWindow(window);
    glfwTerminate();

    exit(EXIT_SUCCESS);
}

Upvotes: 1

Views: 132

Answers (1)

Rabbid76
Rabbid76

Reputation: 211166

You have to set the uniform variable uModelViewProjectionMatrix before you draw the circle. For all other objects you set a proper model view projection matrix, but you don't do so for the circle. Since the circle does not move and has no other location data you only need the projection matrix and the view matrix. In this case the model matrix is the identity matrix, so you can skip it.

glm::mat4 MVP = g_projectionMatrix * g_viewMatrix;
glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
glBindVertexArray(g_VAO[1]);
glDrawArrays(GL_LINE_LOOP, 0, g_slices + 2);

If you want to place the circle to another position in the scene you have to set up a model matrix for the circle and you have to concatenate the model matrix of the circle with the view matrix and the projection matrix.

glm::vec3 circlePos = ....;
glm::mat4 circleModelMat = glm::translate(glm::mat4(1.0f), circlePos);
glm::mat4 MVP = g_projectionMatrix * g_viewMatrix * circleModelMat;

Extension to the answer:

However, my cubes are still missing. All I can see is a static circle. Do you know how I can get the cubes to appear as well?

You have to enable the vertex attributes vor both vertex array objects:

glBindVertexArray(g_VAO[0]);
// ... bind buffer and set vetex attribute pointer
glEnableVertexAttribArray(positionIndex);   // enable vertex attributes
glEnableVertexAttribArray(colorIndex);

/*------------------------Circle----------------------*/
// ...
glBindVertexArray(g_VAO[1]);
// ... bind buffer and set vetex attribute pointer
glEnableVertexAttribArray(positionIndex);   // enable vertex attributes
glEnableVertexAttribArray(colorIndex);

Upvotes: 1

Related Questions