1 /**
2  * Draw two quads, one using only a vertex shader, the other only with a
3  * fragment shader.  They should appear the same.
4  * 17 Dec 2008
5  * Brian Paul
6  */
7 
8 
9 #include <assert.h>
10 #include <string.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <math.h>
14 #include <glad/glad.h>
15 #include "glut_wrap.h"
16 #include "shaderutil.h"
17 
18 
19 static char *FragProgFile = NULL;
20 static char *VertProgFile = NULL;
21 static GLuint FragShader;
22 static GLuint VertShader;
23 static GLuint VertProgram;  /* w/out vertex shader */
24 static GLuint FragProgram;  /* w/out fragment shader */
25 static GLint Win = 0;
26 
27 
28 static void
DrawQuadColor(void)29 DrawQuadColor(void)
30 {
31    glBegin(GL_QUADS);
32    glColor3f(1, 0, 0);    glVertex2f(-1, -1);
33    glColor3f(0, 1, 0);    glVertex2f( 1, -1);
34    glColor3f(0, 0, 1);    glVertex2f( 1,  1);
35    glColor3f(1, 0, 1);    glVertex2f(-1,  1);
36    glEnd();
37 }
38 
39 
40 /** as above, but specify color via texcoords */
41 static void
DrawQuadTex(void)42 DrawQuadTex(void)
43 {
44    glBegin(GL_QUADS);
45    glTexCoord3f(1, 0, 0);    glVertex2f(-1, -1);
46    glTexCoord3f(0, 1, 0);    glVertex2f( 1, -1);
47    glTexCoord3f(0, 0, 1);    glVertex2f( 1,  1);
48    glTexCoord3f(1, 0, 1);    glVertex2f(-1,  1);
49    glEnd();
50 }
51 
52 
53 static void
Redisplay(void)54 Redisplay(void)
55 {
56    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
57 
58    /* render with vertex shader only */
59    glUseProgram(VertProgram);
60    glPushMatrix();
61    glTranslatef(-1.5, 0, 0);
62    DrawQuadTex();
63    glPopMatrix();
64 
65    /* render with fragment shader only */
66    glUseProgram(FragProgram);
67    glPushMatrix();
68    glTranslatef(+1.5, 0, 0);
69    DrawQuadColor();
70    glPopMatrix();
71 
72    glutSwapBuffers();
73 }
74 
75 
76 static void
Reshape(int width,int height)77 Reshape(int width, int height)
78 {
79    glViewport(0, 0, width, height);
80    glMatrixMode(GL_PROJECTION);
81    glLoadIdentity();
82    glOrtho(-4, 4, -2, 2, -1, 1);
83    glMatrixMode(GL_MODELVIEW);
84    glLoadIdentity();
85 }
86 
87 
88 static void
CleanUp(void)89 CleanUp(void)
90 {
91    glDeleteShader(FragShader);
92    glDeleteShader(VertShader);
93    glDeleteProgram(VertProgram);
94    glDeleteProgram(FragProgram);
95    glutDestroyWindow(Win);
96 }
97 
98 
99 static void
Key(unsigned char key,int x,int y)100 Key(unsigned char key, int x, int y)
101 {
102   (void) x;
103   (void) y;
104    switch(key) {
105    case 27:
106       CleanUp();
107       exit(0);
108       break;
109    }
110    glutPostRedisplay();
111 }
112 
113 
114 static void
Init(void)115 Init(void)
116 {
117    static const char *fragShaderText =
118       "void main() {\n"
119       "   gl_FragColor = gl_Color;\n"
120       "}\n";
121    static const char *vertShaderText =
122       "void main() {\n"
123       "   gl_Position = ftransform();\n"
124       "   gl_FrontColor = gl_MultiTexCoord0;\n" /* see DrawQuadTex() */
125       "}\n";
126 
127    if (!ShadersSupported())
128       exit(1);
129 
130    if (FragProgFile)
131       FragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile);
132    else
133       FragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText);
134 
135    if (VertProgFile)
136       VertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile);
137    else
138       VertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText);
139 
140    VertProgram = LinkShaders(VertShader, 0);
141    FragProgram = LinkShaders(0, FragShader);
142 
143    glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
144    glEnable(GL_DEPTH_TEST);
145 
146    printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
147 
148    assert(glIsProgram(VertProgram));
149    assert(glIsProgram(FragProgram));
150    assert(glIsShader(FragShader));
151    assert(glIsShader(VertShader));
152 
153    glColor3f(1, 0, 0);
154 }
155 
156 
157 static void
ParseOptions(int argc,char * argv[])158 ParseOptions(int argc, char *argv[])
159 {
160    int i;
161    for (i = 1; i < argc; i++) {
162       if (strcmp(argv[i], "-fs") == 0) {
163          FragProgFile = argv[i+1];
164       }
165       else if (strcmp(argv[i], "-vs") == 0) {
166          VertProgFile = argv[i+1];
167       }
168    }
169 }
170 
171 
172 int
main(int argc,char * argv[])173 main(int argc, char *argv[])
174 {
175    glutInit(&argc, argv);
176    glutInitWindowSize(400, 200);
177    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
178    Win = glutCreateWindow(argv[0]);
179    gladLoadGL();
180    glutReshapeFunc(Reshape);
181    glutKeyboardFunc(Key);
182    glutDisplayFunc(Redisplay);
183    ParseOptions(argc, argv);
184    Init();
185    glutMainLoop();
186    return 0;
187 }
188