1 /*
2 * Copyright 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21
22 //#define GL_API
23 //#define GL_APIENTRY
24
25 #undef ANDROID
26 #include <EGL/egl.h>
27 #include <GLES2/gl2.h>
28
29 #ifdef __APPLE__
30 extern "C" void * createGLView(void *nsWindowPtr, int x, int y, int width, int height);
31 #endif
32
33 #undef HAVE_MALLOC_H
34 #include <SDL.h>
35 #include <SDL_syswm.h>
36
37
38 #define WINDOW_WIDTH 500
39 #define WINDOW_HEIGHT 500
40
41 #define TEX_WIDTH 256
42 #define TEX_HEIGHT 256
43
44
45 #define F_to_X(d) ((d) > 32767.65535 ? 32767 * 65536 + 65535 : \
46 (d) < -32768.65535 ? -32768 * 65536 + 65535 : \
47 ((GLfixed) ((d) * 65536)))
48 #define X_to_F(x) ((float)(x))/65536.0f
49
50 //#define __FIXED__
51
52 const char *def_vShaderStr =
53 "attribute vec4 vPosition; \n"
54 "void main() \n"
55 "{ \n"
56 " gl_Position = vPosition; \n"
57 "} \n";
58
59 const char *def_fShaderStr =
60 "precision mediump float; \n"
61 "void main() \n"
62 "{ \n"
63 #ifndef __FIXED__
64 " gl_FragColor = vec4(0.2, 0.5, 0.1, 1.0); \n"
65 #else
66 " gl_FragColor = vec4(0.4, 0.3, 0.7, 1.0); \n"
67 #endif
68 "} \n";
69
70 static EGLint const attribute_list[] = {
71 EGL_RED_SIZE, 1,
72 EGL_GREEN_SIZE, 1,
73 EGL_BLUE_SIZE, 1,
74 EGL_NONE
75 };
76
genTexture(int width,int height,int comp)77 unsigned char *genTexture(int width, int height, int comp)
78 {
79 unsigned char *img = new unsigned char[width * height * comp];
80 unsigned char *ptr = img;
81 for (int i = 0; i < height; i++) {
82 for (int j = 0; j < width; j++) {
83 unsigned char col = ((i / 8 + j / 8) % 2) * 255 ;
84 for (int c = 0; c < comp; c++) {
85 *ptr = col; ptr++;
86 }
87 }
88 }
89 return img;
90 }
91
genRedTexture(int width,int height,int comp)92 unsigned char *genRedTexture(int width, int height, int comp)
93 {
94 unsigned char *img = new unsigned char[width * height * comp];
95 memset(img,0,width*height*comp);
96 unsigned char *ptr = img;
97 for (int i = 0; i < height; i++) {
98 for (int j = 0; j < width; j++) {
99 unsigned char col = ((i / 8 + j / 8) % 2) * 255 ;
100 *ptr = col;
101 ptr+=comp;
102 }
103 }
104 return img;
105 }
106
107
printUsage(const char * progname)108 void printUsage(const char *progname)
109 {
110 fprintf(stderr, "usage: %s [options]\n", progname);
111 fprintf(stderr, "\t-vs <filename> - vertex shader to use\n");
112 fprintf(stderr, "\t-fs <filename> - fragment shader to use\n");
113 }
114
115
116
LoadShader(GLenum type,const char * shaderSrc)117 GLuint LoadShader(GLenum type,const char *shaderSrc)
118 {
119 GLuint shader;
120 GLint compiled;
121 // Create the shader object
122 shader = glCreateShader(type);
123 if(shader == 0)
124 return 0;
125 // Load the shader source
126 glShaderSource(shader, 1, &shaderSrc, NULL);
127 // Compile the shader
128 glCompileShader(shader);
129 // Check the compile status
130 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
131 if(!compiled)
132 {
133 GLint infoLen = 0;
134 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
135 if(infoLen > 1)
136 {
137 char* infoLog = (char*)malloc(sizeof(char) * infoLen);
138 glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
139 printf("Error compiling shader:\n%s\n", infoLog);
140 free(infoLog);
141 }
142 glDeleteShader(shader);
143 return 0;
144 }
145 return shader;
146 }
147
readShader(const char * fileName)148 const char *readShader(const char *fileName)
149 {
150 FILE *fp = fopen(fileName, "rb");
151 if (!fp) return NULL;
152
153 int bSize = 1024;
154 int nBufs = 1;
155 char *buf = (char *)malloc(bSize);
156 int n;
157 int len = 0;
158 n = fread(&buf[0], 1, bSize, fp);
159 while( n == bSize ) {
160 len += n;
161 nBufs++;
162 buf = (char *)realloc(buf, bSize * nBufs);
163 n = fread(&buf[len], 1, bSize, fp);
164 }
165 len += n;
166
167 buf[len] = '\0';
168 return (const char *)buf;
169 }
170
dumpUniforms(GLuint program)171 void dumpUniforms(GLuint program)
172 {
173 GLint numU;
174 glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numU);
175 printf("==== Program %d has %d active uniforms ===\n", program, numU);
176 char name[512];
177 GLsizei len;
178 GLint size;
179 GLenum type;
180 for (int i=0; i<numU; i++) {
181 glGetActiveUniform(program, i,
182 512, &len, &size, &type, name);
183 printf("\t%s : type=0x%x size=%d\n", name, type, size);
184 }
185 }
186
187 ///
188 // Initialize the shader and program object
189 //
Init(const char * vShaderStr,const char * fShaderStr)190 int Init(const char *vShaderStr, const char *fShaderStr)
191 {
192 GLuint vertexShader;
193 GLuint fragmentShader;
194 GLuint programObject;
195 GLint linked;
196 // Load the vertex/fragment shaders
197 vertexShader = LoadShader(GL_VERTEX_SHADER, vShaderStr);
198 fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fShaderStr);
199 // Create the program object
200 programObject = glCreateProgram();
201 if(programObject == 0)
202 return -1;
203 glAttachShader(programObject, vertexShader);
204 glAttachShader(programObject, fragmentShader);
205 // Bind vPosition to attribute 0
206 glBindAttribLocation(programObject, 0, "vPosition");
207 // Link the program
208 glLinkProgram(programObject);
209 // Check the link status
210 glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
211 if(!linked)
212 {
213 GLint infoLen = 0;
214 glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen);
215 if(infoLen > 1)
216 {
217 char* infoLog = (char*)malloc(sizeof(char) * infoLen);
218 glGetProgramInfoLog(programObject, infoLen, NULL, infoLog);
219 printf("Error linking program:\n%s\n", infoLog);
220 free(infoLog);
221 }
222 glDeleteProgram(programObject);
223 return -1;
224 }
225
226 // dump active uniforms
227 dumpUniforms(programObject);
228
229 // Store the program object
230 #ifndef __FIXED__
231 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
232 #else
233 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
234 #endif
235 return programObject;
236 }
237
238
239 ///
240 // Draw a triangle using the shader pair created in Init()
241 //
Draw(EGLDisplay display,EGLSurface surface,int width,int height,GLuint program)242 void Draw(EGLDisplay display,EGLSurface surface,int width,int height,GLuint program)
243 {
244 #ifndef __FIXED__
245 GLfloat vVertices[] = {0.0f, 0.5f, 0.0f,
246 -0.5f, -0.5f, 0.0f,
247 0.5f, -0.5f, 0.0f};
248 #else
249
250 GLfixed vVertices[] = {F_to_X(0.0f), F_to_X(0.5f),F_to_X(0.0f),
251 F_to_X(-0.5f),F_to_X(-0.5f), F_to_X(0.0f),
252 F_to_X(0.5f),F_to_X(-0.5f),F_to_X(0.0f)};
253 #endif
254
255 // Set the viewport
256 glViewport(0, 0,width,height);
257 // Clear the color buffer
258 glClear(GL_COLOR_BUFFER_BIT);
259 // Use the program object
260 glUseProgram(program);
261 // Load the vertex data
262 #ifndef __FIXED__
263 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
264 #else
265 glVertexAttribPointer(0, 3, GL_FIXED, GL_FALSE, 0, vVertices);
266 #endif
267 glEnableVertexAttribArray(0);
268 glDrawArrays(GL_TRIANGLES, 0, 3);
269 eglSwapBuffers(display,surface);
270 }
271
272 #ifdef _WIN32
parseCmdLine(char * cmdLine,int * argc)273 char **parseCmdLine(char *cmdLine, int *argc)
274 {
275 int argvSize = 10;
276 char **argv = (char **)malloc(argvSize * sizeof(char *));
277 *argc = 0;
278 int i=0;
279 bool prevIsSpace = true;
280 int argStart = 0;
281
282 argv[(*argc)++] = strdup("playdump");
283
284 while(cmdLine[i] != '\0') {
285 bool isSpace = (cmdLine[i] == ' ' || cmdLine[i] == '\t');
286 if ( !isSpace && prevIsSpace ) {
287 argStart = i;
288 }
289 else if (isSpace && !prevIsSpace) {
290 cmdLine[i] = '\0';
291 if (*argc >= argvSize) {
292 argvSize *= 2;
293 argv = (char **)realloc(argv, argvSize * sizeof(char *));
294 }
295 argv[(*argc)++] = &cmdLine[argStart];
296 argStart = i+1;
297 }
298
299 prevIsSpace = isSpace;
300 i++;
301 }
302
303 if (i > argStart) {
304 argv[(*argc)++] = &cmdLine[argStart];
305 }
306 return argv;
307 }
308 #endif
309
310 #ifdef _WIN32
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)311 int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
312 #else
313 int main(int argc, char **argv)
314 #endif
315 {
316 GLuint ui32Vbo = 0; // Vertex buffer object handle
317 GLuint ui32IndexVbo;
318 GLuint ui32Texture;
319
320 int nframes = 100;
321 bool immidateMode = false;
322 bool useIndices = false;
323 bool useTexture = true;
324 bool useCompTexture = false;
325 bool useFixed = true;
326 bool usePoints = false;
327 bool useCopy = false;
328 bool useSubCopy = false;
329
330 #ifdef _WIN32
331 int argc;
332 char **argv = parseCmdLine(lpCmdLine, &argc);
333 #endif
334 const char *vShader = def_vShaderStr;
335 const char *fShader = def_fShaderStr;
336
337 for (int i=1; i<argc; i++) {
338 if (!strcmp(argv[i],"-vs")) {
339 if (++i >= argc) {
340 printUsage(argv[0]);
341 return -1;
342 }
343 vShader = readShader(argv[i]);
344 if (!vShader) {
345 vShader = def_vShaderStr;
346 printf("Failed to load vshader %s, using defualt\n", argv[i]);
347 }
348 else {
349 printf("Using vshader %s\n", argv[i]);
350 }
351 }
352 else if (!strcmp(argv[i],"-fs")) {
353 if (++i >= argc) {
354 printUsage(argv[0]);
355 return -1;
356 }
357 fShader = readShader(argv[i]);
358 if (!fShader) {
359 fShader = def_fShaderStr;
360 printf("Failed to load fshader %s, using defualt\n", argv[i]);
361 }
362 else {
363 printf("Using fshader %s\n", argv[i]);
364 }
365 }
366 else {
367 printUsage(argv[0]);
368 return -1;
369 }
370 }
371
372 #ifdef _WIN32
373 HWND windowId = NULL;
374 #elif __linux__
375 Window windowId = NULL;
376 #elif __APPLE__
377 void* windowId = NULL;
378 #endif
379
380 // // Inialize SDL window
381 //
382 if (SDL_Init(SDL_INIT_NOPARACHUTE | SDL_INIT_VIDEO)) {
383 fprintf(stderr,"SDL init failed: %s\n", SDL_GetError());
384 return -1;
385 }
386
387 SDL_Surface *surface = SDL_SetVideoMode(WINDOW_WIDTH,WINDOW_HEIGHT, 32, SDL_HWSURFACE);
388 if (surface == NULL) {
389 fprintf(stderr,"Failed to set video mode: %s\n", SDL_GetError());
390 return -1;
391 }
392
393 SDL_SysWMinfo wminfo;
394 memset(&wminfo, 0, sizeof(wminfo));
395 SDL_GetWMInfo(&wminfo);
396 #ifdef _WIN32
397 windowId = wminfo.window;
398 #elif __linux__
399 windowId = wminfo.info.x11.window;
400 #elif __APPLE__
401 windowId = createGLView(wminfo.nsWindowPtr,0,0,WINDOW_WIDTH,WINDOW_HEIGHT);
402 #endif
403
404 int major,minor,num_config;
405 int attrib_list[] ={
406 EGL_CONTEXT_CLIENT_VERSION, 2,
407 EGL_NONE
408 };
409 EGLConfig configs[150];
410 EGLSurface egl_surface;
411 EGLContext ctx;
412 EGLDisplay d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
413 eglInitialize(d,&major,&minor);
414 printf("DISPLAY == %p major =%d minor = %d\n",d,major,minor);
415 eglChooseConfig(d, attribute_list, configs, 150, &num_config);
416 printf("config returned %d\n",num_config);
417 egl_surface = eglCreateWindowSurface(d,configs[0],windowId,NULL);
418 ctx = eglCreateContext(d,configs[0],EGL_NO_CONTEXT,attrib_list);
419 printf("SURFACE == %p CONTEXT == %p\n",egl_surface,ctx);
420 if(eglMakeCurrent(d,egl_surface,egl_surface,ctx)!= EGL_TRUE){
421 printf("make current failed\n");
422 return false;
423 }
424 printf("after make current\n");
425
426 GLenum err = glGetError();
427 if(err != GL_NO_ERROR) {
428 printf("error before drawing ->>> %d \n",err);
429 } else {
430 printf("no error before drawing\n");
431 }
432
433 int program = Init(vShader, fShader);
434 if(program < 0){
435 printf("failed init shaders\n");
436 return false;
437 }
438
439 Draw(d,egl_surface,WINDOW_WIDTH,WINDOW_HEIGHT,program);
440
441 err = glGetError();
442 if(err != GL_NO_ERROR)
443 printf("error ->>> %d \n",err);
444 eglDestroySurface(d,egl_surface);
445 eglDestroyContext(d,ctx);
446
447 // Just wait until the window is closed
448 SDL_Event ev;
449 while( SDL_WaitEvent(&ev) ) {
450 if (ev.type == SDL_QUIT) {
451 break;
452 }
453 }
454 return 0;
455 }
456
457
458