Forum Discussion
tmason101
11 years agoHonored Guest
Almost working GLFW+OpenGL+SDK 0.4.3 Example ...
Hello,
So, as the title suggests, I am trying to create a simple GLFW+OpenGL+SDK0.4.3 example to model my larger project out of but I am running into trouble.
I can't figure out what is wrong with the below code so I am hoping someone can help out.
Of course, if we can get this working the community can use the example I am posting as a template for their projects.
Thank you for your time.
The code below has the following dependencies:
Header File "Main.H":
Code File Main.CPP:
So, as the title suggests, I am trying to create a simple GLFW+OpenGL+SDK0.4.3 example to model my larger project out of but I am running into trouble.
I can't figure out what is wrong with the below code so I am hoping someone can help out.
Of course, if we can get this working the community can use the example I am posting as a template for their projects.
Thank you for your time.
The code below has the following dependencies:
- GLEW
- GLFW
- GLM
- Oculus Rift SDK 0.4.3
Header File "Main.H":
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#ifndef OPENGL_INCLUDES_
#define OPENGL_INCLUDES_
#include "GL\glew.h"
#ifndef GLFW_INCLUDES_
#define GLFW_INCLUDES_
#if defined(_WIN32)
#include <Windows.h>
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WGL
#elif defined(__linux__)
#include <X11/X.h>
#include <X11/extensions/Xrandr.h>
#define GLFW_EXPOSE_NATIVE_X11
#define GLFW_EXPOSE_NATIVE_GLX
#endif
#include "GLFW\glfw3.h"
#include "GLFW\glfw3native.h"
#endif
#ifndef GLM_INCLUDES_
#define GLM_INCLUDES_
#include <glm/glm.hpp>
#include <glm/gtx/rotate_vector.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/quaternion.hpp>
#endif
#ifndef OCULUS_SDK_
#define OCULUS_SDK_
#define OVR_OS_WIN32
#include "OVR_CAPI_GL.h"
#include "Kernel\OVR_Math.h"
#endif
#endif
GLFWwindow* MainWindow;
#ifdef _WIN32
HWND MainWindowWin32Handle = NULL;
#endif
GLint WindowWidth = 1024;
GLint WindowHeight = 768;
GLfloat AspectRatio;
GLulong SizeDivizor = 1;
GLboolean RiftAvailable = false;
GLboolean UseApplicationWindowFrame = false;
ovrHmd Main_HMD = NULL;
ovrEyeRenderDesc Main_EyeRenderDesc[2];
ovrRecti Main_EyeRenderViewport[2];
ovrGLConfig Main_HMD_Render_Config;
ovrGLTexture Main_EyeTexture[2];
OVR::Recti Main_HMD_Pos_Res;
ovrFovPort Main_HMD_eyeFov[2];
GLuint Main_HMD_FrameIndex;
OVR::Sizei recommenedLeftEyeSize;
OVR::Sizei recommenedRightEyeSize;
OVR::Sizei finalTextureSize;
GLuint OculusRiftFrameBufferID;
GLuint OculusRiftRenderBufferID;
GLuint OculusRiftDepthBufferID;
GLuint OculusRiftTextureID;
GLuint MainOpenGLShaderProgramID;
GLuint MatricesUniformBlockID;
GLuint MatricesUniformBufferID;
GLuint LightsUniformBlockID;
GLuint LightsUniformBufferID;
GLuint MaterialsUniformBlockID;
GLuint MaterialsUniformBufferID;
glm::mat4 ViewMatrix;
glm::mat4 ViewModelMatrix;
glm::mat4 ProjectionMatrix;
glm::mat4 MVPMatrix;
glm::mat3 NormalMatrix;
class StandardCube;
std::vector<StandardCube> Cubes;
void (*DrawScene)();
int initializeOculusRift();
int initializeGLFWGLEW();
int prepareOpenGL();
int prepareFrameBuffer();
int prepareOculusRiftWindow();
int configureOculusRift();
int configureOculusRiftTracking();
int loadShaders();
int prepareShaderUniforms();
int loadCubes();
int prepareMatrices();
int SetDrawFunctionPointer();
void DrawWindowed();
void DrawOculusRift();
static void GLFWKeyCallback(GLFWwindow* p_Window, GLint p_Key, GLint p_Scancode, GLint p_Action, GLint p_Mods);
static void GLFWWindowResizeCallBack(GLFWwindow* p_Window, GLint width, GLint height);
static void GLFWMouseMovementCallBack(GLFWwindow* p_Window, GLdouble MouseX, GLdouble MouseY);
static void GLFWFramebufferSizeCallback(GLFWwindow* window, GLint width, GLint height);
static void GLFWErrorCallback(GLint error, const char* description);
int main(int argc, char** argv);
Code File Main.CPP:
#include "Main.h"
class StandardCube {
private:
GLfloat* Vertices;
GLfloat* Normals;
GLuint* Indices;
GLuint VAO;
glm::mat4 ModelMatrix;
public:
void LoadIntoOpenGL() {
Vertices = new GLfloat[72]
{
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
};
Normals = new GLfloat[72] {
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f
};
Indices = new GLuint[36] {0, 1, 2, 2, 3, 0,
4, 5, 6, 6, 7, 4,
8, 9, 10, 10, 11, 8,
12, 13, 14, 14, 15, 12,
16, 17, 18, 18, 19, 16,
20, 21, 22, 22, 23, 20
};
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
GLuint MeshBufferID;
glGenBuffers(1, &MeshBufferID);
glBindBuffer(GL_ARRAY_BUFFER, MeshBufferID);
GLuint TotalBufferData = (sizeof(GLfloat) * 72) + (sizeof(GLfloat) * 72);
glBufferData(GL_ARRAY_BUFFER, TotalBufferData, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, NULL, sizeof(GLfloat) * 72, Vertices);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 72, sizeof(GLfloat) * 72, Normals);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)(sizeof(GLfloat) * 72));
glEnableVertexAttribArray(1);
GLuint IndexBufferID;
glGenBuffers(1, &IndexBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLint) * 36, Indices, GL_STATIC_DRAW);
glBindVertexArray(NULL);
ModelMatrix = glm::mat4(1.0f);
}
void DrawMe() {
MVPMatrix = ProjectionMatrix * ViewMatrix * ModelMatrix;
ViewModelMatrix = ViewMatrix * ModelMatrix;
NormalMatrix = glm::transpose(glm::inverse(glm::mat3(MVPMatrix)));
glBindBuffer(GL_UNIFORM_BUFFER, MatricesUniformBufferID);
glBufferSubData(GL_UNIFORM_BUFFER, NULL, sizeof(glm::mat4), glm::value_ptr(MVPMatrix));
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(ViewModelMatrix));
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4) + sizeof(glm::mat4), sizeof(glm::mat3), glm::value_ptr(NormalMatrix));
glBindBuffer(GL_UNIFORM_BUFFER, NULL);
glBindVertexArray(VAO);
glDrawElementsInstanced(GL_TRIANGLES, 36, GL_UNSIGNED_INT, NULL, 1);
glBindVertexArray(NULL);
}
void MoveMe(glm::vec3 NewPosition) {
ModelMatrix = glm::translate(ModelMatrix, NewPosition);
}
void RotateMe(GLfloat AmountToRotateBy) {
ModelMatrix = glm::rotate(ModelMatrix, AmountToRotateBy, glm::vec3(0.0f, 1.0f, 0.0f));
}
};
int initializeOculusRift() {
if (!ovr_Initialize()) {
return EXIT_FAILURE;
}
if (!Main_HMD) {
Main_HMD = ovrHmd_Create(0);
if (!Main_HMD)
{
fprintf(stderr, "Oculus Rift not detected.");
RiftAvailable = false;
}
else {
if (Main_HMD->ProductName[0] == '\0')
{
fprintf(stderr, "Rift detected, display not enabled.");
RiftAvailable = false;
}
else {
UseApplicationWindowFrame = (Main_HMD->HmdCaps & ovrHmdCap_ExtendDesktop) ? false : true;
Main_HMD_Pos_Res = OVR::Recti(Main_HMD->WindowsPos, Main_HMD->Resolution);
if (UseApplicationWindowFrame) {
SizeDivizor = 2;
}
WindowWidth = Main_HMD_Pos_Res.w / SizeDivizor;
WindowHeight = Main_HMD_Pos_Res.h / SizeDivizor;
RiftAvailable = true;
}
}
}
return EXIT_SUCCESS;
}
int initializeGLFWGLEW() {
MainWindow = NULL;
if (!glfwInit())
{
fprintf(stderr, "GLFW failed to initialize.");
glfwTerminate();
return EXIT_FAILURE;
}
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE);
glfwSetErrorCallback(GLFWErrorCallback);
if (UseApplicationWindowFrame) {
MainWindow = glfwCreateWindow(WindowWidth, WindowHeight, "Basic Oculus Rift Example", NULL, NULL);
}
else {
if (!RiftAvailable) {
MainWindow = glfwCreateWindow(WindowWidth, WindowHeight, "Basic Oculus Rift Example", NULL, NULL);
}
else {
GLint MonitorCount;
GLFWmonitor** GLFW_Monitors = glfwGetMonitors(&MonitorCount);
GLFWmonitor* MonitorToUse;
switch (MonitorCount)
{
case 0:
printf("No monitors found, exiting.\n");
return EXIT_FAILURE;
break;
case 1:
printf("Two monitors expected, found only one, using primary...\n");
MonitorToUse = glfwGetPrimaryMonitor();
break;
case 2:
printf("Two monitors found, using second monitor\n");
MonitorToUse = GLFW_Monitors[1];
break;
default:
printf("More than two monitors found, using second monitor\n");
MonitorToUse = GLFW_Monitors[1];
}
MainWindow = glfwCreateWindow(WindowWidth, WindowHeight, "Basic Oculus Rift Example", MonitorToUse, NULL);
}
}
if (!MainWindow)
{
fprintf(stderr, "Could not determine OpenGL version; exiting.");
glfwTerminate();
return EXIT_FAILURE;
}
glfwMakeContextCurrent(MainWindow);
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (GLEW_OK != err)
{
/* Problem: glewInit failed, something is seriously wrong. */
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
return EXIT_FAILURE;
}
glfwSetInputMode(MainWindow, GLFW_STICKY_KEYS, GL_TRUE);
glfwSetKeyCallback(MainWindow, GLFWKeyCallback);
glfwSetWindowSizeCallback(MainWindow, GLFWWindowResizeCallBack);
glfwSetCursorPosCallback(MainWindow, GLFWMouseMovementCallBack);
glfwSetFramebufferSizeCallback(MainWindow, GLFWFramebufferSizeCallback);
glfwSwapBuffers(MainWindow);
glfwPollEvents();
return EXIT_SUCCESS;
}
int prepareOpenGL() {
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glEnable(GL_CULL_FACE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_MULTISAMPLE);
return EXIT_SUCCESS;
}
int prepareFrameBuffer() {
if (!RiftAvailable) {
//This process doesn't apply if an Oculus Rift isn't available.
return EXIT_SUCCESS;
}
recommenedLeftEyeSize = ovrHmd_GetFovTextureSize(Main_HMD, ovrEye_Left, Main_HMD->DefaultEyeFov[0], 1.0f);
recommenedRightEyeSize = ovrHmd_GetFovTextureSize(Main_HMD, ovrEye_Right, Main_HMD->DefaultEyeFov[1], 1.0f);
finalTextureSize.w = recommenedLeftEyeSize.w + recommenedRightEyeSize.w;
finalTextureSize.h = std::max(recommenedLeftEyeSize.h, recommenedRightEyeSize.h);
glGenFramebuffers(1, &OculusRiftFrameBufferID);
glBindFramebuffer(GL_FRAMEBUFFER, OculusRiftFrameBufferID);
// The texture we're going to render to...
glGenTextures(1, &OculusRiftTextureID);
// "Bind" the newly created texture : all future texture functions will modify this texture...
glBindTexture(GL_TEXTURE_2D, OculusRiftTextureID);
// Give an empty image to OpenGL (the last "0")
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, finalTextureSize.w, finalTextureSize.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
// Linear filtering...
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Create Depth Buffer...
glGenRenderbuffers(1, &OculusRiftDepthBufferID);
glBindRenderbuffer(GL_RENDERBUFFER, OculusRiftDepthBufferID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, finalTextureSize.w, finalTextureSize.h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, OculusRiftDepthBufferID);
// Set the texture as our colour attachment #0...
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, OculusRiftTextureID, 0);
// Set the list of draw buffers...
GLenum l_GLDrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, l_GLDrawBuffers); // "1" is the size of DrawBuffers
// Check if everything is OK...
GLenum l_Check = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
if (l_Check != GL_FRAMEBUFFER_COMPLETE)
{
printf("There is a problem with the FBO.\n");
return EXIT_FAILURE;
}
// Unbind...
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return EXIT_SUCCESS;
}
int prepareOculusRiftWindow() {
if (!RiftAvailable) {
//This process doesn't apply if an Oculus Rift isn't available.
return EXIT_SUCCESS;
}
#ifdef _WIN32
if (RiftAvailable) {
MainWindowWin32Handle = glfwGetWin32Window(MainWindow);
if (UseApplicationWindowFrame) {
ovrHmd_AttachToWindow(Main_HMD, MainWindowWin32Handle, NULL, NULL);
}
return EXIT_SUCCESS;
}
else {
return EXIT_FAILURE;
}
#endif
}
int configureOculusRift() {
if (!RiftAvailable) {
return EXIT_SUCCESS;
}
Main_HMD_eyeFov[ovrEye_Left] = Main_HMD->DefaultEyeFov[ovrEye_Left];
Main_HMD_eyeFov[ovrEye_Right] = Main_HMD->DefaultEyeFov[ovrEye_Right];
Main_HMD_Render_Config.Config.Header.API = ovrRenderAPI_OpenGL;
Main_HMD_Render_Config.Config.Header.Multisample = 1;
Main_HMD_Render_Config.Config.Header.RTSize = OVR::Sizei(Main_HMD->Resolution.w, Main_HMD->Resolution.h);
Main_HMD_Render_Config.OGL.Window = MainWindowWin32Handle;
HDC MainHDC = GetDC(Main_HMD_Render_Config.OGL.Window);
Main_HMD_Render_Config.OGL.DC = MainHDC;
Main_HMD_Render_Config.OGL.Header.API = ovrRenderAPI_OpenGL;
Main_HMD_Render_Config.OGL.Header.Multisample = 1;
Main_HMD_Render_Config.OGL.Header.RTSize = OVR::Sizei(Main_HMD->Resolution.w, Main_HMD->Resolution.h);
Main_HMD_Render_Config.Config.Header.API = ovrRenderAPI_OpenGL;
Main_HMD_Render_Config.Config.Header.Multisample = 1;
Main_HMD_Render_Config.Config.Header.RTSize = OVR::Sizei(Main_HMD->Resolution.w, Main_HMD->Resolution.h);
Main_EyeRenderViewport[ovrEye_Left].Pos = OVR::Vector2i(0, 0);
Main_EyeRenderViewport[ovrEye_Left].Size = OVR::Sizei(finalTextureSize.w / 2, finalTextureSize.h);
Main_EyeRenderViewport[ovrEye_Right].Pos = OVR::Vector2i((finalTextureSize.w + 1) / 2, 0);
Main_EyeRenderViewport[ovrEye_Right].Size = Main_EyeRenderViewport[ovrEye_Left].Size;
Main_EyeTexture[ovrEye_Left].OGL.Header.API = ovrRenderAPI_OpenGL;
Main_EyeTexture[ovrEye_Left].OGL.Header.RenderViewport = Main_EyeRenderViewport[ovrEye_Left];
Main_EyeTexture[ovrEye_Left].OGL.Header.TextureSize = finalTextureSize;
Main_EyeTexture[ovrEye_Left].OGL.TexId = OculusRiftTextureID;
Main_EyeTexture[ovrEye_Left].Texture.Header.API = ovrRenderAPI_OpenGL;
Main_EyeTexture[ovrEye_Left].Texture.Header.RenderViewport = Main_EyeRenderViewport[ovrEye_Left];
Main_EyeTexture[ovrEye_Left].Texture.Header.TextureSize = finalTextureSize;
Main_EyeTexture[ovrEye_Right] = Main_EyeTexture[ovrEye_Left];
Main_EyeTexture[ovrEye_Right].OGL.Header.RenderViewport = Main_EyeRenderViewport[ovrEye_Right];
Main_EyeTexture[ovrEye_Right].Texture.Header.RenderViewport = Main_EyeRenderViewport[ovrEye_Right];
if (!ovrHmd_ConfigureRendering(Main_HMD, &Main_HMD_Render_Config.Config,
ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette |
ovrDistortionCap_TimeWarp | ovrDistortionCap_Overdrive,
Main_HMD_eyeFov,
Main_EyeRenderDesc)) {
return EXIT_FAILURE;
}
ovrHmd_SetEnabledCaps(Main_HMD, ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction);
return EXIT_SUCCESS;
}
int configureOculusRiftTracking() {
if (!RiftAvailable) {
return EXIT_SUCCESS;
}
if (!ovrHmd_ConfigureTracking(Main_HMD, ovrTrackingCap_Orientation & ovrTrackingCap_MagYawCorrection & ovrTrackingCap_Position, NULL)) {
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int loadShaders() {
// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Compile Vertex Shader
printf("Compiling Vertext Shader.\n\n");
char const * VertexSource = "#version 330 \n\n\
layout(std140) uniform Matrices{\n\
mat4 m_pvm;\n\
mat4 m_viewModel;\n\
mat3 m_normal;\n\
};\n\
layout(std140) uniform Lights{\n\
vec3 l_dir; \n\
};\n\
layout (location=0) in vec4 position;\n\
layout (location=1) in vec3 normal;\n\
\n\
\n\
out Data{\n\
vec3 normal;\n\
vec4 eye;\n\
} DataOut;\n\
\n\
void main() {\n\
\n\
DataOut.normal = normalize(m_normal * normal);\n\
DataOut.eye = -(m_viewModel * position);\n\
\n\
gl_Position = m_pvm * position;\n\
}\n\
\n";
glShaderSource(VertexShaderID, 1, &VertexSource, NULL);
glCompileShader(VertexShaderID);
// Check Vertex Shader
GLint Result = GL_FALSE;
int InfoLogLength;
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0){
std::vector<char> VertexShaderErrorMessage(InfoLogLength + 1);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
std::string ErrorMessage = std::string(&VertexShaderErrorMessage[0]);
printf("%s\n", &VertexShaderErrorMessage[0]);
}
printf("Compiling Fragment Shader.\n\n");
char const * FragmentSource = "#version 330\n\
\
layout(std140) uniform Matrices{\n\
mat4 m_pvm;\n\
mat4 m_viewModel;\n\
mat3 m_normal;\n\
};\n\
\
layout(std140) uniform Materials{\n\
vec4 diffuse;\n\
vec4 ambient;\n\
vec4 specular;\n\
vec4 emissive;\n\
float shininess;\n\
int texCount;\n\
};\
\n\
layout(std140) uniform Lights{\n\
vec3 l_dir; \n\
};\
\n\
in Data{\n\
vec3 normal;\n\
vec4 eye;\n\
} DataIn;\n\
\n\
out vec4 colorOut;\
\n\
void main() {\n\
\n\
vec4 spec = vec4(0.0);\n\
\n\
vec3 n = normalize(DataIn.normal);\n\
vec3 e = normalize(vec3(DataIn.eye));\n\
\n\
float intensity = max(dot(n, l_dir), 0.0);\n\
\n\
if (intensity > 0.0) {\n\
vec3 h = normalize(l_dir + e);\n\
\n\
float intSpec = max(dot(h, n), 0.0);\n\
spec = specular * pow(intSpec, shininess);\n\
}\n\
\n\
colorOut = max(intensity * diffuse + spec, ambient);\n\
}";
glShaderSource(FragmentShaderID, 1, &FragmentSource, NULL);
glCompileShader(FragmentShaderID);
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0){
std::vector<char> FragmentShaderErrorMessage(InfoLogLength + 1);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
std::string ErrorMessage = std::string(&FragmentShaderErrorMessage[0]);
printf("%s\n", &FragmentShaderErrorMessage[0]);
}
// Link the program
printf("Linking shader program.\n\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0){
std::vector<char> ProgramErrorMessage(InfoLogLength + 1);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
std::string ErrorMessage = std::string(&ProgramErrorMessage[0]);
printf("%s\n", &ProgramErrorMessage[0]);
}
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
MainOpenGLShaderProgramID = ProgramID;
return EXIT_SUCCESS;
}
int prepareShaderUniforms() {
glUseProgram(MainOpenGLShaderProgramID);
MatricesUniformBlockID = glGetUniformBlockIndex(MainOpenGLShaderProgramID, "Matrices");
glUniformBlockBinding(MainOpenGLShaderProgramID, MatricesUniformBlockID, 1);
glGenBuffers(1, &MatricesUniformBufferID);
glBindBuffer(GL_UNIFORM_BUFFER, MatricesUniformBufferID);
glBindBufferBase(GL_UNIFORM_BUFFER, 1, MatricesUniformBufferID);
GLsizeiptr TotalBufferSize = sizeof(glm::mat4) + sizeof(glm::mat4);
TotalBufferSize += sizeof(glm::mat3);
glBufferData(GL_UNIFORM_BUFFER, TotalBufferSize, NULL, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, NULL);
LightsUniformBlockID = glGetUniformBlockIndex(MainOpenGLShaderProgramID, "Lights");
glUniformBlockBinding(MainOpenGLShaderProgramID, LightsUniformBlockID, 2);
glGenBuffers(1, &LightsUniformBufferID);
glBindBuffer(GL_UNIFORM_BUFFER, LightsUniformBufferID);
glBindBufferBase(GL_UNIFORM_BUFFER, 2, LightsUniformBufferID);
GLfloat LightDirection[3] = {-4.0f, -3.0f, -3.0f};
glBufferData(GL_UNIFORM_BUFFER, sizeof(LightDirection), &LightDirection, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, NULL);
MaterialsUniformBlockID = glGetUniformBlockIndex(MainOpenGLShaderProgramID, "Materials");
glUniformBlockBinding(MainOpenGLShaderProgramID, MaterialsUniformBlockID, 3);
glGenBuffers(1, &MaterialsUniformBufferID);
glBindBuffer(GL_UNIFORM_BUFFER, MaterialsUniformBufferID);
glBindBufferBase(GL_UNIFORM_BUFFER, 3, MaterialsUniformBufferID);
GLfloat Material[18];
//Diffuse
Material[0] = 0.5f;
Material[1] = 0.0f;
Material[2] = 0.0f;
Material[3] = 1.0f;
//Ambient
Material[4] = 0.2f;
Material[5] = 0.2f;
Material[6] = 0.2f;
Material[7] = 1.0f;
//Specular
Material[8] = 1.0f;
Material[9] = 1.0f;
Material[10] = 1.0f;
Material[11] = 1.0f;
//Emissive
Material[12] = 0.0f;
Material[13] = 0.0f;
Material[14] = 0.0f;
Material[15] = 1.0f;
//Shininess
Material[16] = 5.0f;
//Texture Count
Material[17] = 0.0f;
glBufferData(GL_UNIFORM_BUFFER, sizeof(Material), &Material, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, NULL);
return EXIT_SUCCESS;
}
int loadCubes() {
StandardCube NewCube;
NewCube.LoadIntoOpenGL();
NewCube.MoveMe(glm::vec3(0.0f, 0.0f, -3.0f));
Cubes.push_back(NewCube);
return EXIT_SUCCESS;
}
int prepareMatricies() {
AspectRatio = (GLfloat)(WindowWidth) / (GLfloat)(WindowHeight);
ProjectionMatrix = glm::perspective(45.0f, AspectRatio, 1.0f, 1000.0f);
ViewMatrix = glm::lookAt(
glm::vec3(0.0f, 6.0f, 6.0f), // camera is at (4,3,3), in world space - Where the camera is inside world.
glm::vec3(0.0f, 0.0f, -3.0f), // and looks at the origin - What point the camera is looking at inside world.
glm::vec3(0.0f, 1.0f, 0.0f) // head is up(set to 0,1,0) - the direction of up for camera.
);
glViewport(0, 0, WindowWidth, WindowHeight);
return EXIT_SUCCESS;
}
int SetDrawFunctionPointer() {
if (!RiftAvailable) {
DrawScene = DrawWindowed;
}
else {
DrawScene = DrawOculusRift;
}
return EXIT_SUCCESS;
}
void DrawWindowed() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for (auto & C : Cubes) {
C.RotateMe(0.001f);
C.DrawMe();
}
glfwSwapBuffers(MainWindow);
glfwPollEvents();
}
void DrawOculusRift() {
static ovrFrameTiming Current_Frame = ovrHmd_BeginFrame(Main_HMD, Main_HMD_FrameIndex);
static ovrPosef Main_HMD_eyeRenderPose[2];
static ovrMatrix4f OculusRiftProjection[2];
static ovrMatrix4f OculusRiftView[2];
static OVR::Vector3f Main_HMD_HeadPos(0.0f, 1.6f, -5.0f);
static ovrTrackingState HmdState;
ovrVector3f hmdToEyeViewOffset[2] = { Main_EyeRenderDesc[0].HmdToEyeViewOffset, Main_EyeRenderDesc[1].HmdToEyeViewOffset };
ovrHmd_GetEyePoses(Main_HMD, Main_HMD_FrameIndex, hmdToEyeViewOffset, Main_HMD_eyeRenderPose, &HmdState);
Main_HMD_HeadPos.y = ovrHmd_GetFloat(Main_HMD, OVR_KEY_EYE_HEIGHT, Main_HMD_HeadPos.y);
glBindFramebuffer(GL_FRAMEBUFFER, OculusRiftFrameBufferID);
glUseProgram(MainOpenGLShaderProgramID);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for (GLint CurrentEyeIndex = 0; CurrentEyeIndex < ovrEye_Count; ++CurrentEyeIndex)
{
ovrEyeType CurrentEye = Main_HMD->EyeRenderOrder[CurrentEyeIndex];
glViewport(
Main_EyeTexture[CurrentEyeIndex].Texture.Header.RenderViewport.Pos.x,
Main_EyeTexture[CurrentEyeIndex].Texture.Header.RenderViewport.Pos.y,
Main_EyeTexture[CurrentEyeIndex].Texture.Header.RenderViewport.Size.w,
Main_EyeTexture[CurrentEyeIndex].Texture.Header.RenderViewport.Size.h
);
OculusRiftProjection[CurrentEyeIndex] = ovrMatrix4f_Projection(Main_EyeRenderDesc[CurrentEyeIndex].Fov,
1.0f, 1000.0f, true);
for (int o = 0; o < 4; o++) {
for (int i = 0; i < 4; i++) {
ProjectionMatrix[o][i] = OculusRiftProjection[CurrentEyeIndex].M[o][i];
}
}
ProjectionMatrix = glm::transpose(ProjectionMatrix);
ViewMatrix = glm::toMat4(glm::quat(
Main_HMD_eyeRenderPose[CurrentEyeIndex].Orientation.w,
-Main_HMD_eyeRenderPose[CurrentEyeIndex].Orientation.x,
-Main_HMD_eyeRenderPose[CurrentEyeIndex].Orientation.y,
-Main_HMD_eyeRenderPose[CurrentEyeIndex].Orientation.z
));
for (auto & C : Cubes) {
C.RotateMe(0.001f);
C.DrawMe();
}
}
ovrHmd_EndFrame(Main_HMD, Main_HMD_eyeRenderPose, &Main_EyeTexture[0].Texture);
Main_HMD_FrameIndex += 1;
glfwPollEvents();
}
static void GLFWKeyCallback(GLFWwindow* p_Window, GLint p_Key, GLint p_Scancode, GLint p_Action, GLint p_Mods) {
if (RiftAvailable) {
ovrHSWDisplayState l_HasWarningState;
ovrHmd_GetHSWDisplayState(Main_HMD, &l_HasWarningState);
if (l_HasWarningState.Displayed) {
ovrHmd_DismissHSWDisplay(Main_HMD);
}
}
if (p_Key == GLFW_KEY_ESCAPE && p_Action == GLFW_PRESS) {
glfwSetWindowShouldClose(p_Window, GL_TRUE);
}
if (p_Key == GLFW_KEY_O && p_Action == GLFW_PRESS) {
glClearColor(0.2f, 0.1f, 0.3f, 1.0f);
}
if (p_Key == GLFW_KEY_I && p_Action == GLFW_PRESS) {
glClearColor(1.0f, 0.5f, 0.5f, 1.0f);
}
}
static void GLFWWindowResizeCallBack(GLFWwindow* p_Window, GLint width, GLint height) {
//CurrentGLFWApplication->WindowResizeCallBack(p_Window, width, height);
}
static void GLFWMouseMovementCallBack(GLFWwindow* p_Window, GLdouble MouseX, GLdouble MouseY) {
//CurrentGLFWApplication->MouseMovementCallBack(p_Window, MouseX, MouseY);
}
static void GLFWFramebufferSizeCallback(GLFWwindow* window, GLint width, GLint height)
{
AspectRatio = (GLfloat)(width) / (GLfloat)(height);
ProjectionMatrix = glm::perspective(45.0f, AspectRatio, 1.0f, 1000.0f);
glViewport(0, 0, width, height);
}
static void GLFWErrorCallback(GLint error, const char* description)
{
fputs(description, stderr);
}
int main(int argc, char** argv) {
if (initializeOculusRift() == EXIT_FAILURE) {
exit(EXIT_FAILURE);
}
if (initializeGLFWGLEW() == EXIT_FAILURE) {
exit(EXIT_FAILURE);
}
if (prepareOpenGL() == EXIT_FAILURE) {
exit(EXIT_FAILURE);
}
if (prepareFrameBuffer() == EXIT_FAILURE) {
exit(EXIT_FAILURE);
}
if (prepareOculusRiftWindow() == EXIT_FAILURE) {
exit(EXIT_FAILURE);
}
if (configureOculusRift() == EXIT_FAILURE) {
exit(EXIT_FAILURE);
}
if (configureOculusRiftTracking() == EXIT_FAILURE) {
exit(EXIT_FAILURE);
}
if (loadShaders() == EXIT_FAILURE) {
exit(EXIT_FAILURE);
}
if (prepareShaderUniforms() == EXIT_FAILURE) {
exit(EXIT_FAILURE);
}
if (loadCubes() == EXIT_FAILURE) {
exit(EXIT_FAILURE);
}
if (prepareMatricies() == EXIT_FAILURE) {
exit(EXIT_FAILURE);
}
if (SetDrawFunctionPointer() == EXIT_FAILURE) {
exit(EXIT_FAILURE);
}
while (!glfwWindowShouldClose(MainWindow))
{
DrawScene();
}
exit(EXIT_SUCCESS);
}
16 Replies
- jhericoAdventurerYou haven't given any indication of what's going wrong with this app.
- tmason101Honored Guest
"jherico" wrote:
You haven't given any indication of what's going wrong with this app.
Hey,
My fault; when I run the above code in "Direct" mode glfwCreateWindow() crashes and when I run the application in "Extended" mode the call to ovrHmd_ConfigureRendering() produces an exception.
I looked it over a few times and I can't find exactly what I am doing wrong.
Any ideas?
Thank you. - jhericoAdventurer
Main_HMD_Render_Config.OGL.Header.API = ovrRenderAPI_OpenGL;
Main_HMD_Render_Config.OGL.Header.Multisample = 1;
Main_HMD_Render_Config.OGL.Header.RTSize = OVR::Sizei(Main_HMD->Resolution.w, Main_HMD->Resolution.h);
Main_HMD_Render_Config.Config.Header.API = ovrRenderAPI_OpenGL;
Main_HMD_Render_Config.Config.Header.Multisample = 1;
Main_HMD_Render_Config.Config.Header.RTSize = OVR::Sizei(Main_HMD->Resolution.w, Main_HMD->Resolution.h);
Main_HMD_Render_Config is a union type. You're setting the same memory location whether you access it through OGL.Header or Config.Header.
if (!ovrHmd_ConfigureTracking(Main_HMD, ovrTrackingCap_Orientation & ovrTrackingCap_MagYawCorrection & ovrTrackingCap_Position, NULL)) {
"ovrTrackingCap_Orientation & ovrTrackingCap_MagYawCorrection & ovrTrackingCap_Position" will evaluate to 0. You want to use the or operator '|'. - tmason101Honored GuestThank you for your quick feedback.
So now I get further along and then I get back the following GLSL errors:
Debug: GL_VERSION: 3.1.0 - Build 9.17.10.3347
Debug: Compiling shader
#version 110
#extension GL_ARB_shader_texture_lod : enable
#extension GL_ARB_draw_buffers : enable
#extension GL_EXT_gpu_shader4 : enable
#define _FRAGCOLOR_DECLARATION
#define _MRTFRAGCOLOR0_DECLARATION
#define _MRTFRAGCOLOR1_DECLARATION
#define _VS_IN attribute
#define _VS_OUT varying
#define _FS_IN varying
#define _TEXTURELOD texture2DLod
#define _TEXTURE texture2D
#define _FRAGCOLOR gl_FragColor
#define _MRTFRAGCOLOR0 gl_FragData[0]
#define _MRTFRAGCOLOR1 gl_FragData[1]
#define _TEXELFETCHDECL vec4 texelFetch(sampler2D tex, ivec2 coord, int lod){ ivec2 size = textureSize2D(tex, lod); return texture2D(tex, vec2(float((coord.x * 2) + 1) / float(size.x * 2), float((coord.y * 2) + 1) / float(size.y * 2))); }
uniform sampler2D Texture0;
uniform sampler2D Texture1;
uniform vec3 OverdriveScales_IsSrgb;
_FS_IN vec4 oColor;
_FS_IN vec2 oTexCoord0;
_FS_IN vec2 oTexCoord1;
_FS_IN vec2 oTexCoord2;
_MRTFRAGCOLOR0_DECLARATION
_MRTFRAGCOLOR1_DECLARATION
_FS_IN vec4 gl_FragCoord;
_TEXELFETCHDECL
void main()
{
float ResultR = _TEXTURE(Texture0, oTexCoord0, 0.0).r;
float ResultG = _TEXTURE(Texture0, oTexCoord1, 0.0).g;
float ResultB = _TEXTURE(Texture0, oTexCoord2, 0.0).b;
vec3 newColor = vec3(ResultR * oColor.r, ResultG * oColor.g, ResultB * oColor
.b);
_MRTFRAGCOLOR0 = vec4(newColor, 1);
_MRTFRAGCOLOR1 = _MRTFRAGCOLOR0;
if(OverdriveScales_IsSrgb.x > 0.0)
{
ivec2 pixelCoord = ivec2(gl_FragCoord.x, gl_FragCoord.y);
vec3 oldColor = texelFetch(Texture1, pixelCoord, 0).rgb;
vec3 adjustedScales;
adjustedScales.x = newColor.x > oldColor.x ? OverdriveScales_IsSrgb.x : OverdriveScales_IsSrgb.y;
adjustedScales.y = newColor.y > oldColor.y ? OverdriveScales_IsSrgb.x : OverdriveScales_IsSrgb.y;
adjustedScales.z = newColor.z > oldColor.z ? OverdriveScales_IsSrgb.x : OverdriveScales_IsSrgb.y;
vec3 overdriveColor;
if(OverdriveScales_IsSrgb.z > 0.0)
{
oldColor = pow(oldColor, vec3(1.0/2.2, 1.0/2.2, 1.0/2.2));
newColor = pow(newColor, vec3(1.0/2.2, 1.0/2.2, 1.0/2.2));
overdriveColor = clamp(newColor + (newColor - oldColor) * adjustedScales, 0.0, 1.0);
overdriveColor = pow(overdriveColor, vec3(2.2, 2.2, 2.2));
}
else
overdriveColor = clamp(newColor + (newColor - oldColor) * adjustedScales, 0.0, 1.0);
_MRTFRAGCOLOR1 = vec4(overdriveColor, 1.0);
}
}
failed: WARNING: 0:3: extension 'GL_ARB_draw_buffers' is not supported
WARNING: 0:4: extension 'GL_EXT_gpu_shader4' is not supported
ERROR: 0:26: 'gl_' : reserved built-in name
OpenGL 3.1 isn't that old; Is this because I have overDrive enabled?
Thank you for your time. - nuclearExplorerFirst of all, when you post problems, first make your example as minimal as possible. All those defines at the beginning of your GLSL program just obfuscate it.
The problem is you're defining a varying named gl_FragCoord. You don't define anything with the gl_ prefix, it's already defined by GLSL and reserved. - tmason101Honored Guest
"nuclear" wrote:
First of all, when you post problems, first make your example as minimal as possible. All those defines at the beginning of your GLSL program just obfuscate it.
The problem is you're defining a varying named gl_FragCoord. You don't define anything with the gl_ prefix, it's already defined by GLSL and reserved.
Thanks; the problem is that it isn't my shader; this is Oculus VR's shader.
Straight from the SDK.
So now I guess I need to do a rename from within their source?
Thank you again for the feedback. - nuclearExplorerRight, now that you mention it, it smells auto-generated ... maybe conversion from HLSL :)
I suggest you start from scratch with a minimal program that you can build up gradually, and just use existing examples as a reference. I think it's easier that way. - tmason101Honored Guest
"nuclear" wrote:
Right, now that you mention it, it smells auto-generated ... maybe conversion from HLSL :)
I suggest you start from scratch with a minimal program that you can build up gradually, and just use existing examples as a reference. I think it's easier that way.
That's what I have been trying to do with this example :)
Perhaps you can run it; the example from my code above which @jherico has helped with just shows a spinning cube.
Even with the example above I can't get "Direct" or "Extended" modes to work.
I know everyone is busy but can anyone try the code I posted above and just see if they get the same errors as myself.
I really appreciate all of the feedback. - jhericoAdventurer
"nuclear" wrote:
Right, now that you mention it, it smells auto-generated ... maybe conversion from HLSL :)
I suggest you start from scratch with a minimal program that you can build up gradually, and just use existing examples as a reference. I think it's easier that way.
It's not auto-generated. It's their wacky mechanism to use one shader across multiple versions of OpenGL and use the header defines to smooth the differences between various versions of GLSL.
What I suspect is happening is that OP is getting an 1.x OpenGL context but that the version string is still reporting 3.x, hence the SDK is trying to use the 3.x header, which then fails to compile on the context.
You might try adding this before creating your window:
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - tmason101Honored Guest
"jherico" wrote:
"nuclear" wrote:
Right, now that you mention it, it smells auto-generated ... maybe conversion from HLSL :)
I suggest you start from scratch with a minimal program that you can build up gradually, and just use existing examples as a reference. I think it's easier that way.
It's not auto-generated. It's their wacky mechanism to use one shader across multiple versions of OpenGL and use the header defines to smooth the differences between various versions of GLSL.
What I suspect is happening is that OP is getting an 1.x OpenGL context but that the version string is still reporting 3.x, hence the SDK is trying to use the 3.x header, which then fails to compile on the context.
You might try adding this before creating your window:
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
Thanks! Setting this does allow me to work in extended mode.
The application still crashes in "Direct" mode though on glfwCreateWindow()
Any ideas on this front?
Quick Links
- Horizon Developer Support
- Quest User Forums
- Troubleshooting Forum for problems with a game or app
- Quest Support for problems with your device
Other Meta Support
Related Content
- 23 days ago
- 4 years ago