Related
I cannot figure out why the camera will not move when i move the mouse.
Here is my entire code:
#include <iostream> // cout, cerr
#include <cstdlib> // EXIT_FAILURE
#include <GL/glew.h> // GLEW library
#include <GLFW/glfw3.h> // GLFW library
// GLM Math Header inclusions
#include <glm/glm.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtc/type_ptr.hpp>
using namespace std; // Standard namespace
/*Shader program Macro*/
#ifndef GLSL
#define GLSL(Version, Source) "#version " #Version " core \n" #Source
#endif
// Unnamed namespace
namespace
{
const char* const WINDOW_TITLE = "Tutorial 4.3"; // Macro for window title
// Variables for window width and height
const int WINDOW_WIDTH = 800;
const int WINDOW_HEIGHT = 600;
// Stores the GL data relative to a given mesh
struct GLMesh
{
GLuint vao; // Handle for the vertex array object
GLuint vbo; // Handle for the vertex buffer object
GLuint nVertices; // Number of indices of the mesh
};
// Main GLFW window
GLFWwindow* gWindow = nullptr;
// Triangle mesh data
GLMesh gMesh;
// Shader program
GLuint gProgramId;
// camera
//Camera gCamera(glm::vec3(0.0f, 0.0f, 0.0f));
glm::vec3 gCameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 gCameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 gCameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
float gLastX = WINDOW_WIDTH / 2.0f;
float gLastY = WINDOW_HEIGHT / 2.0f;
bool gFirstMouse = true;
// timing
float gDeltaTime = 0.0f; // time between current frame and last frame
float gLastFrame = 0.0f;
// Default camera values
float Yaw = -90.0f;
float Pitch = 0.0f;
float cameraSpeed = 2.5f;
// camera options
float MovementSpeed;
float MouseSensitivity;
float Zoom;
}
/* User-defined Function prototypes to:
* initialize the program, set the window size,
* redraw graphics on the window when resized,
* and render graphics on the screen
*/
bool UInitialize(int, char* [], GLFWwindow** window);
void UResizeWindow(GLFWwindow* window, int width, int height);
void UProcessInput(GLFWwindow* window);
void UMousePositionCallback(GLFWwindow* window, double xpos, double ypos);
void UMouseScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
void UMouseButtonCallback(GLFWwindow* window, int button, int action, int mods);
void UCreateMesh(GLMesh& mesh);
void UDestroyMesh(GLMesh& mesh);
void URender();
bool UCreateShaderProgram(const char* vtxShaderSource, const char* fragShaderSource, GLuint& programId);
void UDestroyShaderProgram(GLuint programId);
/* Vertex Shader Source Code*/
const GLchar* vertexShaderSource = GLSL(440,
layout(location = 0) in vec3 position; // Vertex data from Vertex Attrib Pointer 0
layout(location = 1) in vec4 color; // Color data from Vertex Attrib Pointer 1
out vec4 vertexColor; // variable to transfer color data to the fragment shader
//Global variables for the transform matrices
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0f); // transforms vertices to clip coordinates
vertexColor = color; // references incoming color data
}
);
/* Fragment Shader Source Code*/
const GLchar* fragmentShaderSource = GLSL(440,
in vec4 vertexColor; // Variable to hold incoming color data from vertex shader
out vec4 fragmentColor;
void main()
{
fragmentColor = vec4(vertexColor);
}
);
int main(int argc, char* argv[])
{
if (!UInitialize(argc, argv, &gWindow))
return EXIT_FAILURE;
// Create the mesh
UCreateMesh(gMesh); // Calls the function to create the Vertex Buffer Object
// Create the shader program
if (!UCreateShaderProgram(vertexShaderSource, fragmentShaderSource, gProgramId))
return EXIT_FAILURE;
// Sets the background color of the window to black (it will be implicitely used by glClear)
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// render loop
// -----------
while (!glfwWindowShouldClose(gWindow))
{
// per-frame timing
// --------------------
float currentFrame = glfwGetTime();
gDeltaTime = currentFrame - gLastFrame;
gLastFrame = currentFrame;
// input
// -----
UProcessInput(gWindow);
// Render this frame
URender();
glfwPollEvents();
}
// Release mesh data
UDestroyMesh(gMesh);
// Release shader program
UDestroyShaderProgram(gProgramId);
exit(EXIT_SUCCESS); // Terminates the program successfully
}
// Initialize GLFW, GLEW, and create a window
bool UInitialize(int argc, char* argv[], GLFWwindow** window)
{
// GLFW: initialize and configure
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
// GLFW: window creation
// ---------------------
* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE, NULL, NULL);
if (*window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return false;
}
glfwMakeContextCurrent(*window);
glfwSetFramebufferSizeCallback(*window, UResizeWindow);
glfwSetCursorPosCallback(*window, UMousePositionCallback);
glfwSetScrollCallback(*window, UMouseScrollCallback);
glfwSetMouseButtonCallback(*window, UMouseButtonCallback);
// tell GLFW to capture our mouse
glfwSetInputMode(*window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
// GLEW: initialize
// ----------------
// Note: if using GLEW version 1.13 or earlier
glewExperimental = GL_TRUE;
GLenum GlewInitResult = glewInit();
if (GLEW_OK != GlewInitResult)
{
std::cerr << glewGetErrorString(GlewInitResult) << std::endl;
return false;
}
// Displays GPU OpenGL version
cout << "INFO: OpenGL Version: " << glGetString(GL_VERSION) << endl;
return true;
}
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
void UProcessInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
float cameraOffset = cameraSpeed * gDeltaTime;
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
gCameraPos += cameraOffset * gCameraFront;
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
gCameraPos -= cameraOffset * gCameraFront;
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
gCameraPos -= glm::normalize(glm::cross(gCameraFront, gCameraUp)) * cameraOffset;
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
gCameraPos += glm::normalize(glm::cross(gCameraFront, gCameraUp)) * cameraOffset;
if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS)
gCameraPos += cameraOffset * gCameraUp;
if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS)
gCameraPos -= cameraOffset * gCameraUp;
}
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
void UResizeWindow(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
// glfw: whenever the mouse moves, this callback is called
// -------------------------------------------------------
void UMousePositionCallback(GLFWwindow* window, double xpos, double ypos)
{
if (gFirstMouse)
{
gLastX = xpos;
gLastY = ypos;
gFirstMouse = false;
}
float xoffset = xpos - gLastX;
float yoffset = gLastY - ypos; // reversed since y-coordinates go from bottom to top
gLastX = xpos;
gLastY = ypos;
xoffset *= MouseSensitivity;
yoffset *= MouseSensitivity;
Yaw += xoffset;
Pitch += yoffset;
// make sure that when pitch is out of bounds, screen doesn't get flipped
if (Pitch > 89.0f)
Pitch = 89.0f;
if (Pitch < -89.0f)
Pitch = -89.0f;
// update Front, Right and Up Vectors using the updated Euler angles
glm::vec3 front;
front.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch));
front.y = sin(glm::radians(Pitch));
front.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch));
gCameraFront = glm::normalize(front);
}
// glfw: whenever the mouse scroll wheel scrolls, this callback is called
// ----------------------------------------------------------------------
void UMouseScrollCallback(GLFWwindow* window, double xoffset, double yoffset)
{
cameraSpeed += yoffset;
cameraSpeed = std::fmaxf(cameraSpeed, 1);
cameraSpeed = std::fminf(cameraSpeed, 100);
}
// glfw: handle mouse button events
// --------------------------------
void UMouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
{
switch (button)
{
case GLFW_MOUSE_BUTTON_LEFT:
{
if (action == GLFW_PRESS)
cout << "Left mouse button pressed" << endl;
else
cout << "Left mouse button released" << endl;
}
break;
case GLFW_MOUSE_BUTTON_MIDDLE:
{
if (action == GLFW_PRESS)
cout << "Middle mouse button pressed" << endl;
else
cout << "Middle mouse button released" << endl;
}
break;
case GLFW_MOUSE_BUTTON_RIGHT:
{
if (action == GLFW_PRESS)
cout << "Right mouse button pressed" << endl;
else
cout << "Right mouse button released" << endl;
}
break;
default:
cout << "Unhandled mouse button event" << endl;
break;
}
}
// Function called to render a frame
void URender()
{
// Enable z-depth
glEnable(GL_DEPTH_TEST);
// Clear the frame and z buffers
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 1. Scales the object by 2
glm::mat4 scale = glm::scale(glm::vec3(2.0f, 2.0f, 2.0f));
// 2. Rotates shape by 15 degrees in the x axis
glm::mat4 rotation = glm::rotate(45.0f, glm::vec3(1.0, 1.0f, 1.0f));
// 3. Place object at the origin
glm::mat4 translation = glm::translate(glm::vec3(0.0f, 0.0f, 0.0f));
// Model matrix: transformations are applied right-to-left order
glm::mat4 model = translation * rotation * scale;
// camera/view transformation
glm::mat4 view = glm::lookAt(gCameraPos, gCameraPos + gCameraFront, gCameraUp);
// Creates a perspective projection
glm::mat4 projection = glm::perspective(45.0f, (GLfloat)WINDOW_WIDTH / (GLfloat)WINDOW_HEIGHT, 0.1f, 100.0f);
// Set the shader to be used
glUseProgram(gProgramId);
// Retrieves and passes transform matrices to the Shader program
GLint modelLoc = glGetUniformLocation(gProgramId, "model");
GLint viewLoc = glGetUniformLocation(gProgramId, "view");
GLint projLoc = glGetUniformLocation(gProgramId, "projection");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
// Activate the VBOs contained within the mesh's VAO
glBindVertexArray(gMesh.vao);
// Draws the triangles
glDrawArrays(GL_TRIANGLES, 0, gMesh.nVertices);
// Deactivate the Vertex Array Object
glBindVertexArray(0);
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
glfwSwapBuffers(gWindow); // Flips the the back buffer with the front buffer every frame.
}
// Implements the UCreateMesh function
void UCreateMesh(GLMesh& mesh)
{
// Vertex data
GLfloat verts[] = {
// Vertex Positions // Colors (r,g,b,a)
0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Top Vertex
0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, // Front Bottom Right Vertex
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, // Front Bottom Left Vertex
0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Top Vertex
0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, // Back Bottom Right Vertex
-0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f, // Back Bottom Left Vertex
0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Top Vertex
-0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f, // Back Bottom Left Vertex
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, // Front Bottom Left Vertex
0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // Top Vertex
0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, // Back Bottom Right Vertex
0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, // Front Bottom Right Vertex
0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, // Back Bottom Right Vertex
0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, // Front Bottom Right Vertex
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, // Front Bottom Left Vertex
0.5f, -0.5f, -0.5f, 0.5f, 0.5f, 1.0f, 1.0f, // Back Bottom Right Vertex
-0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, 1.0f, // Back Bottom Left Vertex
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f // Front Bottom Left Vertex
};
const GLuint floatsPerVertex = 3;
const GLuint floatsPerColor = 4;
mesh.nVertices = sizeof(verts) / (sizeof(verts[0]) * (floatsPerVertex + floatsPerColor));
glGenVertexArrays(1, &mesh.vao); // we can also generate multiple VAOs or buffers at the same time
glBindVertexArray(mesh.vao);
// Create VBO
glGenBuffers(1, &mesh.vbo);
glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo); // Activates the buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); // Sends vertex or coordinate data to the GPU
// Strides between vertex coordinates
GLint stride = sizeof(float) * (floatsPerVertex + floatsPerColor);
// Create Vertex Attribute Pointers
glVertexAttribPointer(0, floatsPerVertex, GL_FLOAT, GL_FALSE, stride, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, floatsPerColor, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * floatsPerVertex));
glEnableVertexAttribArray(1);
}
void UDestroyMesh(GLMesh& mesh)
{
glDeleteVertexArrays(1, &mesh.vao);
glDeleteBuffers(1, &mesh.vbo);
}
// Implements the UCreateShaders function
bool UCreateShaderProgram(const char* vtxShaderSource, const char* fragShaderSource, GLuint& programId)
{
// Compilation and linkage error reporting
int success = 0;
char infoLog[512];
// Create a Shader program object.
programId = glCreateProgram();
// Create the vertex and fragment shader objects
GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
// Retrive the shader source
glShaderSource(vertexShaderId, 1, &vtxShaderSource, NULL);
glShaderSource(fragmentShaderId, 1, &fragShaderSource, NULL);
// Compile the vertex shader, and print compilation errors (if any)
glCompileShader(vertexShaderId); // compile the vertex shader
// check for shader compile errors
glGetShaderiv(vertexShaderId, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShaderId, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
return false;
}
glCompileShader(fragmentShaderId); // compile the fragment shader
// check for shader compile errors
glGetShaderiv(fragmentShaderId, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShaderId, sizeof(infoLog), NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
return false;
}
// Attached compiled shaders to the shader program
glAttachShader(programId, vertexShaderId);
glAttachShader(programId, fragmentShaderId);
glLinkProgram(programId); // links the shader program
// check for linking errors
glGetProgramiv(programId, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(programId, sizeof(infoLog), NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
return false;
}
glUseProgram(programId); // Uses the shader program
return true;
}
void UDestroyShaderProgram(GLuint programId)
{
glDeleteProgram(programId);
}
It was silly, took me a while to find it.
float MouseSensitivity; was declared but no default value was given. Therefore when i moved the mouse, it had no output since there was no value.
After scaling model2 matrix. model2 matrix is matrix of grid
Before
I want to increase size of grid not cube. Why is it happened? Why scale set y of cube to 0? Where is the mistake? All my code below.
Look at draw_canvas.cpp paintGL function, there is scaling matrix with name 'model2'. This line model2.scale(10.0f,0.0f,10.0f). Why this scaling changes my cube?
QMatrix4x4 model2(1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
unsigned int modelID2 = gridShaderProgram->uniformLocation("model");
model2.translate(QVector3D(0.0f, 0.0f, 0.0f));
model2.scale(10.0f, 0.0f, 10.0f);
draw_canwas3D.h
#pragma once
#include <QOpenGLWidget>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include <QOpenGLShaderProgram>
#include <QOpenGLShader>
#include <list>
class Canvas3D : public QOpenGLWidget
{
public:
Canvas3D(QWidget *parent = nullptr) : QOpenGLWidget(parent) { };
~Canvas3D();
private:
QOpenGLVertexArrayObject m_vao;
QOpenGLBuffer m_vbo;
QOpenGLShaderProgram* m_program;
QOpenGLShaderProgram* gridShaderProgram;
QOpenGLShaderProgram* shLightprogram;
QVector3D cameraPos {0.0f, 0.0f, 3.0f};
QVector3D cameraFront{0.0f, 0.0f, -1.0f};
QVector3D cameraUp{0.0f, 1.0f, 0.0f};
float yaw = -90.0f;
float pitch = 0.0f;
float lastX = 400, lastY = 300;
float Zoom = 45.0;
unsigned int gridVAO;
unsigned int gridEBO;
GLuint lenght = 0;
//std::list<Object*>
protected:
void initializeGL() override;
void resizeGL(int w, int h) override;
void paintGL() override;
void keyPressEvent(QKeyEvent *ev) override;
bool eventFilter(QObject *obj, QEvent *event);
};
draw_canvas3D.cpp
#include "draw_canvas3D.h"
#include "src/common/geometry/shapes3D/cube.h"
#include <iostream>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QOpenGLExtraFunctions>
#include <QMatrix4x4>
#include <QVector3D>
#include <QtMath>
#include <QKeyEvent>
void Canvas3D::initializeGL()
{
connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
auto functions = this->context()->functions();
functions->glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
this->setGeometry(100, 100, 800, 600);
functions->glViewport(this->geometry().x(),
this->geometry().y(),
this->geometry().width(),
this->geometry().height());
m_program = new QOpenGLShaderProgram(this);
QOpenGLShader vxShader(QOpenGLShader::Vertex);
vxShader.compileSourceFile("/main/stage/home/andreyp/fork_invar/invar/shaders/shader.vs");
QOpenGLShader frShader(QOpenGLShader::Fragment);
frShader.compileSourceFile("/main/stage/home/andreyp/fork_invar/invar/shaders/shader.fs");
m_program->addShader(&vxShader);
m_program->addShader(&frShader);
m_program->link();
functions->glEnable(GL_DEPTH_TEST);
this->installEventFilter(this);
functions->glEnable(GL_POLYGON_SMOOTH);
functions->glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
functions->glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
/*GRID*/ //Create Class
auto additionalFunctions = this->context()->extraFunctions();
unsigned int gridVBO;
std::vector<QVector3D> vertices;
std::vector<unsigned int> indices;
int slices = 10;
for(int j=0; j<=slices; ++j) {
for(int i=0; i<=slices; ++i) {
float x = (float)i/(float)slices;
float y = 0;
float z = (float)j/(float)slices;
vertices.push_back(QVector3D(x, y, z));
}
}
for(int j=0; j<slices; ++j) {
for(int i=0; i<slices; ++i) {
int row1 = j * (slices+1);
int row2 = (j+1) * (slices+1);
indices.push_back(row1+i); indices.push_back(row1+i+1); indices.push_back(row1+i+1); indices.push_back(row2+i+1);
indices.push_back(row2+i+1); indices.push_back(row2+i); indices.push_back(row2+i); indices.push_back(row1+i);
}
}
lenght = (GLuint)indices.size()*4;
/*std::vector<QVector3D> vecLines;
std::vector<unsigned int> vecLinesIdx;*/
/*for(unsigned int nHorizontalLines = 0; nHorizontalLines < 10; ++nHorizontalLines)
{
vecLines.push_back(QVector3D(0.0f, 0.0, -(float)nHorizontalLines));
vecLines.push_back(QVector3D(9.0f, 0.0, -(float)nHorizontalLines));
}
for(unsigned int nVerticalLines = 0; nVerticalLines < 10; ++nVerticalLines)
{
vecLines.push_back(QVector3D((float)nVerticalLines, 0.0f, 0.0f));
vecLines.push_back(QVector3D((float)nVerticalLines, 0.0f, -9.0f));
}
for(unsigned int j = 0; j < 39; j+=2)
{
vecLinesIdx.push_back(j);
vecLinesIdx.push_back(j+1);
}*/
functions->glGenBuffers(1, &gridEBO);
functions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gridEBO);
functions->glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);
functions->glGenBuffers(1, &gridVBO);
additionalFunctions->glGenVertexArrays(1, &gridVAO);
additionalFunctions->glBindVertexArray(gridVAO);
functions->glBindBuffer(GL_ARRAY_BUFFER, gridVBO);
functions->glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(QVector3D), vertices.data(), GL_STATIC_DRAW);
functions->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), nullptr);
functions->glEnableVertexAttribArray(0);
gridShaderProgram = new QOpenGLShaderProgram(this);
QOpenGLShader vxShader2(QOpenGLShader::Vertex);
vxShader2.compileSourceFile("/main/stage/home/andreyp/fork_invar/invar/shaders/shaderGrid.vs");
QOpenGLShader frShader2(QOpenGLShader::Fragment);
frShader2.compileSourceFile("/main/stage/home/andreyp/fork_invar/invar/shaders/shaderGrid.fs");
gridShaderProgram->addShader(&vxShader2);
gridShaderProgram->addShader(&frShader2);
gridShaderProgram->link();
/*GRID END*/
}
void Canvas3D::resizeGL(int w, int h)
{
auto functions = this->context()->functions();
functions->glViewport(0,
0,
this->geometry().width(),
this->geometry().height());
}
void Canvas3D::paintGL()
{
auto functions = this->context()->functions();
//auto additionalFunctions = this->context()->extraFunctions();
functions->glClearColor(0.0f / 255.0f, 25.0f / 255.0f, 53.0f / 255.0f, 1.0f);
functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QMatrix4x4 projection;
projection.perspective(Zoom, 800.0f / 600.0f, 0.1f, 100.0f);
QMatrix4x4 view;
view.lookAt(cameraPos,
cameraPos + cameraFront,
cameraUp);
unsigned int viewID = m_program->uniformLocation("view");
functions->glUniformMatrix4fv(viewID, 1, GL_FALSE, view.constData());
unsigned int projectionID = m_program->uniformLocation("projection");
functions->glUniformMatrix4fv(projectionID, 1, GL_FALSE, projection.constData());
QVector3D cubePositions[] = {
QVector3D(0.0f, 0.0, 0.0),
QVector3D( 0.5f, 0.0f, 0.5f),
QVector3D( 2.0f, 0.0f, 3.0f),
QVector3D(-1.5f, -2.2f, -2.5f),
QVector3D(-3.8f, -2.0f, -12.3f),
QVector3D( 2.4f, -0.4f, -3.5f),
QVector3D(-1.7f, 3.0f, -7.5f),
QVector3D( 1.3f, -2.0f, -2.5f),
QVector3D( 1.5f, 2.0f, -2.5f),
QVector3D( 1.5f, 0.2f, -1.5f),
QVector3D(-1.3f, 1.0f, -1.5f)
};
for(unsigned int i = 0; i < 2; i++)
{
QMatrix4x4 model(1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
unsigned int modelID = m_program->uniformLocation("model");
model.translate(cubePositions[i]);
functions->glUniformMatrix4fv(modelID, 1, GL_FALSE, model.constData());
auto cube3d = new invar::geometry3D::Cube(cubePositions[i], 1*qSqrt(3), m_program);
cube3d->Draw();
}
auto additionalFunctions = this->context()->extraFunctions();
additionalFunctions->glBindVertexArray(0);
/*GRID*/
unsigned int viewID2 = gridShaderProgram->uniformLocation("view");
functions->glUniformMatrix4fv(viewID2, 1, GL_FALSE, view.constData());
unsigned int projectionID2 = gridShaderProgram->uniformLocation("projection");
functions->glUniformMatrix4fv(projectionID2, 1, GL_FALSE, projection.constData());
QMatrix4x4 model2(1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
unsigned int modelID2 = gridShaderProgram->uniformLocation("model");
//model2.scale(10.0f, 0.0f, 10.0f); ------ THIS SCALING
model2.translate(QVector3D(0.0f, 0.0f, 0.0f));
functions->glUniformMatrix4fv(modelID2, 1, GL_FALSE, model2.constData());
gridShaderProgram->bind();
additionalFunctions->glBindVertexArray(gridVAO);
functions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gridEBO);
functions->glDrawElements(GL_LINES, lenght, GL_UNSIGNED_INT, 0);
/*GRID END*/
}
void Canvas3D::keyPressEvent(QKeyEvent *ev)
{
const float cameraSpeed = 0.25f;
if(ev->key() == Qt::Key_W)
cameraPos += cameraSpeed * cameraFront;
else if(ev->key() == Qt::Key_S)
cameraPos -= cameraSpeed * cameraFront;
else if(ev->key() == Qt::Key_A)
cameraPos -= QVector3D(QVector3D::crossProduct(cameraFront, cameraUp)) * cameraSpeed;
else if(ev->key() == Qt::Key_D)
cameraPos += QVector3D(QVector3D::crossProduct(cameraFront, cameraUp)) * cameraSpeed;
else if(ev->key() == Qt::Key_Q)
{
/*Rotate camera*/
}
else if(ev->key() == Qt::Key_E)
{
/*Rotate camera*/
}
}
bool Canvas3D::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::MouseButtonPress)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
lastX = mouseEvent->pos().x();
lastY = mouseEvent->pos().y();
}
if (event->type() == QEvent::MouseMove)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
float xoffset = mouseEvent->pos().x() - lastX;
float yoffset = lastY - mouseEvent->pos().y();
lastX = mouseEvent->pos().x();
lastY = mouseEvent->pos().y();
float sensitivity = 0.1f;
xoffset *= sensitivity;
yoffset *= sensitivity;
yaw += xoffset;
pitch += yoffset;
if(pitch > 89.0f)
pitch = 89.0f;
if(pitch < -89.0f)
pitch = -89.0f;
QVector3D direction;
direction.setX(qCos(qDegreesToRadians(yaw)) * qCos(qDegreesToRadians(pitch)));
direction.setY(qSin(qDegreesToRadians(pitch)));
direction.setZ(qSin(qDegreesToRadians(yaw)) * qCos(qDegreesToRadians(pitch)));
cameraFront = direction.normalized();
}
else if (event->type() == QEvent::Wheel)
{
QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event);
QPoint numDegrees = wheelEvent->angleDelta();
if (numDegrees.y() < 0 && Zoom < 45.0f)
Zoom += 1.0f;
if (numDegrees.y() > 0 && Zoom > 1.0f)
Zoom -= 1.0f;
}
return false;
}
Canvas3D::~Canvas3D()
{
//delete f;
}
cube.cpp
#include "src/common/geometry/shapes3D/cube.h"
#include <QOpenGLExtraFunctions>
#include <QOpenGLWidget>
#include <QOpenGLContext>
#include <QtMath>
#include <iostream>
namespace invar::geometry3D
{
void Cube::Draw()
{
auto context = QOpenGLContext::currentContext();
auto functions = context->functions();
auto additionalFunctions = context->extraFunctions();
m_program->bind();
additionalFunctions->glBindVertexArray(VAO);
functions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
int size;
functions->glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
functions->glDrawElements(GL_TRIANGLES, size/sizeof(float), GL_UNSIGNED_INT, 0);
}
void Cube::setupShape()
{
auto context = QOpenGLContext::currentContext();
auto functions = context->functions();
auto additionalFunctions = context->extraFunctions();
float vertices[] = {
-0.5f,0.5f,-0.5f, 0.0f, 0.0f, 0.0f,//Point A 0
-0.5f,0.5f,0.5f, 0.0f, 0.0f, 1.0f,//Point B 1
0.5f,0.5f,-0.5f, 0.0f, 1.0f, 0.0f,//Point C 2
0.5f,0.5f,0.5f, 0.0f, 1.0f, 1.0f,//Point D 3
-0.5f,-0.5f,-0.5f, 1.0f, 0.0f, 0.0f,//Point E 4
-0.5f,-0.5f,0.5f, 1.0f, 0.0f, 1.0f,//Point F 5
0.5f,-0.5f,-0.5f, 1.0f, 1.0f, 0.0f,//Point G 6
0.5f,-0.5f,0.5f, 1.0f, 1.0f, 1.0f//Point H 7
};
unsigned int indices[] = {
0,1,2,
1,2,3,
4,5,6,
5,6,7,
0,1,5,
0,4,5,
2,3,7,
2,6,7,
0,2,6,
0,4,6,
1,5,7,
1,3,7
};
functions->glGenBuffers(1, &EBO);
functions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
functions->glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
unsigned int VBO;
functions->glGenBuffers(1, &VBO);
additionalFunctions->glGenVertexArrays(1, &VAO);
additionalFunctions->glBindVertexArray(VAO);
functions->glBindBuffer(GL_ARRAY_BUFFER, VBO);
functions->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
functions->glEnableVertexAttribArray(0);/*Check if need to normilize*/
functions->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float),(void*)0);
functions->glEnableVertexAttribArray(1);
functions->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float),
(void*)(3*sizeof(float)));
additionalFunctions->glBindVertexArray(0);
}
Cube::Cube(QVector3D pos, float diagonal, QOpenGLShaderProgram* m_program):
pos(pos), diagonal(diagonal), m_program(m_program)
{
this->setupShape();
}
}
cube.h
#pragma once
#include "shape3D.h"
#include <QOpenGLContext>
#include <QVector3D>
#include <QOpenGLShaderProgram>
namespace invar::geometry3D
{
class Cube
{
public:
Cube(QVector3D pos, float diagonal, QOpenGLShaderProgram* program);
void Draw();
private:
unsigned int VAO;
unsigned int EBO;
QVector3D pos;
float diagonal;
QOpenGLShaderProgram* m_program;
void setupShape();
};
}
Shaders is simple
shaderGrid.fs
#version 130
out vec4 FragColor;
void main()
{
FragColor = vec4(0, 1.0, 1.0, 1.0);
}
shaderGrid.vs
#version 130
in vec3 aPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
}
shader.fs //--- CUBE FRAGMENT SHADER
#version 130
out vec4 FragColor;
in vec3 ourColor;
void main()
{
FragColor = vec4(ourColor, 1.0);
}
shader.vs //--- CUBE VERTEX SHADER
#version 130
in vec3 aPos;
in vec3 aColor;
out vec3 ourColor;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
ourColor = aColor;
}
glUniform* changes a uniform of the currently installed shader program. Therefore, you must install (bind) the program before setting the uniforms:
gridShaderProgram->bind(); // <--- INSERT
unsigned int viewID2 = gridShaderProgram->uniformLocation("view");
functions->glUniformMatrix4fv(viewID2, 1, GL_FALSE, view.constData());
unsigned int projectionID2 = gridShaderProgram->uniformLocation("projection");
functions->glUniformMatrix4fv(projectionID2, 1, GL_FALSE, projection.constData());
QMatrix4x4 model2(1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
unsigned int modelID2 = gridShaderProgram->uniformLocation("model");
//model2.scale(10.0f, 0.0f, 10.0f); ------ THIS SCALING
model2.translate(QVector3D(0.0f, 0.0f, 0.0f));
functions->glUniformMatrix4fv(modelID2, 1, GL_FALSE, model2.constData());
// gridShaderProgram->bind(); <--- DELETE
I have been using this tutorial to create a skybox but sampling the texture returns black. If I use my texture coordinates as colour then I get sensible looking coloured skybox so I presume the problem is with the texture sampling! Could it be a problem with my graphics card or openGL version?
Here is my code:
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include "utils.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#define CUSTOM_PI 3.1415926535897931
/*
*
* Include files for Windows, Linux and OSX
* __APPLE is defined if OSX, otherwise Windows and Linux.
*
*/
#ifdef __APPLE__
#define GLFW_INCLUDE_GLCOREARB 1
#include <GLFW/glfw3.h>
#else
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#endif
struct Vertex {
GLfloat position[3];
};
float aspectRatio;
// Position of camera in world space
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 200.0f);
// Camera Orientation in view space
glm::vec3 cameraOrientation = glm::vec3(0.0f, 1.0f, 0.0f);
/* yaw is initialized to -90.0 degrees since a yaw of 0.0 results in a direction
* vector pointing to the right so we initially rotate a bit to the left. */
float yaw = -90.0f;
float pitch = 0.0f;
float yawPitchStep = 2.0f;
float cameraSpeed = 0.0f;
float cameraAccelerationStep = 0.025f;
float cameraDecelerationStep = 0.05f;
bool left = false;
bool right = false;
bool page_up = false;
bool page_down = false;
bool up = false;
bool down = false;
GLuint shaderProgram;
unsigned int skyboxVAO, skyboxVBO;
unsigned int cubemapTexture;
/* Whenever the window size changed (by OS or user resize) this callback
* function executes */
void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
/* Make sure the viewport matches the new window dimensions; note that width
* and height will be significantly larger than specified on retina
* displays. */
if (!(width == 0 || height == 0)) {
aspectRatio = (float)width / (float)height;
glViewport(0, 0, width, height);
}
}
static void key_callback(GLFWwindow *window, int key, int scancode, int action,
int mods) {
if ((key == GLFW_KEY_ESCAPE || key == GLFW_KEY_Q) && action == GLFW_PRESS) {
glfwSetWindowShouldClose(window, GL_TRUE);
}
if (key == GLFW_KEY_LEFT) {
if (action == GLFW_PRESS)
left = true;
if (action == GLFW_RELEASE)
left = false;
}
if (key == GLFW_KEY_RIGHT) {
if (action == GLFW_PRESS)
right = true;
if (action == GLFW_RELEASE)
right = false;
}
if (key == GLFW_KEY_PAGE_UP) {
if (action == GLFW_PRESS)
page_up = true;
if (action == GLFW_RELEASE)
page_up = false;
}
if (key == GLFW_KEY_PAGE_DOWN) {
if (action == GLFW_PRESS)
page_down = true;
if (action == GLFW_RELEASE)
page_down = false;
}
if (key == GLFW_KEY_UP) {
if (action == GLFW_PRESS)
up = true;
if (action == GLFW_RELEASE)
up = false;
}
if (key == GLFW_KEY_DOWN) {
if (action == GLFW_PRESS)
down = true;
if (action == GLFW_RELEASE)
down = false;
}
}
// loads a cubemap texture from 6 individual texture faces
// order:
// +X (right)
// -X (left)
// +Y (top)
// -Y (bottom)
// +Z (front)
// -Z (back)
// -------------------------------------------------------
unsigned int loadCubemap(std::vector<std::string> faces) {
unsigned int textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);
int width, height, nrChannels;
for (unsigned int i = 0; i < faces.size(); i++) {
unsigned char *data =
stbi_load(faces[i].c_str(), &width, &height, &nrChannels, 0);
if (data) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width,
height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
stbi_image_free(data);
} else {
std::cout << "Cubemap texture failed to load at path: " << faces[i]
<< std::endl;
stbi_image_free(data);
}
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
return textureID;
}
void setup() {
// These pointers will receive the contents of our shader source code files
GLchar *vertexSource, *fragmentSource;
// These are handles used to reference the shaders
GLuint vertexShader, fragmentShader;
/* Read our shaders into the appropriate buffers */
vertexSource = fileToBuf("./skyboxShader.vert");
fragmentSource = fileToBuf("./skyboxShader.frag");
/* Assign our handles a "name" to new shader objects */
vertexShader = glCreateShader(GL_VERTEX_SHADER);
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
/* Associate the source code buffers with each handle */
glShaderSource(vertexShader, 1, (const GLchar **)&vertexSource, 0);
glShaderSource(fragmentShader, 1, (const GLchar **)&fragmentSource, 0);
/* Compile our shader objects */
glCompileShader(vertexShader);
glCompileShader(fragmentShader);
/* Assign our program handle a "name" */
shaderProgram = glCreateProgram();
// Attach our shaders to our program
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindAttribLocation(shaderProgram, 0, "in_Position");
// Link our program, and set it as being actively used
glLinkProgram(shaderProgram);
checkShader(shaderProgram, "Basic Shader");
glUseProgram(shaderProgram);
GLuint cubemapTexture;
glGenTextures(1, &cubemapTexture);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
float skyboxVertices[] = {
// positions
-1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f};
// skybox VAO
glGenVertexArrays(1, &skyboxVAO);
glGenBuffers(1, &skyboxVBO);
glBindVertexArray(skyboxVAO);
glBindBuffer(GL_ARRAY_BUFFER, skyboxVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices,
GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float),
(void *)0);
// load textures
// -------------
std::vector<std::string> faces{
"./textures/skybox/right.jpg", "./textures/skybox/left.jpg",
"./textures/skybox/top.jpg", "./textures/skybox/bottom.jpg",
"./textures/skybox/front.jpg", "./textures/skybox/back.jpg"};
cubemapTexture = loadCubemap(faces);
// shader configuration
// --------------------
glUniform1i(glGetUniformLocation(shaderProgram, "skybox"), 0);
}
void render(float time, glm::mat4 projection, glm::mat4 view) {
// draw skybox as last
glDepthFunc(GL_LEQUAL); // change depth function so depth test passes when
// values are equal to depth buffer's content
glUseProgram(shaderProgram);
view =
glm::mat4(glm::mat3(view)); // remove translation from the view matrix
glm::mat4 VP = projection * view;
// Bind Model, View, Perspective transformation matrix to be a uniform
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "vpmatrix"), 1,
GL_FALSE, glm::value_ptr(VP));
// skybox cube
glBindVertexArray(skyboxVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glDepthFunc(GL_LESS); // set depth function back to default
}
int main(void) {
int k = 0;
float time = 0;
GLFWwindow *window;
if (!glfwInit()) {
printf("Failed to start GLFW\n");
exit(EXIT_FAILURE);
}
#ifdef __APPLE__
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#endif
window = glfwCreateWindow(800, 800, "Graphics Test", NULL, NULL);
aspectRatio = 1.0f;
if (!window) {
glfwTerminate();
printf("GLFW Failed to start\n");
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
#ifndef __APPLE__
glewExperimental = GL_TRUE;
int err = glewInit();
if (GLEW_OK != err) {
/* Problem: glewInit failed, something is seriously wrong. */
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
}
#endif
glfwSetKeyCallback(window, key_callback);
fprintf(stderr, "GL INFO %s\n", glGetString(GL_VERSION));
glEnable(GL_DEPTH_TEST);
setup();
printf("Ready to render\n");
while (!glfwWindowShouldClose(window)) { // Main loop
time = glfwGetTime();
// Make our blue to ensure skybox is working.
glClearColor(0.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* Defines the projection:
* With 45 degree field of view
* With A given aspect ratio
* Cliping everything closer than 0.1 to the camera
* Cliping everything further than 1000 from the camera */
glm::mat4 Projection =
glm::perspective(45.0f, aspectRatio, 0.1f, 1000.0f);
if (left) {
yaw -= yawPitchStep;
}
if (right) {
yaw += yawPitchStep;
}
if (page_up) {
pitch += yawPitchStep;
}
if (page_down) {
pitch -= yawPitchStep;
}
if (up) {
cameraSpeed += cameraAccelerationStep;
printf("Camera Speed = %f\n", cameraSpeed);
}
if (down) {
cameraSpeed -= cameraDecelerationStep;
if (cameraSpeed < 0) {
cameraSpeed = 0;
}
printf("Camera Speed = %f\n", cameraSpeed);
}
glm::vec3 front;
front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
front.y = sin(glm::radians(pitch));
front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
glm::vec3 cameraDirection = glm::normalize(front);
cameraPos += cameraSpeed * cameraDirection;
glm::mat4 View = glm::lookAt(cameraPos, cameraPos + cameraDirection,
cameraOrientation);
render(time, Projection, View);
k++;
glfwSwapBuffers(window); // Swap front and back rendering buffers
glfwPollEvents(); // Poll for events.
}
glfwTerminate(); // Close window and terminate GLFW
exit(EXIT_SUCCESS); // Exit program
}
And my vertex shader:
#version 400
precision highp float;
// Position of vertex
in vec3 in_Position;
// The model, view, and projection matrices which needs to be applied to every vertex
uniform mat4 vpmatrix;
// Texture coordinates passed on to fragment shader
out vec3 TexCoords;
void main(void) {
TexCoords = in_Position;
vec4 pos = vpmatrix * vec4(in_Position, 1.0);
gl_Position = pos.xyww;
}
And my fragment shader:
#version 400
precision highp float;
in vec3 TexCoords;
out vec4 FragColor;
uniform samplerCube skybox;
void main()
{
FragColor = texture(skybox, TexCoords);
// FragColor = vec4(TexCoords, 1.0f);
}
The global variable unsigned int cubemapTexture;, which is used in the function render is never set, because there is a 2nd (local) variable named cubemapTexture in the function setup.
Remove the local variable cubemapTexture from the function setup to solve the issue:
unsigned int cubemapTexture;
void setup() {
.....
GLuint cubemapTexture; // delete this part of the
glGenTextures(1, &cubemapTexture); //
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture); //
.....
cubemapTexture = loadCubemap(faces);
.....
}
void render(float time, glm::mat4 projection, glm::mat4 view) {
.....
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);
.....
}
unable to insert more than one element in vector; worked fine when I tested with an integer vector. tried the following:
push_back function
insert function
assign function
The issue is in the createObjects() function this error due to the way i have written the opengl code...?
Thank you very much
// Include standard headers
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <array>
#include <sstream>
// Include GLEW
#include <GL/glew.h>
// Include GLFW
#include <glfw3.h>
// Include GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/quaternion.hpp>
using namespace glm;
// Include AntTweakBar
#include <AntTweakBar.h>
#include <common/shader.hpp>
#include <common/controls.hpp>
#include <common/objloader.hpp>
#include <common/vboindexer.hpp>
typedef struct Vertex {
float XYZW[4];
float RGBA[4];
void SetCoords(float *coords) {
XYZW[0] = coords[0];
XYZW[1] = coords[1];
XYZW[2] = coords[2];
XYZW[3] = coords[3];
}
void SetColor(float *color) {
RGBA[0] = color[0];
RGBA[1] = color[1];
RGBA[2] = color[2];
RGBA[3] = color[3];
}
};
// ATTN: USE POINT STRUCTS FOR EASIER COMPUTATIONS
typedef struct point {
float x, y, z;
point(const float x = 0, const float y = 0, const float z = 0) : x(x), y(y), z(z) {};
point(float *coords) : x(coords[0]), y(coords[1]), z(coords[2]) {};
point operator -(const point& a)const {
return point(x - a.x, y - a.y, z - a.z);
}
point operator +(const point& a)const {
return point(x + a.x, y + a.y, z + a.z);
}
point operator *(const float& a)const {
return point(x*a, y*a, z*a);
}
point operator /(const float& a)const {
return point(x / a, y / a, z / a);
}
float* toArray() {
float array[] = { x, y, z, 1.0f };
return array;
}
};
// function prototypes
int initWindow(void);
void initOpenGL(void);
void createVAOs(Vertex[], unsigned short[], size_t, size_t, int);
void createObjects(void);
void pickVertex(void);
void moveVertex(void);
void drawScene(void);
void cleanup(void);
static void mouseCallback(GLFWwindow*, int, int, int);
static void keyCallback(GLFWwindow*, int, int, int, int);
// GLOBAL VARIABLES
GLFWwindow* window;
const GLuint window_width = 1024, window_height = 768;
glm::mat4 gProjectionMatrix;
glm::mat4 gViewMatrix;
GLuint gPickedIndex;
std::string gMessage;
GLuint programID;
GLuint pickingProgramID;
GLuint kthLevel = 0;
// ATTN: INCREASE THIS NUMBER AS YOU CREATE NEW OBJECTS
const GLuint NumObjects = 3; // number of different "objects" to be drawn
GLuint VertexArrayId[NumObjects] = { 0, 1, 2 };
GLuint VertexBufferId[NumObjects] = { 0, 1, 2 };
GLuint IndexBufferId[NumObjects] = { 0, 1, 2 };
size_t NumVert[NumObjects] = { 0, 1, 2 };
GLuint MatrixID;
GLuint ViewMatrixID;
GLuint ModelMatrixID;
GLuint PickingMatrixID;
GLuint pickingColorArrayID;
GLuint pickingColorID;
GLuint LightID;
// Define objects
Vertex Vertices[] =
{
{ { 1.0f, 1.0f, 0.0f, 1.0f },{ 0.0f, 0.0f, 0.0f, 1.0f } }, // 0
{ { 0.0f, 1.4f, 0.0f, 1.0f },{ 0.0f, 0.0f, 1.0f, 1.0f } }, // 1
{ { -1.0f, 1.0f, 0.0f, 1.0f },{ 0.0f, 1.0f, 0.0f, 1.0f } }, // 2
{ { -1.4f, 0.0f, 0.0f, 1.0f },{ 0.0f, 1.0f, 1.0f, 1.0f } }, // 3
{ { -1.0f, -1.0f, 0.0f, 1.0f },{ 1.0f, 0.0f, 0.0f, 1.0f } }, // 4
{ { 0.0f, -1.4f, 0.0f, 1.0f },{ 1.0f, 0.0f, 1.0f, 1.0f } },// 5
{ { 1.0f, -1.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 0.0f, 1.0f } }, // 6
{ { 1.4f, 0.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } },// 7
};
Vertex OriginalVertices[] =
{
{ { 1.0f, 1.0f, 0.0f, 1.0f },{ 0.0f, 0.0f, 0.0f, 1.0f } }, // 0
{ { 0.0f, 1.4f, 0.0f, 1.0f },{ 0.0f, 0.0f, 1.0f, 1.0f } }, // 1
{ { -1.0f, 1.0f, 0.0f, 1.0f },{ 0.0f, 1.0f, 0.0f, 1.0f } }, // 2
{ { -1.4f, 0.0f, 0.0f, 1.0f },{ 0.0f, 1.0f, 1.0f, 1.0f } }, // 3
{ { -1.0f, -1.0f, 0.0f, 1.0f },{ 1.0f, 0.0f, 0.0f, 1.0f } }, // 4
{ { 0.0f, -1.4f, 0.0f, 1.0f },{ 1.0f, 0.0f, 1.0f, 1.0f } },// 5
{ { 1.0f, -1.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 0.0f, 1.0f } }, // 6
{ { 1.4f, 0.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } },// 7
};
Vertex LineVertices[] =
{
{ { 1.0f, 1.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } }, // 0
{ { 0.0f, 1.4f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } }, // 1
{ { -1.0f, 1.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } }, // 2
{ { -1.4f, 0.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } }, // 3
{ { -1.0f, -1.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } }, // 4
{ { 0.0f, -1.4f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } },// 5
{ { 1.0f, -1.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } }, // 6
{ { 1.4f, 0.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } },// 7
};
Vertex *kVertices;
Vertex *kPlusOneVertices;
unsigned short *kIndices;
unsigned short *kPlusOneIndices;
//Vertex VTwo[32];
//Vertex VThree[64];
//unsigned short IOne[];
//unsigned short ITwo[];
//unsigned short IThree[];
std::vector<Vertex>TaskTwoVerticesN;
std::vector<unsigned short>TaskTwoIndicesN;
std::vector<Vertex>TaskTwoVerticesNPlusOne;
std::vector<unsigned short>TaskTwoIndicesNPlusOne;
unsigned short Indices[] = {
0, 1, 2, 3, 4, 5, 6, 7
};
unsigned short LineIndices[] = {
0, 1, 2, 3, 4, 5, 6, 7
};
const size_t IndexCount = sizeof(Indices) / sizeof(unsigned short);
// ATTN: DON'T FORGET TO INCREASE THE ARRAY SIZE IN THE PICKING VERTEX SHADER WHEN YOU ADD MORE PICKING COLORS
float pickingColor[IndexCount] = { 0 / 255.0f, 1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f, 5 / 255.0f, 6 / 255.0f, 7 / 255.0f };
// ATTN: ADD YOU PER-OBJECT GLOBAL ARRAY DEFINITIONS HERE
**void createObjects(void)
{
// ATTN: DERIVE YOUR NEW OBJECTS HERE:
// each has one vertices {posCurrent;color} and one indices array (no picking needed here)
if (kthLevel > 4 || kthLevel == 0) {
kthLevel = 0;
TaskTwoVerticesN.clear();
for (int i = 0;i < 8;i++) {
TaskTwoVerticesN.push_back(Vertex());
printf("pushed");
TaskTwoVerticesN[i].XYZW[0] = Vertices[i].XYZW[0];
TaskTwoVerticesN[i].XYZW[1] = Vertices[i].XYZW[1];
TaskTwoVerticesN[i].XYZW[2] = Vertices[i].XYZW[2];
TaskTwoVerticesN[i].XYZW[3] = Vertices[i].XYZW[3];
TaskTwoVerticesN[i].RGBA[0] = Vertices[i].RGBA[0];
TaskTwoVerticesN[i].RGBA[1] = Vertices[i].RGBA[1];
TaskTwoVerticesN[i].RGBA[2] = Vertices[i].RGBA[2];
TaskTwoVerticesN[i].RGBA[3] = Vertices[i].RGBA[3];
}
TaskTwoVerticesN.insert(TaskTwoVerticesN.begin(), Vertices, Vertices + 8);
TaskTwoIndicesN.clear();
TaskTwoIndicesN.insert(TaskTwoIndicesN.begin(), Indices, Indices + (sizeof(Indices) / sizeof(Indices[0])));
printf("\n size of vertices %d\n ", sizeof(TaskTwoVerticesN) / sizeof(TaskTwoVerticesN[0]));
//TaskTwoVerticesNPlusOne = TaskTwoVerticesN;
//TaskTwoIndicesNPlusOne = TaskTwoIndicesN;
kVertices = &TaskTwoVerticesN[0];
kIndices = &TaskTwoIndicesN[0];
//kPlusOneVertices = &TaskTwoVerticesNPlusOne[0];
//kPlusOneIndices = &TaskTwoIndicesNPlusOne[0];
}
else {
GLint numberOfPoints = sizeof(TaskTwoVerticesN) / sizeof(TaskTwoVerticesN[0]);
GLint newPointsLength = (8 * 2 ^ kthLevel);
GLint oldPointsLength = newPointsLength / 2;
printf("\n%d\n", newPointsLength);
Vertex newVertexOne, newVertexTwo;
newVertexOne.RGBA[0] = 0.0f;
newVertexOne.RGBA[1] = 1.0f;
newVertexOne.RGBA[2] = 0.0f;
newVertexOne.RGBA[3] = 1.0f;
newVertexOne.XYZW[2] = 0.0f;
newVertexOne.XYZW[3] = 1.0f;
newVertexTwo = newVertexOne;
for (GLint i = 0; i < oldPointsLength; i++)
{
GLint posMinusTwo = abs(oldPointsLength + i - 2) % oldPointsLength;
GLint posMinusOne = abs(oldPointsLength + i - 1) % oldPointsLength;
GLint posCurrent = abs(i) % oldPointsLength;
GLint posPlusOne = abs(oldPointsLength + i + 1) % oldPointsLength;
GLint newPosOne = abs(2 * i) % newPointsLength;
GLint newPosTwo = abs((2 * i) + 1) % newPointsLength;
float xMinusTwo = TaskTwoVerticesN[posMinusTwo].XYZW[0];
float xMinusOne = TaskTwoVerticesN[posMinusOne].XYZW[0];
float xCurrent = TaskTwoVerticesN[posCurrent].XYZW[0];
float xPlusOne = TaskTwoVerticesN[posPlusOne].XYZW[0];
float yMinusTwo = TaskTwoVerticesN[posMinusTwo].XYZW[1];
float yMinusOne = TaskTwoVerticesN[posMinusOne].XYZW[1];
float yCurrent = TaskTwoVerticesN[posCurrent].XYZW[1];
float yPlusOne = TaskTwoVerticesN[posPlusOne].XYZW[1];
newVertexOne.XYZW[0] = (xMinusTwo + (10 * xMinusOne) + (5 * xCurrent)) / 16;
newVertexOne.XYZW[1] = (yMinusTwo + (10 * yMinusOne) + (5 * yCurrent)) / 16;
TaskTwoVerticesNPlusOne.insert(TaskTwoVerticesNPlusOne.begin() + newPosOne, newVertexOne);
TaskTwoIndicesNPlusOne.insert(TaskTwoIndicesNPlusOne.begin() + newPosOne, newPosOne);
printf("\nIn createObjects");
newVertexTwo.XYZW[0] = (xMinusOne + (10 * xCurrent) + (5 * xPlusOne)) / 16;
newVertexTwo.XYZW[1] = (yMinusOne + (10 * yCurrent) + (5 * yPlusOne)) / 16;
TaskTwoVerticesNPlusOne.insert(TaskTwoVerticesNPlusOne.begin() + newPosTwo, newVertexTwo);
TaskTwoIndicesNPlusOne.insert(TaskTwoIndicesNPlusOne.begin() + newPosTwo, newPosTwo);
}
TaskTwoVerticesN.clear();
TaskTwoVerticesN = TaskTwoVerticesNPlusOne;
TaskTwoIndicesN = TaskTwoIndicesNPlusOne;// is this possible?
//TaskTwoVerticesN.assign(TaskTwoIndicesNPlusOne.begin(), TaskTwoIndicesNPlusOne.end());
kVertices = &TaskTwoVerticesN[0];
kIndices = &TaskTwoIndicesN[0];
kPlusOneVertices = &TaskTwoVerticesNPlusOne[0];
kPlusOneIndices = &TaskTwoIndicesNPlusOne[0];
}
printf("\n%d", kthLevel);
kthLevel++;
}**
void drawScene(void)
{
// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
// Re-clear the screen for real rendering
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID);
{
glm::mat4 ModelMatrix = glm::mat4(1.0); // TranslationMatrix * RotationMatrix;
glm::mat4 MVP = gProjectionMatrix * gViewMatrix * ModelMatrix;
// Send our transformation to the currently bound shader,
// in the "MVP" uniform
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &ModelMatrix[0][0]);
glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &gViewMatrix[0][0]);
glm::vec3 lightPos = glm::vec3(4, 4, 4);
glUniform3f(LightID, lightPos.x, lightPos.y, lightPos.z);
glEnable(GL_PROGRAM_POINT_SIZE);
glBindVertexArray(VertexArrayId[0]); // draw Vertices
glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertices), Vertices); // update buffer data
//glDrawElements(GL_LINE_LOOP, NumVert[0], GL_UNSIGNED_SHORT, (void*)0);
glDrawElements(GL_POINTS, NumVert[0], GL_UNSIGNED_SHORT, (void*)0);
// ATTN: OTHER BINDING AND DRAWING COMMANDS GO HERE, one set per object:
//glBindVertexArray(VertexArrayId[<x>]); etc etc
glBindVertexArray(0);
glBindVertexArray(VertexArrayId[1]); // draw Vertices
glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[1]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(LineVertices), LineVertices); // update buffer data
glDrawElements(GL_LINE_STRIP, NumVert[1], GL_UNSIGNED_SHORT, (void*)0);
glBindVertexArray(1);
glBindVertexArray(VertexArrayId[2]); // draw Vertices
glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[2]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(kPlusOneIndices), kPlusOneVertices); // update buffer data
glDrawElements(GL_LINE_STRIP, NumVert[2], GL_UNSIGNED_SHORT, (void*)0);
glBindVertexArray(2);
}
glUseProgram(0);
// Draw GUI
TwDraw();
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
}
void pickVertex(void)
{
// Clear the screen in white
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(pickingProgramID);
{
glm::mat4 ModelMatrix = glm::mat4(1.0); // TranslationMatrix * RotationMatrix;
glm::mat4 MVP = gProjectionMatrix * gViewMatrix * ModelMatrix;
// Send our transformation to the currently bound shader, in the "MVP" uniform
glUniformMatrix4fv(PickingMatrixID, 1, GL_FALSE, &MVP[0][0]);
glUniform1fv(pickingColorArrayID, NumVert[0], pickingColor); // here we pass in the picking marker array
// Draw the ponts
glEnable(GL_PROGRAM_POINT_SIZE);
glBindVertexArray(VertexArrayId[0]);
glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertices), Vertices); // update buffer data
glDrawElements(GL_POINTS, NumVert[0], GL_UNSIGNED_SHORT, (void*)0);
glBindVertexArray(0);
}
glUseProgram(0);
// Wait until all the pending drawing commands are really done.
// Ultra-mega-over slow !
// There are usually a long time between glDrawElements() and
// all the fragments completely rasterized.
glFlush();
glFinish();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Read the pixel at the center of the screen.
// You can also use glfwGetMousePos().
// Ultra-mega-over slow too, even for 1 pixel,
// because the framebuffer is on the GPU.
double xpos, ypos;
glfwGetCursorPos(window, &xpos, &ypos);
unsigned char data[4];
glReadPixels(xpos, window_height - ypos, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data); // OpenGL renders with (0,0) on bottom, mouse reports with (0,0) on top
// Convert the color back to an integer ID
gPickedIndex = int(data[0]);
// Uncomment these lines to see the picking shader in effect
//glfwSwapBuffers(window);
//continue; // skips the normal rendering
}
// fill this function in!
void moveVertex(void)
{
double xpos, ypos;
glfwGetCursorPos(window, &xpos, &ypos);
unsigned char data[4];
glReadPixels(xpos, 768 - ypos, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data); // OpenGL renders with (0,0) on bottom, mouse reports with (0,0) on top
glm::mat4 ModelMatrix = glm::mat4(1.0);
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
glm::vec4 vp = glm::vec4(viewport[0], viewport[1], viewport[2], viewport[3]);
// retrieve your cursor position
// get your world coordinates
// move points
if (gPickedIndex == 255) { // Full white, must be the background !
gMessage = "background";
}
else {
std::ostringstream oss;
oss << "point " << gPickedIndex;
gMessage = oss.str();
}
if ((glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT)) == GLFW_PRESS) {
printf("\n pressed");
Vertices[gPickedIndex].RGBA[0] = 0.5f;
Vertices[gPickedIndex].RGBA[1] = 0.5f;
Vertices[gPickedIndex].RGBA[2] = 0.5f;
Vertices[gPickedIndex].RGBA[3] = 1.0f;
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
glm::vec3 vertex = glm::unProject(glm::vec3(xpos, 768 - ypos, 0.0), ModelMatrix, gProjectionMatrix, vp);
Vertices[gPickedIndex].XYZW[0] = -vertex[0];
Vertices[gPickedIndex].XYZW[1] = vertex[1];
LineVertices[gPickedIndex].XYZW[0] = -vertex[0];
LineVertices[gPickedIndex].XYZW[1] = vertex[1];
}
else {
printf("released");
Vertices[gPickedIndex].RGBA[0] = OriginalVertices[gPickedIndex].RGBA[0];
Vertices[gPickedIndex].RGBA[1] = OriginalVertices[gPickedIndex].RGBA[1];
Vertices[gPickedIndex].RGBA[2] = OriginalVertices[gPickedIndex].RGBA[2];
Vertices[gPickedIndex].RGBA[3] = OriginalVertices[gPickedIndex].RGBA[3];
}
}
int initWindow(void)
{
// Initialise GLFW
if (!glfwInit()) {
fprintf(stderr, "Failed to initialize GLFW\n");
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
// Open a window and create its OpenGL context
window = glfwCreateWindow(window_width, window_height, "Lastname,FirstName(ufid)", 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");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Initialize GLEW
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
// Initialize the GUI
TwInit(TW_OPENGL_CORE, NULL);
TwWindowSize(window_width, window_height);
TwBar * GUI = TwNewBar("Picking");
TwSetParam(GUI, NULL, "refresh", TW_PARAM_CSTRING, 1, "0.1");
TwAddVarRW(GUI, "Last picked object", TW_TYPE_STDSTRING, &gMessage, NULL);
// Set up inputs
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_FALSE);
glfwSetCursorPos(window, window_width / 2, window_height / 2);
glfwSetMouseButtonCallback(window, mouseCallback);
glfwSetKeyCallback(window, keyCallback);
return 0;
}
void initOpenGL(void)
{
// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
// Enable depth test
glEnable(GL_DEPTH_TEST);
// Accept fragment if it closer to the camera than the former one
glDepthFunc(GL_LESS);
// Cull triangles which normal is not towards the camera
glEnable(GL_CULL_FACE);
// Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
//glm::mat4 ProjectionMatrix = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
// Or, for an ortho camera :
gProjectionMatrix = glm::ortho(-4.0f, 4.0f, -3.0f, 3.0f, 0.0f, 100.0f); // In world coordinates
// Camera matrix
gViewMatrix = glm::lookAt(
glm::vec3(0, 0, -5), // Camera is at (4,3,3), in World Space
glm::vec3(0, 0, 0), // and looks at the origin
glm::vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down)
);
// Create and compile our GLSL program from the shaders
programID = LoadShaders("StandardShading.vertexshader", "StandardShading.fragmentshader");
pickingProgramID = LoadShaders("Picking.vertexshader", "Picking.fragmentshader");
// Get a handle for our "MVP" uniform
MatrixID = glGetUniformLocation(programID, "MVP");
ViewMatrixID = glGetUniformLocation(programID, "V");
ModelMatrixID = glGetUniformLocation(programID, "M");
PickingMatrixID = glGetUniformLocation(pickingProgramID, "MVP");
// Get a handle for our "pickingColorID" uniform
pickingColorArrayID = glGetUniformLocation(pickingProgramID, "PickingColorArray");
pickingColorID = glGetUniformLocation(pickingProgramID, "PickingColor");
// Get a handle for our "LightPosition" uniform
LightID = glGetUniformLocation(programID, "LightPosition_worldspace");
createVAOs(Vertices, Indices, sizeof(Vertices), sizeof(Indices), 0);
createVAOs(LineVertices, LineIndices, sizeof(LineVertices), sizeof(LineIndices), 1);
createVAOs(kPlusOneVertices, kPlusOneIndices, sizeof(kPlusOneVertices), sizeof(kPlusOneIndices), 2);
printf("\nVAO");
createObjects();
// ATTN: create VAOs for each of the newly created objects here:
// createVAOs(<fill this appropriately>);
}
void createVAOs(Vertex Vertices[], unsigned short Indices[], size_t BufferSize, size_t IdxBufferSize, int ObjectId) {
NumVert[ObjectId] = IdxBufferSize / (sizeof GLubyte);
GLenum ErrorCheckValue = glGetError();
size_t VertexSize = sizeof(Vertices[0]);
size_t RgbOffset = sizeof(Vertices[0].XYZW);
// Create Vertex Array Object
glGenVertexArrays(1, &VertexArrayId[ObjectId]);
glBindVertexArray(VertexArrayId[ObjectId]);
// Create Buffer for vertex data
glGenBuffers(1, &VertexBufferId[ObjectId]);
glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[ObjectId]);
glBufferData(GL_ARRAY_BUFFER, BufferSize, Vertices, GL_STATIC_DRAW);
// Create Buffer for indices
glGenBuffers(1, &IndexBufferId[ObjectId]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferId[ObjectId]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, IdxBufferSize, Indices, GL_STATIC_DRAW);
// Assign vertex attributes
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, VertexSize, 0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, VertexSize, (GLvoid*)RgbOffset);
glEnableVertexAttribArray(0); // position
glEnableVertexAttribArray(1); // color
// Disable our Vertex Buffer Object
glBindVertexArray(0);
ErrorCheckValue = glGetError();
if (ErrorCheckValue != GL_NO_ERROR)
{
fprintf(
stderr,
"ERROR: Could not create a VBO: %s \n",
gluErrorString(ErrorCheckValue)
);
}
}
void cleanup(void)
{
// Cleanup VBO and shader
for (int i = 0; i < NumObjects; i++) {
glDeleteBuffers(1, &VertexBufferId[i]);
glDeleteBuffers(1, &IndexBufferId[i]);
glDeleteVertexArrays(1, &VertexArrayId[i]);
}
glDeleteProgram(programID);
glDeleteProgram(pickingProgramID);
// Close OpenGL window and terminate GLFW
glfwTerminate();
}
static void mouseCallback(GLFWwindow* window, int button, int action, int mods)
{
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
pickVertex();
}
}
static void keyCallback(GLFWwindow* window, int button, int scancode, int action, int mods) {
if (button == GLFW_KEY_1 && action == GLFW_PRESS) {
createObjects();
//printf("\n1 pressed");
}
}
int main(void)
{
// initialize window
int errorCode = initWindow();
if (errorCode != 0)
return errorCode;
// initialize OpenGL pipeline
initOpenGL();
// For speed computation
double lastTime = glfwGetTime();
int nbFrames = 0;
do {
// Measure speed
double currentTime = glfwGetTime();
nbFrames++;
if (currentTime - lastTime >= 1.0) { // If last prinf() was more than 1sec ago
// printf and reset
printf("%f ms/frame\n", 1000.0 / double(nbFrames));
nbFrames = 0;
lastTime += 1.0;
}
glfwSetInputMode(window, GLFW_STICKY_MOUSE_BUTTONS, 1);
// DRAGGING: move current (picked) vertex with cursor
if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT))
moveVertex();
// DRAWING SCENE
glfwSetKeyCallback(window, keyCallback);
//createObjects(); // re-evaluate curves in case vertices have been moved
drawScene();
} // Check if the ESC key was pressed or the window was closed
while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0);
cleanup();
return 0;
}
have you tried using arrays like this
bool MAP::InsertVertex(long obj, GLdouble x, GLdouble y, GLdouble z,GLfloat r
,GLfloat g, GLfloat b, GLfloat a,GLfloat nx, GLfloat ny
,GLfloat nz, GLfloat fogdepth)
{
MAP_VERTEX new_vertex;
long rgb = GenerateVertexColor(obj);
if(obj>header.max_objects||obj<0)
return (false);
new_vertex.xyz[0] =x;
new_vertex.xyz[1] =y;
new_vertex.xyz[2] =z;
new_vertex.rgba[0] =r;
new_vertex.rgba[1] =g;
new_vertex.rgba[2] =b;
new_vertex.rgba[3] =a;
new_vertex.normal[0] =nx;
new_vertex.normal[1] =ny;
new_vertex.normal[2] =nz;
new_vertex.fogdepth =fogdepth;
new_vertex.select_rgb[0] = GetRValue(rgb);
new_vertex.select_rgb[1] = GetGValue(rgb);
new_vertex.select_rgb[2] = GetBValue(rgb);
if(object[obj].max_vertices==0) object[obj].vertex = new MAP_VERTEX
[object[obj].max_vertices+1];
else{
//Backing up the vertices that are already there
MAP_VERTEX *temp = new MAP_VERTEX[object[obj].max_vertices+1];
for(long i=0;i<object[obj].max_vertices;i++)
temp[i] = object[obj].vertex[i];
//Deleting the old vertices that were allocated earlier
delete [] object[obj].vertex;
//Now allocating new memory for vertex with an extra buffer
object[obj].vertex = new MAP_VERTEX[object[obj].max_vertices+2];
for(long i=0;i<object[obj].max_vertices;i++)
object[obj].vertex[i] =temp[i];
delete [] temp;
temp = NULL;
}
//Insert a new Vertex
object[obj].vertex[object[obj].max_vertices] = new_vertex;
object[obj].max_vertices++;
return (true);
}
The piece of code you find below draws a cube with a camera inside of it.
I don't understand why when I press escape key or the right, left, up and down arrow keys the program doesn't catch the event.
Inside key_callback I've added std::cout << key << std::endl; expecting to see on the console the identifier of the pressed keys, but everytime I press any keys nothing is printed in the console.
#include <cstdlib>
#include <iostream>
#include <vector>
#include <array>
#include <chrono>
using timer = std::chrono::high_resolution_clock;
#ifdef _WIN32
#include <GL/glew.h>
#else
#define GLFW_INCLUDE_GLCOREARB
#define GL_GLEXT_PROTOTYPES
#endif
#define PI 3.1415926535897932384626433832795f
#include <GLFW/glfw3.h>
#include "lodepng.hpp"
#define GLM_FORCE_RADIANS
#include "glm/glm.hpp"
#include "glm/gtx/norm.hpp"
#include "glm/gtx/rotate_vector.hpp"
#include "glm/gtc/matrix_transform.hpp"
#if defined(_MSC_VER)
#pragma comment(lib,"user32")
#pragma comment(lib,"gdi32")
#pragma comment(lib,"opengl32")
#pragma comment(lib,"glew32")
#pragma comment(lib,"glfw3")
#endif
glm::vec3 camera_position(0.0f, 0.0f, 6.0f);
glm::vec3 camera_direction(0.0f, 0.0f, -1.0f);
glm::vec3 camera_up(0.0f, 1.0f, 0.0f);
using timer = std::chrono::high_resolution_clock;
timer::time_point start_time, last_time;
float t = 0.0;
float dt = 0.0;
bool translate_forward = false;
bool translate_backward = false;
bool translate_right = false;
bool translate_left = false;
bool rotate_up = false;
bool rotate_down = false;
bool rotate_right = false;
bool rotate_left = false;
bool rotate_z_left = false;
bool rotate_z_right = false;
bool sky_on = true;
bool sun_visible = true;
bool earth_visible = true;
bool moon_visible = true;
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
GLuint tex_flag;
static void error_callback(int error, const char* description)
{
std::cerr << description << std::endl;
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
std::cout << key << std::endl;
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
if (key == GLFW_KEY_UP)
{
if (action)
rotate_up = true;
else
rotate_up = false;
}
if (key == GLFW_KEY_DOWN)
{
if (action)
rotate_down = true;
else
rotate_down = false;
}
if (key == GLFW_KEY_RIGHT)
{
if (action)
rotate_right = true;
else
rotate_right = false;
}
if (key == GLFW_KEY_LEFT)
{
if (action)
rotate_left = true;
else
rotate_left = false;
}
}
// Shader sources
const GLchar* vertexSource =
#if defined(__APPLE_CC__)
"#version 150 core\n"
#else
"#version 130\n"
#endif
"in vec3 position;"
"in vec3 color;"
"in vec2 coord;"
"out vec3 Color;"
"out vec2 Coord;"
"uniform mat4 model;"
"uniform mat4 view;"
"uniform mat4 projection;"
"void main() {"
" Color = color;"
" Coord = coord;"
" gl_Position = projection * view * model * vec4(position, 1.0);"
"}";
const GLchar* fragmentSource =
#if defined(__APPLE_CC__)
"#version 150 core\n"
#else
"#version 130\n"
#endif
"in vec3 Color;"
"in vec2 Coord;"
"out vec4 outColor;"
"uniform sampler2D textureSampler;"
"void main() {"
" outColor = vec4(Color, 1.0)*texture(textureSampler, Coord);"
"}";
const GLfloat vertices[] = {
// Position Color Texcoords
-0.5f, 0.5f, -0.5f, 0.15f, 0.33f, 0.55f, .25f, 0.0f, // 0
0.5f, 0.5f, -0.5f, 0.15f, 0.33f, 0.55f, 0.5f, 0.0f, // 1
-0.5f, 0.5f, -0.5f, 0.15f, 0.33f, 0.55f, 0.0f, 1.f / 3.f, // 2
-0.5f, 0.5f, 0.5f, 0.15f, 0.33f, 0.55f, .25f, 1.f / 3.f, // 3
0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.5f, 1.f / 3.f, // 4
0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, .75f, 1.f / 3.f, // 5
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.f / 3.f, // 6
-0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 2.f / 3.f, // 7
-0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, .25f, 2.f / 3.f, // 8
0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.5f, 2.f / 3.f, // 9
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, .75f, 2.f / 3.f, // 10
-0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 2.f / 3.f, // 11
-0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, .25f, 1.0f, // 12
0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.5f, 1.0f, // 13
};
const GLuint elements[] = {
0, 3, 4, 0, 4, 1,
2, 7, 8, 2, 8, 3,
3, 8, 9, 3, 9, 4,
4, 9,10, 4,10, 5,
5,10,11, 5,11, 6,
8,12,13, 8,13, 9
};
GLuint vao;
GLuint vbo;
GLuint ibo;
GLuint shaderProgram;
GLuint textures[1];
float t = 0;
void check(int line)
{
GLenum error = glGetError();
while (error != GL_NO_ERROR)
{
switch (error)
{
case GL_INVALID_ENUM: std::cout << "GL_INVALID_ENUM : " << line << std::endl; break;
case GL_INVALID_VALUE: std::cout << "GL_INVALID_VALUE : " << line << std::endl; break;
case GL_INVALID_OPERATION: std::cout << "GL_INVALID_OPERATION : " << line << std::endl; break;
case GL_OUT_OF_MEMORY: std::cout << "GL_OUT_OF_MEMORY : " << line << std::endl; break;
default: std::cout << "Unrecognized error : " << line << std::endl; break;
}
error = glGetError();
}
}
void initialize_shader()
{
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
void destroy_shader()
{
glDeleteProgram(shaderProgram);
}
void initialize_vao()
{
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
// shaderProgram must be already initialized
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), 0);
GLint colAttrib = glGetAttribLocation(shaderProgram, "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
GLint cooAttrib = glGetAttribLocation(shaderProgram, "coord");
glEnableVertexAttribArray(cooAttrib);
glVertexAttribPointer(cooAttrib, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(6 * sizeof(GLfloat)));
}
void destroy_vao()
{
glDeleteBuffers(1, &ibo);
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
}
void initialize_texture()
{
glGenTextures(1, &textures[0]);
std::vector<unsigned char> image;
unsigned width, height;
unsigned error = lodepng::decode(image, width, height, "cube3.png");
if (error) std::cout << "decode error " << error << ": " << lodepng_error_text(error) << std::endl;
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.data());
// shaderProgram must be already initialized
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
void destroy_texture()
{
glDeleteTextures(1, &textures[0]);
}
void update_camera()
{
glm::vec3 right = glm::cross(camera_direction, camera_up);
glm::vec3 left = glm::cross(right, camera_up);
if (translate_forward)
{
camera_position += camera_direction*dt;
}
if (translate_backward)
{
camera_position -= camera_direction*dt;
}
if (translate_right)
{
camera_position += right * dt;
}
if (translate_left)
{
camera_position -= right * dt;
}
if (rotate_up)
{
camera_direction = glm::rotate(camera_direction, dt, right);
camera_up = glm::rotate(camera_up, dt, right);
}
if (rotate_down)
{
camera_direction = glm::rotate(camera_direction, -dt, right);
camera_up = glm::rotate(camera_up, -dt, right);
}
if (rotate_right)
{
camera_direction = glm::rotate(camera_direction, -dt, camera_up);
}
if (rotate_left)
{
camera_direction = glm::rotate(camera_direction, dt, camera_up);
}
if (rotate_z_left)
{
camera_direction = glm::rotate(camera_direction, dt, left);
camera_up = glm::rotate(camera_up, dt, left);
}
if (rotate_z_right)
{
camera_direction = glm::rotate(camera_direction, -dt, left);
camera_up = glm::rotate(camera_up, -dt, left);
}
}
void draw(GLFWwindow* window)
{
t = (timer::now() - start_time).count() * (float(timer::period::num) / float(timer::period::den));
dt = (timer::now() - last_time).count() * (float(timer::period::num) / float(timer::period::den));
update_camera();
last_time = timer::now();
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 projection = glm::perspective(PI / 4, 1.f / 1.f, 1.0f, 10.0f);
glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 0.0f, -1.3f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 model = glm::rotate(glm::mat4(1.f), PI, glm::vec3(0.0f, 1.0f, 0.0f));
glUseProgram(shaderProgram);
glUniform1i(glGetUniformLocation(shaderProgram, "textureSampler"), tex_flag);
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, &projection[0][0]);
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "view"), 1, GL_FALSE, &view[0][0]);
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, &model[0][0]);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, 6 * 2 * 3, GL_UNSIGNED_INT, 0); // facce * triangoli per faccia * vertici per triangolo
}
int main(int argc, char const *argv[])
{
GLFWwindow *window;
glfwSetErrorCallback(error_callback);
tex_flag = 0;
if (!glfwInit())
return EXIT_FAILURE;
#if defined(__APPLE_CC__)
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#else
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
#endif
window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Project", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
#if defined(_MSC_VER)
glewExperimental = true;
if (glewInit() != GL_NO_ERROR)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
#endif
glfwSetKeyCallback(window, key_callback);
initialize_shader(); check(__LINE__);
initialize_vao(); check(__LINE__);
initialize_texture(); check(__LINE__);
//start = timer::now();
glEnable(GL_DEPTH_TEST); check(__LINE__);
while (!glfwWindowShouldClose(window))
{
draw(window); check(__LINE__);
glfwSwapBuffers(window);
glfwPollEvents();
}
destroy_vao(); check(__LINE__);
destroy_shader(); check(__LINE__);
destroy_texture(); check(__LINE__);
glfwDestroyWindow(window);
glfwTerminate();
return EXIT_SUCCESS;
}
First order of business when hunting down problems like yours it to minimize the surface area and reduce the program as far as possible yet retaining the problematic behaviour. Your code snippet does not constitute a Minimal Complete Verifyable Example (MCVE). I stripped it down to a MCVE:
#include <cstdlib>
#include <iostream>
#include <GLFW/glfw3.h>
static void error_callback(int error, const char* description)
{
std::cerr << description << std::endl;
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
std::cout << key << std::endl;
}
int main(int argc, char const *argv[])
{
GLFWwindow *window;
glfwSetErrorCallback( error_callback );
if (!glfwInit())
return EXIT_FAILURE;
window = glfwCreateWindow(100, 100, "Project", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwSetKeyCallback(window, key_callback);
while (!glfwWindowShouldClose(window))
{
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
return EXIT_SUCCESS;
}
Given this minimal example I am unable to reproduce your particular problem; i.e. I am getting key events out of this.
That can mean two things: Either the problem resides somewhere else in your code, or it is something about your particular system and development environment. This is why MCVEs are so important (especially the minimal part); it's the only way to pinpoint the actual culprit.
So here's my suggestion: Try the minimal code I put up and see if it still does not report key events. If so, then it's a problem with your system and not with the code. Otherwise you can re-add layers of functionality piece by piece until it breaks.