Reputation: 317
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
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;
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