1 /*
2  * OpenHMD - Free and Open Source API and drivers for immersive technology.
3  * Copyright (C) 2013 Fredrik Hultin.
4  * Copyright (C) 2013 Jakob Bornecrantz.
5  * Distributed under the Boost 1.0 licence, see LICENSE for full text.
6  */
7 
8 /* OpenGL Test - GL Helper Functions Implementation */
9 
10 #include "gl.h"
11 #include <string.h>
12 #include <math.h>
13 
14 #ifdef __unix
15 #include <signal.h>
16 #endif
17 
18 #ifndef M_PI
19 #define M_PI 3.14159265359
20 #endif
21 
init_gl(gl_ctx * ctx,int w,int h)22 void init_gl(gl_ctx* ctx, int w, int h)
23 {
24 	memset(ctx, 0, sizeof(gl_ctx));
25 
26 	// == Initialize SDL ==
27 	int ret = SDL_Init(SDL_INIT_EVERYTHING);
28 	if(ret < 0){
29 		printf("SDL_Init failed\n");
30 		exit(-1);
31 	}
32 
33 	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
34 
35 	ctx->window = SDL_CreateWindow("OpenHMD opengl example",
36 			SDL_WINDOWPOS_UNDEFINED,
37 			SDL_WINDOWPOS_UNDEFINED,
38 			w, h, SDL_WINDOW_OPENGL );
39 	if(ctx->window == NULL) {
40 		printf("SDL_CreateWindow failed\n");
41 		exit(-1);
42 	}
43 	ctx->w = w;
44 	ctx->h = h;
45 	ctx->is_fullscreen = 0;
46 
47 	ctx->glcontext = SDL_GL_CreateContext(ctx->window);
48 	if(ctx->glcontext == NULL){
49 		printf("SDL_GL_CreateContext\n");
50 		exit(-1);
51 	}
52 
53 	SDL_GL_SetSwapInterval(1);
54 
55 	// Disable ctrl-c catching on Linux (and OS X?)
56 #ifdef __unix
57 	signal(SIGINT, SIG_DFL);
58 #endif
59 
60 	// Load extensions.
61 	glewInit();
62 
63 	printf("OpenGL Renderer: %s\n", glGetString(GL_RENDERER));
64 	printf("OpenGL Vendor: %s\n", glGetString(GL_VENDOR));
65 	printf("OpenGL Version: %s\n", glGetString(GL_VERSION));
66 
67 	// == Initialize OpenGL ==
68 	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
69 	glClear(GL_COLOR_BUFFER_BIT);
70 
71 	glEnable(GL_BLEND);
72 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
73 	glEnable(GL_ALPHA_TEST);
74 	glLoadIdentity();
75 
76 	glShadeModel(GL_SMOOTH);
77 	glDisable(GL_DEPTH_TEST);
78 	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
79 	glLoadIdentity();
80 
81 	glMatrixMode(GL_PROJECTION);
82 	glEnable(GL_POLYGON_SMOOTH);
83 	glLoadIdentity();
84 
85 	glViewport(0, 0, ctx->w, ctx->h);
86 }
87 
ortho(gl_ctx * ctx)88 void ortho(gl_ctx* ctx)
89 {
90 	glMatrixMode(GL_PROJECTION);
91 	//glPushMatrix();
92 	glLoadIdentity();
93 
94 	glOrtho(0.0f, ctx->w, ctx->h, 0.0f, -1.0f, 1.0f);
95 	glMatrixMode(GL_MODELVIEW);
96 	//glPushMatrix();
97 	glLoadIdentity();
98 
99 	glDisable(GL_DEPTH_TEST);
100 	glDisable(GL_DEPTH);
101 
102 	glDisable(GL_MULTISAMPLE);
103 }
104 
draw_cube()105 void draw_cube()
106 {
107 	glBegin(GL_QUADS);
108 
109 	glVertex3f(  0.5f,  0.5f, -0.5f); /* Top Right Of The Quad (Top)      */
110 	glVertex3f( -0.5f,  0.5f, -0.5f); /* Top Left Of The Quad (Top)       */
111 	glVertex3f( -0.5f,  0.5f,  0.5f); /* Bottom Left Of The Quad (Top)    */
112 	glVertex3f(  0.5f,  0.5f,  0.5f); /* Bottom Right Of The Quad (Top)   */
113 
114 	glVertex3f(  0.5f, -0.5f,  0.5f); /* Top Right Of The Quad (Botm)     */
115 	glVertex3f( -0.5f, -0.5f,  0.5f); /* Top Left Of The Quad (Botm)      */
116 	glVertex3f( -0.5f, -0.5f, -0.5f); /* Bottom Left Of The Quad (Botm)   */
117 	glVertex3f(  0.5f, -0.5f, -0.5f); /* Bottom Right Of The Quad (Botm)  */
118 
119 	glVertex3f(  0.5f,  0.5f,  0.5f); /* Top Right Of The Quad (Front)    */
120 	glVertex3f( -0.5f,  0.5f,  0.5f); /* Top Left Of The Quad (Front)     */
121 	glVertex3f( -0.5f, -0.5f,  0.5f); /* Bottom Left Of The Quad (Front)  */
122 	glVertex3f(  0.5f, -0.5f,  0.5f); /* Bottom Right Of The Quad (Front) */
123 
124 	glVertex3f(  0.5f, -0.5f, -0.5f); /* Bottom Left Of The Quad (Back)   */
125 	glVertex3f( -0.5f, -0.5f, -0.5f); /* Bottom Right Of The Quad (Back)  */
126 	glVertex3f( -0.5f,  0.5f, -0.5f); /* Top Right Of The Quad (Back)     */
127 	glVertex3f(  0.5f,  0.5f, -0.5f); /* Top Left Of The Quad (Back)      */
128 
129 	glVertex3f( -0.5f,  0.5f,  0.5f); /* Top Right Of The Quad (Left)     */
130 	glVertex3f( -0.5f,  0.5f, -0.5f); /* Top Left Of The Quad (Left)      */
131 	glVertex3f( -0.5f, -0.5f, -0.5f); /* Bottom Left Of The Quad (Left)   */
132 	glVertex3f( -0.5f, -0.5f,  0.5f); /* Bottom Right Of The Quad (Left)  */
133 
134 	glVertex3f(  0.5f,  0.5f, -0.5f); /* Top Right Of The Quad (Right)    */
135 	glVertex3f(  0.5f,  0.5f,  0.5f); /* Top Left Of The Quad (Right)     */
136 	glVertex3f(  0.5f, -0.5f,  0.5f); /* Bottom Left Of The Quad (Right)  */
137 	glVertex3f(  0.5f, -0.5f, -0.5f); /* Bottom Right Of The Quad (Right) */
138 
139 	glEnd();
140 
141 }
142 
compile_shader_src(GLuint shader,const char * src)143 static void compile_shader_src(GLuint shader, const char* src)
144 {
145 	glShaderSource(shader, 1, &src, NULL);
146 	glCompileShader(shader);
147 
148 	GLint status;
149 	GLint length;
150 	char log[4096] = {0};
151 
152 	glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
153 	glGetShaderInfoLog(shader, 4096, &length, log);
154 	if(status == GL_FALSE){
155 		printf("compile failed %s\n", log);
156 	}
157 }
158 
compile_shader(const char * vertex,const char * fragment)159 GLuint compile_shader(const char* vertex, const char* fragment)
160 {
161 	// Create the handels
162 	GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
163 	GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
164 	GLuint programShader = glCreateProgram();
165 
166 	// Attach the shaders to a program handel.
167 	glAttachShader(programShader, vertexShader);
168 	glAttachShader(programShader, fragmentShader);
169 
170 	// Load and compile the Vertex Shader
171 	compile_shader_src(vertexShader, vertex);
172 
173 	// Load and compile the Fragment Shader
174 	compile_shader_src(fragmentShader, fragment);
175 
176 	// The shader objects are not needed any more,
177 	// the programShader is the complete shader to be used.
178 	glDeleteShader(vertexShader);
179 	glDeleteShader(fragmentShader);
180 
181 	glLinkProgram(programShader);
182 
183 	GLint status;
184 	GLint length;
185 	char log[4096] = {0};
186 
187 	glGetProgramiv(programShader, GL_LINK_STATUS, &status);
188 	glGetProgramInfoLog(programShader, 4096, &length, log);
189 	if(status == GL_FALSE){
190 		printf("link failed %s\n", log);
191 	}
192 
193 	return programShader;
194 }
195 
create_fbo(int eye_width,int eye_height,GLuint * fbo,GLuint * color_tex,GLuint * depth_tex)196 void create_fbo(int eye_width, int eye_height, GLuint* fbo, GLuint* color_tex, GLuint* depth_tex)
197 {
198 	glGenTextures(1, color_tex);
199 	glGenTextures(1, depth_tex);
200 	glGenFramebuffers(1, fbo);
201 
202 	glBindTexture(GL_TEXTURE_2D, *color_tex);
203 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, eye_width, eye_height, 0, GL_RGBA, GL_UNSIGNED_INT, NULL);
204 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
205 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
206 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
207 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
208 
209 	glBindTexture(GL_TEXTURE_2D, *depth_tex);
210 	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, eye_width, eye_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
211 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
212 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
213 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
214 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
215 	glBindTexture(GL_TEXTURE_2D, 0);
216 
217 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *fbo);
218 	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *color_tex, 0);
219 	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, *depth_tex, 0);
220 
221 	GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
222 
223 	if(status != GL_FRAMEBUFFER_COMPLETE_EXT){
224 		printf("failed to create fbo %x\n", status);
225 	}
226 	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
227 }
228