Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 157 additions & 44 deletions [GETTING STARTED]/[6] Camera/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
#include <GL/glew.h>

// GLFW
#include <GLFW/glfw3.h>
//#include <GLFW/glfw3.h>
// SDL2
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>

// GL includes
#include "Shader.h"
Expand All @@ -18,67 +21,97 @@
#include <glm/gtc/type_ptr.hpp>

// Other Libs
#include "SOIL2/SOIL2.h"
//#include "SOIL2/SOIL2.h"

// Properties
const GLuint WIDTH = 800, HEIGHT = 600;
int SCREEN_WIDTH, SCREEN_HEIGHT;

// Function prototypes
void KeyCallback( GLFWwindow *window, int key, int scancode, int action, int mode );
void ScrollCallback( GLFWwindow *window, double xOffset, double yOffset );
void MouseCallback( GLFWwindow *window, double xPos, double yPos );
//void KeyCallback( GLFWwindow *window, int key, int scancode, int action, int mode );
//void ScrollCallback( GLFWwindow *window, double xOffset, double yOffset );
//void MouseCallback( GLFWwindow *window, double xPos, double yPos );
void DoMovement( );

// Camera
Camera camera(glm::vec3( 0.0f, 0.0f, 3.0f ) );
GLfloat lastX = WIDTH / 2.0;
GLfloat lastY = HEIGHT / 2.0;
bool keys[1024];
//bool keys[1024];
const Uint8 * keys;
bool firstMouse = true;

GLfloat deltaTime = 0.0f;
GLfloat lastFrame = 0.0f;

// The MAIN function, from here we start our application and run our Game loop
int main( )
//int main( )
int main(int argc, char ** argv) // SDL needs this form
{
// Init GLFW
glfwInit( );
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
glfwWindowHint( GLFW_RESIZABLE, GL_FALSE );
glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE );
//glfwInit( );
SDL_Init(SDL_INIT_EVERYTHING);
// Init SDL_image with JPG and PNG
IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG);
//glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
//glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
//glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
//glfwWindowHint( GLFW_RESIZABLE, GL_FALSE );
//glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE );
// Enable doublebuffering
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

GLFWwindow* window = glfwCreateWindow( WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr ); // Windowed
//GLFWwindow* window = glfwCreateWindow( WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr ); // Windowed
SDL_Window * window = SDL_CreateWindow("LearnOpenGL",SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, SDL_WINDOW_OPENGL);

if ( nullptr == window )
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate( );
//std::cout << "Failed to create GLFW window" << std::endl;
std::cerr << "Failed to create SDL window" << std::endl;
//glfwTerminate( );
IMG_Quit();
SDL_Quit();

return EXIT_FAILURE;
}

glfwMakeContextCurrent( window );
//glfwMakeContextCurrent( window );
SDL_GLContext context = SDL_GL_CreateContext(window);
if ( nullptr == context )
{
std::cerr << "Failed to create SDL context" << std::endl;
//glfwTerminate( );
SDL_DestroyWindow(window);
IMG_Quit();
SDL_Quit();

return EXIT_FAILURE;
}

glfwGetFramebufferSize( window, &SCREEN_WIDTH, &SCREEN_HEIGHT );
//glfwGetFramebufferSize( window, &SCREEN_WIDTH, &SCREEN_HEIGHT );
SDL_GL_GetDrawableSize(window, &SCREEN_WIDTH, &SCREEN_HEIGHT);

// Set the required callback functions
glfwSetKeyCallback( window, KeyCallback );
glfwSetCursorPosCallback( window, MouseCallback );
glfwSetScrollCallback( window, ScrollCallback );
//glfwSetKeyCallback( window, KeyCallback );
//glfwSetCursorPosCallback( window, MouseCallback );
//glfwSetScrollCallback( window, ScrollCallback );

// Options, removes the mouse cursor for a more immersive experience
glfwSetInputMode( window, GLFW_CURSOR, GLFW_CURSOR_DISABLED );
//glfwSetInputMode( window, GLFW_CURSOR, GLFW_CURSOR_DISABLED );

// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
glewExperimental = GL_TRUE;
// Initialize GLEW to setup the OpenGL Function pointers
if ( GLEW_OK != glewInit( ) )
{
std::cout << "Failed to initialize GLEW" << std::endl;
std::cerr << "Failed to initialize GLEW" << std::endl;
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(window);
IMG_Quit();
SDL_Quit();
return EXIT_FAILURE;
}

Expand All @@ -93,7 +126,7 @@ int main( )
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

// Setup and compile our shaders
Shader ourShader( "res/shaders/core.vs", "res/shaders/core.frag" );
Shader ourShader( "res/shaders/core.vs", "res/shaders/core.frag" );

// Set up our vertex data (and buffer(s)) and attribute pointers
GLfloat vertices[] =
Expand Down Expand Up @@ -186,22 +219,91 @@ int main( )
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
// Load, create texture and generate mipmaps
int width, height;
unsigned char *image = SOIL_load_image( "res/images/image1.jpg", &width, &height, 0, SOIL_LOAD_RGB );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image );
//unsigned char *image = SOIL_load_image( "res/images/image1.jpg", &width, &height, 0, SOIL_LOAD_RGB );
// Begin loading texture
// Not my creation, just something I found with google: https://www.gamedev.net/forums/topic/677152-textures-with-sdl2-opengl/
const char * imgFileName = "rs/images/image1.jpg";
SDL_Surface *surface = IMG_Load(imgFileName); // this surface will tell us the details of the image
GLint nColors;
GLenum textureFormat;
if(surface){
//get number of channels in the SDL surface
nColors = surface->format->BytesPerPixel;

//contains an alpha channel
if(nColors == 4)
{
if(surface->format->Rmask==0x000000ff)
textureFormat = GL_RGBA;
else
textureFormat = GL_BGRA;
}
else if(nColors == 3) //no alpha channel
{
if(surface->format->Rmask==0x000000ff)
textureFormat = GL_RGB;
else
textureFormat = GL_BGR;
}
else
{
std::cerr << "warning: the image is not truecolor…this will break " << std::endl;
}

// Have OpenGL generate a texture object handle for us
glTexImage2D( GL_TEXTURE_2D, 0, textureFormat, surface->w, surface->h, 0, textureFormat, GL_UNSIGNED_BYTE, surface->pixels);

width = surface->w;
height = surface->h;
}
else {
std::cerr << "LoadTexture:: Could not load " << imgFileName << ": " << SDL_GetError() << std::endl;
}

// Free the SDL_Surface only if it was successfully created
if(surface) {
SDL_FreeSurface(surface);
}
// End loading texture
glGenerateMipmap( GL_TEXTURE_2D );
SOIL_free_image_data( image );
//SOIL_free_image_data( image );
glBindTexture( GL_TEXTURE_2D, 0 ); // Unbind texture when done, so we won't accidentily mess up our texture.


bool shouldClose = false;
SDL_SetRelativeMouseMode(SDL_TRUE);
// Game loop
while( !glfwWindowShouldClose( window ) )
//while( !glfwWindowShouldClose( window ) )
while(!shouldClose)
{
// Set frame time
GLfloat currentFrame = glfwGetTime( );
//GLfloat currentFrame = glfwGetTime( );
GLfloat currentFrame = SDL_GetTicks() / 1000.0f; // Because SDL_GetTicks returns milliseconds
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;

// Check and call events
glfwPollEvents( );
//glfwPollEvents( );
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
shouldClose = true;
break;
// Movement keys handling is all done in DoMovement
} else if (event.type == SDL_KEYUP) {
if (event.key.keysym.sym == SDLK_ESCAPE) {
shouldClose = true;
break;
}
} else if (event.type == SDL_MOUSEMOTION) {
GLfloat xOffset, yOffset;
xOffset = event.motion.xrel;
yOffset = event.motion.yrel;

camera.ProcessMouseMovement( xOffset, -yOffset );
} else if (event.type == SDL_MOUSEWHEEL) {
camera.ProcessMouseScroll( event.wheel.y );
}
}
DoMovement( );

// Clear the colorbuffer
Expand All @@ -224,9 +326,9 @@ int main( )
view = camera.GetViewMatrix( );

// Get the uniform locations
GLint modelLoc = glGetUniformLocation( ourShader.Program, "model" );
GLint viewLoc = glGetUniformLocation( ourShader.Program, "view" );
GLint projLoc = glGetUniformLocation( ourShader.Program, "projection" );
GLint modelLoc = glGetUniformLocation( ourShader.program, "model" );
GLint viewLoc = glGetUniformLocation( ourShader.program, "view" );
GLint projLoc = glGetUniformLocation( ourShader.program, "projection" );

// Pass the matrices to the shader
glUniformMatrix4fv( viewLoc, 1, GL_FALSE, glm::value_ptr( view ) );
Expand All @@ -249,42 +351,52 @@ int main( )
glBindVertexArray( 0 );

// Swap the buffers
glfwSwapBuffers( window );
//glfwSwapBuffers( window );
SDL_GL_SwapWindow(window);
}

// Properly de-allocate all resources once they've outlived their purpose
glDeleteVertexArrays( 1, &VAO );
glDeleteBuffers( 1, &VBO );
glfwTerminate( );
//glfwTerminate( );
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(window);
IMG_Quit();
SDL_Quit();

return EXIT_SUCCESS;
}

// Moves/alters the camera positions based on user input
void DoMovement( )
{
keys = SDL_GetKeyboardState(NULL);
// Camera controls
if( keys[GLFW_KEY_W] || keys[GLFW_KEY_UP] )
//if( keys[GLFW_KEY_W] || keys[GLFW_KEY_UP] )
if (keys[SDL_SCANCODE_W] || keys[SDL_SCANCODE_UP])
{
camera.ProcessKeyboard( FORWARD, deltaTime );
}

if( keys[GLFW_KEY_S] || keys[GLFW_KEY_DOWN] )
//if( keys[GLFW_KEY_S] || keys[GLFW_KEY_DOWN] )
if (keys[SDL_SCANCODE_S] || keys[SDL_SCANCODE_DOWN])
{
camera.ProcessKeyboard( BACKWARD, deltaTime );
camera.ProcessKeyboard( BACKWARD, deltaTime );
}

if( keys[GLFW_KEY_A] || keys[GLFW_KEY_LEFT] )
//if( keys[GLFW_KEY_A] || keys[GLFW_KEY_LEFT] )
if (keys[SDL_SCANCODE_A] || keys[SDL_SCANCODE_LEFT])
{
camera.ProcessKeyboard( LEFT, deltaTime );
camera.ProcessKeyboard( LEFT, deltaTime );
}

if( keys[GLFW_KEY_D] || keys[GLFW_KEY_RIGHT] )
//if( keys[GLFW_KEY_D] || keys[GLFW_KEY_RIGHT] )
if (keys[SDL_SCANCODE_D] || keys[SDL_SCANCODE_RIGHT])
{
camera.ProcessKeyboard( RIGHT, deltaTime );
camera.ProcessKeyboard( RIGHT, deltaTime );
}
}

/*
// Is called whenever a key is pressed/released via GLFW
void KeyCallback( GLFWwindow *window, int key, int scancode, int action, int mode )
{
Expand Down Expand Up @@ -329,3 +441,4 @@ void ScrollCallback( GLFWwindow *window, double xOffset, double yOffset )
{
camera.ProcessMouseScroll( yOffset );
}
*/