1/*
2 * Vertex program evaluators test.
3 * Based on book/bezmesh.c
4 *
5 * Brian Paul
6 * 22 June 2002
7 */
8
9#include <assert.h>
10#include <stdlib.h>
11#include <stdio.h>
12#include <string.h>
13#include <GL/glew.h>
14#include "glut_wrap.h"
15
16
17/*
18 * Transform position by modelview/projection.
19 * Square incoming color.
20 */
21static const char prog[] =
22"!!VP1.0\n"
23
24"# Typical modelview/projection\n"
25"DP4   o[HPOS].x, c[0], v[OPOS] ;	# object x MVP -> clip\n"
26"DP4   o[HPOS].y, c[1], v[OPOS] ;\n"
27"DP4   o[HPOS].z, c[2], v[OPOS] ;\n"
28"DP4   o[HPOS].w, c[3], v[OPOS] ;\n"
29
30"MOV   R0, v[COL0];\n       # square the color\n"
31"MUL   R0, R0, R0;\n"
32"MOV   o[COL0], R0;\n       # store output color\n"
33
34"END";
35
36
37static int program = 1;
38
39
40GLfloat ctrlpoints[4][4][4] =
41{
42    {
43        {-1.5, -1.5, 4.0, 1.0},
44        {-0.5, -1.5, 2.0, 1.0},
45        {0.5, -1.5, -1.0, 1.0},
46        {1.5, -1.5, 2.0, 1.0}},
47    {
48        {-1.5, -0.5, 1.0, 1.0},
49        {-0.5, -0.5, 3.0, 1.0},
50        {0.5, -0.5, 0.0, 1.0},
51        {1.5, -0.5, -1.0, 1.0}},
52    {
53        {-1.5, 0.5, 4.0, 1.0},
54        {-0.5, 0.5, 0.0, 1.0},
55        {0.5, 0.5, 3.0, 1.0},
56        {1.5, 0.5, 4.0, 1.0}},
57    {
58        {-1.5, 1.5, -2.0, 1.0},
59        {-0.5, 1.5, -2.0, 1.0},
60        {0.5, 1.5, 0.0, 1.0},
61        {1.5, 1.5, -1.0, 1.0}}
62};
63
64/*
65 * +-------------+
66 * |green        |yellow
67 * |             |
68 * |             |
69 * |black        |red
70 * +-------------+
71 */
72GLfloat colorPoints[4][4][4] =
73{
74    {
75        {0.0, 0.0, 0.0, 1.0},
76        {0.3, 0.0, 0.0, 1.0},
77        {0.6, 0.0, 0.0, 1.0},
78        {1.0, 0.0, 0.0, 1.0}},
79    {
80        {0.0, 0.3, 0.0, 1.0},
81        {0.3, 0.3, 0.0, 1.0},
82        {0.6, 0.3, 0.0, 1.0},
83        {1.0, 0.3, 0.0, 1.0}},
84    {
85        {0.0, 0.6, 0.0, 1.0},
86        {0.3, 0.6, 0.0, 1.0},
87        {0.6, 0.6, 0.0, 1.0},
88        {1.0, 0.6, 0.0, 1.0}},
89    {
90        {0.0, 1.0, 0.0, 1.0},
91        {0.3, 1.0, 0.0, 1.0},
92        {0.6, 1.0, 0.0, 1.0},
93        {1.0, 1.0, 0.0, 1.0}}
94};
95
96
97static void
98initlights(void)
99{
100#if 0 /* no lighting for now */
101    GLfloat ambient[] = {0.2, 0.2, 0.2, 1.0};
102    GLfloat position[] = {0.0, 0.0, 2.0, 1.0};
103    GLfloat mat_diffuse[] = {0.6, 0.6, 0.6, 1.0};
104    GLfloat mat_specular[] = {1.0, 1.0, 1.0, 1.0};
105    GLfloat mat_shininess[] = {50.0};
106
107    glEnable(GL_LIGHTING);
108    glEnable(GL_LIGHT0);
109
110    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
111    glLightfv(GL_LIGHT0, GL_POSITION, position);
112
113    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
114    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
115    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
116#endif
117}
118
119static void
120display(void)
121{
122   glClearColor(.3, .3, .3, 0);
123    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
124    glPushMatrix();
125#if 1
126    glRotatef(85.0, 1.0, 1.0, 1.0);
127#endif
128    glEvalMesh2(GL_FILL, 0, 8, 0, 8);
129    glPopMatrix();
130    glFlush();
131}
132
133static void
134myinit(int argc, char *argv[])
135{
136    glClearColor(0.0, 0.0, 0.0, 1.0);
137    glEnable(GL_DEPTH_TEST);
138
139    initlights();       /* for lighted version only */
140
141    glMapGrid2f(8, 0.0, 1.0, 8, 0.0, 1.0);
142
143    if (argc > 1)
144       program = 0;
145
146    printf("Using vertex program attribs? %s\n", program ? "yes" : "no");
147
148    if (program && !glutExtensionSupported("GL_NV_vertex_program")) {
149       printf("Sorry, this requires GL_NV_vertex_program\n");
150       exit(1);
151    }
152
153    if (!program) {
154        glMap2f(GL_MAP2_VERTEX_4,
155                0.0, 1.0, 4, 4,
156                0.0, 1.0, 16, 4, &ctrlpoints[0][0][0]);
157        glMap2f(GL_MAP2_COLOR_4,
158                0.0, 1.0, 4, 4,
159                0.0, 1.0, 16, 4, &colorPoints[0][0][0]);
160        glEnable(GL_MAP2_VERTEX_4);
161        glEnable(GL_MAP2_COLOR_4);
162        /*
163        glEnable(GL_AUTO_NORMAL);
164        glEnable(GL_NORMALIZE);
165        */
166    }
167    else {
168        glMap2f(GL_MAP2_VERTEX_ATTRIB0_4_NV,
169                0.0, 1.0, 4, 4,
170                0.0, 1.0, 16, 4, &ctrlpoints[0][0][0]);
171        glMap2f(GL_MAP2_VERTEX_ATTRIB3_4_NV,
172                0.0, 1.0, 4, 4,
173                0.0, 1.0, 16, 4, &colorPoints[0][0][0]);
174        glEnable(GL_MAP2_VERTEX_ATTRIB0_4_NV);
175        glEnable(GL_MAP2_VERTEX_ATTRIB3_4_NV);
176
177        /*
178        glEnable(GL_AUTO_NORMAL);
179        glEnable(GL_NORMALIZE);
180        */
181
182        /* vertex program init */
183        glLoadProgramNV(GL_VERTEX_PROGRAM_NV, 1,
184                        strlen(prog), (const GLubyte *) prog);
185        assert(glIsProgramNV(1));
186        glBindProgramNV(GL_VERTEX_PROGRAM_NV, 1);
187
188        /* track matrices */
189        glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV);
190        glEnable(GL_VERTEX_PROGRAM_NV);
191    }
192}
193
194static void
195myReshape(int w, int h)
196{
197    glViewport(0, 0, w, h);
198    glMatrixMode(GL_PROJECTION);
199    glLoadIdentity();
200    if (w <= h)
201        glOrtho(-4.0, 4.0, -4.0 * (GLfloat) h / (GLfloat) w,
202            4.0 * (GLfloat) h / (GLfloat) w, -4.0, 4.0);
203    else
204        glOrtho(-4.0 * (GLfloat) w / (GLfloat) h,
205            4.0 * (GLfloat) w / (GLfloat) h, -4.0, 4.0, -4.0, 4.0);
206    glMatrixMode(GL_MODELVIEW);
207    glLoadIdentity();
208}
209
210static void
211key(unsigned char k, int x, int y)
212{
213  switch (k) {
214  case 27:  /* Escape */
215    exit(0);
216    break;
217  default:
218    return;
219  }
220  glutPostRedisplay();
221}
222
223int
224main(int argc, char **argv)
225{
226    glutInit(&argc, argv);
227    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
228    glutInitWindowPosition(0, 0);
229    glutCreateWindow(argv[0]);
230    glewInit();
231    myinit(argc, argv);
232    glutReshapeFunc(myReshape);
233    glutDisplayFunc(display);
234    glutKeyboardFunc(key);
235    glutMainLoop();
236    return 0;             /* ANSI C requires main to return int. */
237}
238