In this simple program, the cube is drawn, but I’m unable to move it with the mouse. I tried and tried to fix it without success. It might be a very simple issue. Can you help me, please?
/**
* animator.cpp
*/
#include <iostream>
#include "animator.h"
namespace belem
{
Animator::Animator() :
mAnimation(NONE),
mInteractor(0),
mFrame(0),
mFrames(0),
mFramesPerSecond(30.),
mHeight(0),
mTic(std::chrono::system_clock::now()),
mWidth(0)
{
stopwatch();
}
Animator::~Animator()
{
}
void Animator::animate()
{
if (elapsedSeconds() < 1.0 / mFramesPerSecond) {
return;
}
switch(mAnimation) {
case FIRST_PERSON:
firstperson();
break;
case ORBIT:
orbit();
break;
case PAN:
pan();
break;
case ROLL:
roll();
break;
case ZOOM:
zoom();
break;
case NONE: default:
return;
break;
}
stopwatch();
}
double Animator::elapsedSeconds()
{
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
std::chrono::duration<double> seconds = now - mTic;
return seconds.count();
}
void Animator::firstperson()
{
}
void Animator::orbit()
{
Camera *c = mInteractor->getCamera();
if (0 == mFrame) {
mFrames = 5 * mFramesPerSecond;
c->setEye(1., 1., 1.);
c->setUp(-0., -0., 1.);
c->setCenter(0, 0, 0);
c->update();
mInteractor->setCamera(c);
}
double x = fmod(mFrame*4, mWidth);
double y = mHeight * .74;
mInteractor->setLeftClicked(true);
mInteractor->setClickPoint(x, y);
if (++mFrame >= mFrames) {
mInteractor->setLeftClicked(false);
reset();
}
}
void Animator::pan()
{
}
void Animator::reset()
{
mAnimation = NONE;
mFrame = 0;
}
void Animator::roll()
{
}
void Animator::setAnimation(AnimationType type)
{
mAnimation = type;
}
void Animator::setInteractor(TrackBallInteractor *i)
{
mInteractor = i;
}
void Animator::setScreenSize(int w, int h)
{
mWidth = w;
mHeight = h;
}
void Animator::stopwatch()
{
mTic = std::chrono::system_clock::now();
}
void Animator::zoom()
{
}
}
/**
* camera.cpp
*/
#include <camera.h>
#include <iostream>
#define GLM_FORCE_RADIANS
#include <glm/gtc/matrix_transform.hpp> // lookAt
#include <glm/gtc/type_ptr.hpp> // value_ptr
namespace belem
{
Camera::Camera()
{
reset();
}
Camera::~Camera()
{
}
const glm::vec3 & Camera::getCenter()
{
return mCenter;
}
const glm::vec3 & Camera::getEye()
{
return mEye;
}
const glm::mat4 & Camera::getMatrix()
{
return mMatrix;
}
const float* Camera::getMatrixFlat()
{
return glm::value_ptr(mMatrix);
}
const glm::vec3 & Camera::getUp()
{
return mUp;
}
void Camera::reset()
{
mEye.x = 0.f;
mEye.y = 0.f;
mEye.z = 1.f;
mCenter.x = 0.f;
mCenter.y = 0.f;
mCenter.z = 0.f;
mUp.x = 0.f;
mUp.y = 1.f;
mUp.z = 0.f;
update();
}
void Camera::setEye(float x, float y, float z)
{
mEye.x = x;
mEye.y = y;
mEye.z = z;
}
void Camera::setEye(const glm::vec3 & e)
{
mEye = e;
}
void Camera::setCenter(float x, float y, float z)
{
mCenter.x = x;
mCenter.y = y;
mCenter.z = z;
}
void Camera::setCenter(const glm::vec3 & c)
{
mCenter = c;
}
void Camera::setUp(float x, float y, float z)
{
mUp.x = x;
mUp.y = y;
mUp.z = z;
}
void Camera::setUp(const glm::vec3 & u)
{
mUp = u;
}
void Camera::update()
{
mMatrix = glm::lookAt(mEye, mCenter, mUp);
}
} // end namespace belem
/**
* renderer.cpp
*/
#include <renderer.h>
namespace belem
{
Renderer::Renderer() : mCamera(0)
{
}
Renderer::~Renderer()
{
}
const Camera* Renderer::getCamera()
{
return mCamera;
}
void Renderer::setCamera(Camera *c)
{
mCamera = c;
}
} // end namespace belem
/**
* trackball.cpp
*/
#include <glm/gtx/norm.hpp> // length2
#include <glm/vec3.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/constants.hpp> // pi
#include <trackball.h>
#include <iostream>
namespace belem
{
const glm::vec3 TrackBallInteractor::X(1.f, 0.f, 0.f);
const glm::vec3 TrackBallInteractor::Y(0.f, 1.f, 0.f);
const glm::vec3 TrackBallInteractor::Z(0.f, 0.f, 1.f);
TrackBallInteractor::TrackBallInteractor()
: mCamera(nullptr),
mCameraMotionLeftClick(ARC),
mCameraMotionMiddleClick(ROLL),
mCameraMotionRightClick(FIRSTPERSON),
mCameraMotionScroll(ZOOM),
mClickPoint(),
mHeight(1),
mIsDragging(false),
mIsLeftClick(false),
mIsMiddleClick(false),
mIsRightClick(false),
mIsScrolling(false),
mPanScale(0.005f),
mPrevClickPoint(),
mRollScale(0.005f),
mRollSum(0.0f),
mRotation(1.0f, 0.0f, 0.0f, 0.0f),
mRotationSum(1.0f, 0.0f, 0.0f, 0.0f),
mSpeed(1.0f),
mStartVector(),
mStopVector(),
mTranslateLength(0.0f),
mWidth(1),
mZoomSum(0.0f),
mZoomScale(0.1f) // mZoomScale initialized last to avoid warning
{
}
TrackBallInteractor::~TrackBallInteractor()
{
}
char TrackBallInteractor::clickQuadrant(float x, float y)
{
float halfw = .5 * mWidth;
float halfh = .5 * mHeight;
if (x > halfw) {
// Opengl image coordinates origin is upperleft.
if (y < halfh) {
return 1;
} else {
return 4;
}
} else {
if (y < halfh) {
return 2;
} else {
return 3;
}
}
}
void TrackBallInteractor::computeCameraEye(glm::vec3 & eye)
{
glm::vec3 orientation = mRotationSum * Z;
if (mZoomSum) {
mTranslateLength += mZoomScale * mZoomSum;
mZoomSum = 0; // Freeze zooming after applying.
}
eye = mTranslateLength * orientation + mCamera->getCenter();
}
void TrackBallInteractor::computeCameraUp(glm::vec3 & up)
{
up = glm::normalize(mRotationSum * Y);
}
void TrackBallInteractor::computePan(glm::vec3 & pan)
{
glm::vec2 click = mClickPoint - mPrevClickPoint;
glm::vec3 look = mCamera->getEye() - mCamera->getCenter();
float length = glm::length(look);
glm::vec3 right = glm::normalize(mRotationSum * X);
pan = (mCamera->getUp() * -click.y + right * click.x) *
mPanScale * mSpeed * length;
}
void TrackBallInteractor::computePointOnSphere(
const glm::vec2 & point, glm::vec3 & result)
{
// https://www.opengl.org/wiki/Object_Mouse_Trackball
float x = (2.f * point.x - mWidth) / mWidth;
float y = (mHeight - 2.f * point.y) / mHeight;
float length2 = x*x + y*y;
if (length2 <= .5) {
result.z = sqrt(1.0 - length2);
} else {
result.z = 0.5 / sqrt(length2);
}
float norm = 1.0 / sqrt(length2 + result.z*result.z);
result.x = x * norm;
result.y = y * norm;
result.z *= norm;
}
void TrackBallInteractor::computeRotationBetweenVectors(
const glm::vec3 & u, const glm::vec3 & v, glm::quat & result)
{
float cosTheta = glm::dot(u, v);
glm::vec3 rotationAxis;
static const float EPSILON = 1.0e-5f;
if (cosTheta < -1.0f + EPSILON){
// Parallel and opposite directions.
rotationAxis = glm::cross(glm::vec3(0.f, 0.f, 1.f), u);
if (glm::length2(rotationAxis) < 0.01 ) {
// Still parallel, retry.
rotationAxis = glm::cross(glm::vec3(1.f, 0.f, 0.f), u);
}
rotationAxis = glm::normalize(rotationAxis);
result = glm::angleAxis(180.0f, rotationAxis);
} else if (cosTheta > 1.0f - EPSILON) {
// Parallel and same direction.
result = glm::quat(1, 0, 0, 0);
return;
} else {
float theta = acos(cosTheta);
rotationAxis = glm::cross(u, v);
rotationAxis = glm::normalize(rotationAxis);
result = glm::angleAxis(theta * mSpeed, rotationAxis);
}
}
void TrackBallInteractor::drag()
{
if (mPrevClickPoint == mClickPoint) {
// Not moving during drag state, so skip unnecessary processing.
return;
}
computePointOnSphere(mClickPoint, mStopVector);
computeRotationBetweenVectors(mStartVector,
mStopVector,
mRotation);
// Reverse so scene moves with cursor and not away due to camera model.
mRotation = glm::inverse(mRotation);
drag(mIsLeftClick, mCameraMotionLeftClick);
drag(mIsMiddleClick, mCameraMotionMiddleClick);
drag(mIsRightClick, mCameraMotionRightClick);
// After applying drag, reset relative start state.
mPrevClickPoint = mClickPoint;
mStartVector = mStopVector;
}
void TrackBallInteractor::drag(bool isClicked, CameraMotionType motion)
{
if (!isClicked) {
return;
}
switch(motion) {
case ARC:
dragArc();
break;
case FIRSTPERSON:
dragFirstPerson();
break;
case PAN:
dragPan();
break;
case ROLL:
rollCamera();
break;
case ZOOM:
dragZoom();
break;
default: break;
}
}
void TrackBallInteractor::dragArc()
{
mRotationSum *= mRotation; // Accumulate quaternions.
updateCameraEyeUp(true, true);
}
void TrackBallInteractor::dragFirstPerson()
{
glm::vec3 pan;
computePan(pan);
mCamera->setCenter(pan + mCamera->getCenter());
mCamera->update();
freezeTransform();
}
void TrackBallInteractor::dragPan()
{
glm::vec3 pan;
computePan(pan);
mCamera->setCenter(pan + mCamera->getCenter());
mCamera->setEye(pan + mCamera->getEye());
mCamera->update();
freezeTransform();
}
void TrackBallInteractor::dragZoom()
{
glm::vec2 dir = mClickPoint - mPrevClickPoint;
float ax = fabs(dir.x);
float ay = fabs(dir.y);
if (ay >= ax) {
setScrollDirection(dir.y <= 0);
} else {
setScrollDirection(dir.x <= 0);
}
updateCameraEyeUp(true, false);
}
void TrackBallInteractor::freezeTransform()
{
if (mCamera) {
// Opengl is ZYX order.
// Flip orientation to rotate scene with sticky cursor.
mRotationSum = glm::inverse(glm::quat(mCamera->getMatrix()));
mTranslateLength = glm::length(mCamera->getEye()-mCamera->getCenter());
}
}
Camera* TrackBallInteractor::getCamera()
{
return mCamera;
}
TrackBallInteractor::CameraMotionType TrackBallInteractor::getMotionLeftClick()
{
return mCameraMotionLeftClick;
}
TrackBallInteractor::CameraMotionType TrackBallInteractor::getMotionMiddleClick()
{
return mCameraMotionMiddleClick;
}
TrackBallInteractor::CameraMotionType TrackBallInteractor::getMotionRightClick()
{
return mCameraMotionRightClick;
}
TrackBallInteractor::CameraMotionType TrackBallInteractor::getMotionScroll()
{
return mCameraMotionScroll;
}
void TrackBallInteractor::rollCamera()
{
glm::vec2 delta = mClickPoint - mPrevClickPoint;
char quad = clickQuadrant(mClickPoint.x, mClickPoint.y);
switch (quad) {
case 1:
delta.y = -delta.y;
delta.x = -delta.x;
break;
case 2:
delta.x = -delta.x;
break;
case 3:
break;
case 4:
delta.y = -delta.y;
default:
break;
}
glm::vec3 axis = glm::normalize(mCamera->getCenter() - mCamera->getEye());
float angle = mRollScale * mSpeed * (delta.x + delta.y + mRollSum);
glm::quat rot = glm::angleAxis(angle, axis);
mCamera->setUp(rot * mCamera->getUp());
mCamera->update();
freezeTransform();
mRollSum = 0;
}
void TrackBallInteractor::scroll()
{
switch(mCameraMotionScroll) {
case ROLL:
rollCamera();
break;
case ZOOM:
updateCameraEyeUp(true, false);
break;
default: break;
}
}
void TrackBallInteractor::setCamera(Camera *c)
{
mCamera = c;
freezeTransform();
}
void TrackBallInteractor::setClickPoint(double x, double y)
{
mPrevClickPoint = mClickPoint;
mClickPoint.x = x;
mClickPoint.y = y;
}
void TrackBallInteractor::setLeftClicked(bool value)
{
mIsLeftClick = value;
}
void TrackBallInteractor::setMiddleClicked(bool value)
{
mIsMiddleClick = value;
}
void TrackBallInteractor::setMotionLeftClick(CameraMotionType motion)
{
mCameraMotionLeftClick = motion;
}
void TrackBallInteractor::setMotionMiddleClick(CameraMotionType motion)
{
mCameraMotionMiddleClick = motion;
}
void TrackBallInteractor::setMotionRightClick(CameraMotionType motion)
{
mCameraMotionRightClick = motion;
}
void TrackBallInteractor::setMotionScroll(CameraMotionType motion)
{
mCameraMotionScroll = motion;
}
void TrackBallInteractor::setRightClicked(bool value)
{
mIsRightClick = value;
}
void TrackBallInteractor::setScreenSize(float width, float height)
{
if (width > 1 && height > 1) {
mWidth = width;
mHeight = height;
}
}
void TrackBallInteractor::setScrollDirection(bool up)
{
mIsScrolling = true;
float inc = mSpeed * (up ? -1.f : 1.f);
mZoomSum += inc;
mRollSum += inc;
}
void TrackBallInteractor::setSpeed(float s)
{
mSpeed = s;
}
void TrackBallInteractor::update()
{
const bool isClick = mIsLeftClick || mIsMiddleClick || mIsRightClick;
if (! mIsDragging)
{
if (isClick)
{
mIsDragging = true;
computePointOnSphere(mClickPoint, mStartVector);
} else if (mIsScrolling) {
scroll();
mIsScrolling = false;
}
}
else
{
if (isClick)
{
drag();
} else
{
mIsDragging = false;
}
}
}
void TrackBallInteractor::updateCameraEyeUp(bool eye, bool up)
{
if (eye) {
glm::vec3 eye;
computeCameraEye(eye);
mCamera->setEye(eye);
}
if (up) {
glm::vec3 up;
computeCameraUp(up);
mCamera->setUp(up);
}
mCamera->update();
}
} // end namespace belem
/**
* window.cpp
*/
#include "window.h"
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
#include <glm/glm.hpp>
#include <iostream>
namespace belem
{
static const char* HELP =
" c: Print camera Eye, Center, Up\n"
" r: Reset view\n"
" t: Toggle right button to do Pan or First-Person\n"
" x, y, z: Snap camera to axis\n"
" Hold Ctrl: Increase speed\n"
" Hold Shift: Reduce speed\n"
" Left-Click: Rotate\n"
"Middle-Click: Pan or First-Person\n"
" Right-Click: Roll\n"
"Scroll-Wheel: Dolly (zoom)\n";
Window::Window() : mWindow(0)
{
}
Window::~Window()
{
}
void Window::buttonCallback(GLFWwindow *window, int button,
int action, int mods)
{
switch(action)
{
case GLFW_PRESS:
{
switch(button)
{
case GLFW_MOUSE_BUTTON_LEFT:
instance().mInteractor.setLeftClicked(true);
break;
case GLFW_MOUSE_BUTTON_MIDDLE:
instance().mInteractor.setMiddleClicked(true);
break;
case GLFW_MOUSE_BUTTON_RIGHT:
instance().mInteractor.setRightClicked(true);
break;
}
double xpos, ypos;
glfwGetCursorPos(window, & xpos, & ypos);
instance().mInteractor.setClickPoint(xpos, ypos);
break;
}
case GLFW_RELEASE:
{
switch(button)
{
case GLFW_MOUSE_BUTTON_LEFT:
instance().mInteractor.setLeftClicked(false);
break;
case GLFW_MOUSE_BUTTON_MIDDLE:
instance().mInteractor.setMiddleClicked(false);
break;
case GLFW_MOUSE_BUTTON_RIGHT:
instance().mInteractor.setRightClicked(false);
break;
}
break;
}
default: break;
}
}
void Window::errorCallback(int error, const char* description)
{
std::cerr << description << std::endl;
}
Window & Window::instance()
{
static Window i;
return i;
}
void Window::keyCallback(GLFWwindow *window, int key, int scancode,
int action, int mods)
{
float length;
switch(action) {
case GLFW_PRESS:
switch(key)
{
case GLFW_KEY_ESCAPE:
// Exit app on ESC key.
glfwSetWindowShouldClose(window, GL_TRUE);
break;
case GLFW_KEY_LEFT_CONTROL:
case GLFW_KEY_RIGHT_CONTROL:
instance().mInteractor.setSpeed(5.f);
break;
case GLFW_KEY_LEFT_SHIFT:
case GLFW_KEY_RIGHT_SHIFT:
instance().mInteractor.setSpeed(.1f);
break;
case GLFW_KEY_F1:
instance().mAnimator.setAnimation(Animator::ORBIT);
break;
case GLFW_KEY_C:
std::cout
<< "(" << instance().mCamera.getEye().x
<< "," << instance().mCamera.getEye().y
<< "," << instance().mCamera.getEye().z << ") "
<< "(" << instance().mCamera.getCenter().x
<< "," << instance().mCamera.getCenter().y
<< "," << instance().mCamera.getCenter().z << ") "
<< "(" << instance().mCamera.getUp().x
<< "," << instance().mCamera.getUp().y
<< "," << instance().mCamera.getUp().z << ")\n";
fflush(stdout);
break;
case GLFW_KEY_R:
// Reset the view.
instance().mCamera.reset();
instance().mInteractor.setCamera(& instance().mCamera);
break;
case GLFW_KEY_T:
// Toogle motion type.
if (instance().mInteractor.getMotionRightClick() ==
TrackBallInteractor::FIRSTPERSON) {
instance().mInteractor.setMotionRightClick(
TrackBallInteractor::PAN);
} else {
instance().mInteractor.setMotionRightClick(
TrackBallInteractor::FIRSTPERSON);
}
break;
case GLFW_KEY_X:
// Snap view to axis.
length = glm::length(instance().mCamera.getEye() -
instance().mCamera.getCenter());
instance().mCamera.setEye(length,0,0);
instance().mCamera.setUp(0,1,0);
instance().mCamera.update();
instance().mInteractor.setCamera(& instance().mCamera);
break;
case GLFW_KEY_Y:
length = glm::length(instance().mCamera.getEye() -
instance().mCamera.getCenter());
instance().mCamera.setEye(0,length,0);
instance().mCamera.setUp(1,0,0);
instance().mCamera.update();
instance().mInteractor.setCamera(& instance().mCamera);
break;
case GLFW_KEY_Z:
length = glm::length(instance().mCamera.getEye() -
instance().mCamera.getCenter());
instance().mCamera.setEye(0,0,length);
instance().mCamera.setUp(1,0,0);
instance().mCamera.update();
instance().mInteractor.setCamera(& instance().mCamera);
break;
default: break;
}
break;
case GLFW_RELEASE:
switch(key)
{
case GLFW_KEY_LEFT_CONTROL:
case GLFW_KEY_RIGHT_CONTROL:
case GLFW_KEY_LEFT_SHIFT:
case GLFW_KEY_RIGHT_SHIFT:
instance().mInteractor.setSpeed(1.f);
break;
}
break;
default: break;
}
}
void Window::moveCallback(GLFWwindow *window, double xpos, double ypos)
{
instance().mInteractor.setClickPoint(xpos, ypos);
}
void Window::scrollCallback(GLFWwindow *window, double xpos, double ypos)
{
instance().mInteractor.setScrollDirection(xpos + ypos > 0 ? true : false);
}
void Window::sizeCallback(GLFWwindow *window, int width, int height)
{
instance().mRenderer.resize(width, height);
instance().mInteractor.setScreenSize(width, height);
instance().mAnimator.setScreenSize(width, height);
}
int Window::run(int width, int height)
{
int exitcode = EXIT_SUCCESS;
glfwSetErrorCallback(& Window::errorCallback);
if (!glfwInit())
{
exitcode = EXIT_FAILURE;
goto recover;
}
mWindow = glfwCreateWindow(width, height, "Belém", NULL, NULL);
if (!mWindow)
{
glfwTerminate();
exitcode = EXIT_FAILURE;
goto recover;
}
std::cout << HELP;
glfwMakeContextCurrent(mWindow);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
// Handle GLAD initialization error
glfwTerminate();
return -1;
}
// OpenGL is now ready to use
mRenderer.init();
glfwSwapInterval(1);
glfwSetCursorPosCallback(mWindow, & Window::moveCallback);
glfwSetKeyCallback(mWindow, & Window::keyCallback);
glfwSetMouseButtonCallback(mWindow, & Window::buttonCallback);
glfwSetScrollCallback(mWindow, & Window::scrollCallback);
glfwSetWindowSizeCallback(mWindow, &Window::sizeCallback);
mInteractor.setCamera(& mCamera);
mRenderer.setCamera(& mCamera);
mAnimator.setInteractor(& mInteractor);
mRenderer.init();
sizeCallback(mWindow, width, height); // Set initial size.
while (!glfwWindowShouldClose(mWindow))
{
mAnimator.animate();
mInteractor.update();
mRenderer.render();
glfwSwapBuffers(mWindow);
glfwPollEvents();
}
glfwDestroyWindow(mWindow);
glfwTerminate();
recover:
return exitcode;
}
} // end namespace belem
/**
* cube.cpp
*/
#include <iostream>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "world.h"
#include "camera.h"
#include "window.h"
namespace belem
{
const char* vertexShaderSource = R"(
#version 460 core
layout (location = 0) in vec3 aPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
}
)";
const char* fragmentShaderSource = R"(
#version 460 core
out vec4 FragColor;
void main()
{
// Orange color with alpha = 0.9
FragColor = vec4(1.0, 0.5, 0.2, 0.9);
}
)";
void World::prepareCube()
{
// Build and compile shader program
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// Set up vertex data and buffers
float vertices[] = {
0.5f, 0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f
};
unsigned int indices[] = {
0, 1, 3,
1, 2, 3,
4, 5, 7,
5, 6, 7,
0, 1, 5,
0, 5, 4,
2, 3, 7,
2, 7, 6,
0, 3, 7,
0, 7, 4,
1, 2, 6,
1, 6, 5
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
}
void World::renderCube()
{
// Set OpenGL state
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND); // Enable blending for transparency
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Set blending function
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Activate shader
glUseProgram(shaderProgram);
// Set transformation matrices
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = Window::instance().getCamera().getMatrix();
glm::mat4 projection = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f);
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "view"), 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
// Draw the cube
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
}
}