Added shader points and shader bitmap demos
This commit is contained in:
368
progs/glsl/bitmap.c
Normal file
368
progs/glsl/bitmap.c
Normal file
@@ -0,0 +1,368 @@
|
||||
/**
|
||||
* Implement glRasterPos + glBitmap with textures + shaders.
|
||||
* Brian Paul
|
||||
* 14 May 2007
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glut.h>
|
||||
#include <GL/glext.h>
|
||||
#include "extfuncs.h"
|
||||
|
||||
|
||||
static GLuint FragShader;
|
||||
static GLuint VertShader;
|
||||
static GLuint Program;
|
||||
|
||||
static GLint Win = 0;
|
||||
static GLint WinWidth = 500, WinHeight = 500;
|
||||
static GLboolean Anim = GL_TRUE;
|
||||
static GLboolean Bitmap = GL_FALSE;
|
||||
static GLfloat Xrot = 20.0f, Yrot = 70.0f;
|
||||
static GLint uTex, uScale;
|
||||
static GLuint Textures[2];
|
||||
|
||||
#define TEX_WIDTH 16
|
||||
#define TEX_HEIGHT 8
|
||||
|
||||
|
||||
static void
|
||||
BitmapText(const char *s)
|
||||
{
|
||||
while (*s) {
|
||||
glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Redisplay(void)
|
||||
{
|
||||
static const GLfloat px[3] = { 1.2, 0, 0};
|
||||
static const GLfloat nx[3] = {-1.2, 0, 0};
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glPushMatrix();
|
||||
glRotatef(Xrot, 1.0f, 0.0f, 0.0f);
|
||||
glRotatef(Yrot, 0.0f, 1.0f, 0.0f);
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
|
||||
glPushMatrix();
|
||||
glScalef(0.5, 0.5, 0.5);
|
||||
glutSolidDodecahedron();
|
||||
glPopMatrix();
|
||||
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
glColor3f(0, 1, 0);
|
||||
glBegin(GL_LINES);
|
||||
glVertex3f(-1, 0, 0);
|
||||
glVertex3f( 1, 0, 0);
|
||||
glEnd();
|
||||
|
||||
glColor3f(1, 1, 0);
|
||||
|
||||
if (Bitmap) {
|
||||
glRasterPos3fv(px);
|
||||
BitmapText("+X");
|
||||
glRasterPos3fv(nx);
|
||||
BitmapText("-X");
|
||||
}
|
||||
else {
|
||||
glUseProgram_func(Program);
|
||||
|
||||
/* vertex positions (deltas) depend on texture size and window size */
|
||||
if (uScale != -1) {
|
||||
glUniform2f_func(uScale,
|
||||
2.0 * TEX_WIDTH / WinWidth,
|
||||
2.0 * TEX_HEIGHT / WinHeight);
|
||||
}
|
||||
|
||||
/* draw +X */
|
||||
glBindTexture(GL_TEXTURE_2D, Textures[0]);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0, 0); glVertex3fv(px);
|
||||
glTexCoord2f(1, 0); glVertex3fv(px);
|
||||
glTexCoord2f(1, 1); glVertex3fv(px);
|
||||
glTexCoord2f(0, 1); glVertex3fv(px);
|
||||
glEnd();
|
||||
|
||||
/* draw -X */
|
||||
glBindTexture(GL_TEXTURE_2D, Textures[1]);
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0, 0); glVertex3fv(nx);
|
||||
glTexCoord2f(1, 0); glVertex3fv(nx);
|
||||
glTexCoord2f(1, 1); glVertex3fv(nx);
|
||||
glTexCoord2f(0, 1); glVertex3fv(nx);
|
||||
glEnd();
|
||||
|
||||
glUseProgram_func(0);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Idle(void)
|
||||
{
|
||||
Yrot = glutGet(GLUT_ELAPSED_TIME) * 0.01;
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Reshape(int width, int height)
|
||||
{
|
||||
WinWidth = width;
|
||||
WinHeight = height;
|
||||
glViewport(0, 0, width, height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0f, 0.0f, -10.0f);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Key(unsigned char key, int x, int y)
|
||||
{
|
||||
(void) x;
|
||||
(void) y;
|
||||
|
||||
switch(key) {
|
||||
case ' ':
|
||||
case 'a':
|
||||
Anim = !Anim;
|
||||
if (Anim)
|
||||
glutIdleFunc(Idle);
|
||||
else
|
||||
glutIdleFunc(NULL);
|
||||
break;
|
||||
case 'b':
|
||||
Bitmap = !Bitmap;
|
||||
if (Bitmap)
|
||||
printf("Using glBitmap\n");
|
||||
else
|
||||
printf("Using billboard texture\n");
|
||||
break;
|
||||
case 27:
|
||||
glDeleteShader_func(FragShader);
|
||||
glDeleteShader_func(VertShader);
|
||||
glDeleteProgram_func(Program);
|
||||
glutDestroyWindow(Win);
|
||||
exit(0);
|
||||
}
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
SpecialKey(int key, int x, int y)
|
||||
{
|
||||
const GLfloat step = 0.125f;
|
||||
switch(key) {
|
||||
case GLUT_KEY_UP:
|
||||
Xrot -= step;
|
||||
break;
|
||||
case GLUT_KEY_DOWN:
|
||||
Xrot += step;
|
||||
break;
|
||||
case GLUT_KEY_LEFT:
|
||||
Yrot -= step;
|
||||
break;
|
||||
case GLUT_KEY_RIGHT:
|
||||
Yrot += step;
|
||||
break;
|
||||
}
|
||||
/*printf("Xrot: %f Yrot: %f\n", Xrot, Yrot);*/
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
MakeTexImage(const char *p, GLuint texobj)
|
||||
{
|
||||
GLubyte image[TEX_HEIGHT][TEX_WIDTH];
|
||||
GLuint i, j, k;
|
||||
|
||||
for (i = 0; i < TEX_HEIGHT; i++) {
|
||||
for (j = 0; j < TEX_WIDTH; j++) {
|
||||
k = i * TEX_WIDTH + j;
|
||||
if (p[k] == ' ') {
|
||||
image[i][j] = 0;
|
||||
}
|
||||
else {
|
||||
image[i][j] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texobj);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, TEX_WIDTH, TEX_HEIGHT, 0,
|
||||
GL_RED, GL_UNSIGNED_BYTE, image);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
MakeBitmapTextures(void)
|
||||
{
|
||||
const char *px =
|
||||
" X X "
|
||||
" X X X "
|
||||
" X X X "
|
||||
" XXXXX X "
|
||||
" X X X "
|
||||
" X X X "
|
||||
" X X "
|
||||
" X X ";
|
||||
const char *nx =
|
||||
" X X "
|
||||
" X X "
|
||||
" X X "
|
||||
" XXXXX X "
|
||||
" X X "
|
||||
" X X "
|
||||
" X X "
|
||||
" X X ";
|
||||
glGenTextures(2, Textures);
|
||||
MakeTexImage(px, Textures[0]);
|
||||
MakeTexImage(nx, Textures[1]);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
LoadAndCompileShader(GLuint shader, const char *text)
|
||||
{
|
||||
GLint stat;
|
||||
|
||||
glShaderSource_func(shader, 1, (const GLchar **) &text, NULL);
|
||||
|
||||
glCompileShader_func(shader);
|
||||
|
||||
glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat);
|
||||
if (!stat) {
|
||||
GLchar log[1000];
|
||||
GLsizei len;
|
||||
glGetShaderInfoLog_func(shader, 1000, &len, log);
|
||||
fprintf(stderr, "fslight: problem compiling shader:\n%s\n", log);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
CheckLink(GLuint prog)
|
||||
{
|
||||
GLint stat;
|
||||
glGetProgramiv_func(prog, GL_LINK_STATUS, &stat);
|
||||
if (!stat) {
|
||||
GLchar log[1000];
|
||||
GLsizei len;
|
||||
glGetProgramInfoLog_func(prog, 1000, &len, log);
|
||||
fprintf(stderr, "Linker error:\n%s\n", log);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Init(void)
|
||||
{
|
||||
/* Fragment shader: modulate raster color by texture, discard fragments
|
||||
* with alpha < 1.0
|
||||
*/
|
||||
static const char *fragShaderText =
|
||||
"uniform sampler2D tex2d; \n"
|
||||
"void main() {\n"
|
||||
" vec4 c = texture2D(tex2d, gl_TexCoord[0].xy); \n"
|
||||
" if (c.w < 1.0) \n"
|
||||
" discard; \n"
|
||||
" gl_FragColor = c * gl_Color; \n"
|
||||
"}\n";
|
||||
/* Vertex shader: compute new vertex position based on incoming vertex pos,
|
||||
* texcoords and special scale factor.
|
||||
*/
|
||||
static const char *vertShaderText =
|
||||
"uniform vec2 scale; \n"
|
||||
"void main() {\n"
|
||||
" vec4 p = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
|
||||
" gl_Position.xy = p.xy + gl_MultiTexCoord0.xy * scale * p.w; \n"
|
||||
" gl_Position.zw = p.zw; \n"
|
||||
" gl_TexCoord[0] = gl_MultiTexCoord0; \n"
|
||||
" gl_FrontColor = gl_Color; \n"
|
||||
"}\n";
|
||||
const char *version;
|
||||
|
||||
version = (const char *) glGetString(GL_VERSION);
|
||||
if (version[0] != '2' || version[1] != '.') {
|
||||
printf("This program requires OpenGL 2.x, found %s\n", version);
|
||||
exit(1);
|
||||
}
|
||||
printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
|
||||
|
||||
GetExtensionFuncs();
|
||||
|
||||
FragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
|
||||
LoadAndCompileShader(FragShader, fragShaderText);
|
||||
|
||||
VertShader = glCreateShader_func(GL_VERTEX_SHADER);
|
||||
LoadAndCompileShader(VertShader, vertShaderText);
|
||||
|
||||
Program = glCreateProgram_func();
|
||||
glAttachShader_func(Program, FragShader);
|
||||
glAttachShader_func(Program, VertShader);
|
||||
glLinkProgram_func(Program);
|
||||
CheckLink(Program);
|
||||
glUseProgram_func(Program);
|
||||
|
||||
uScale = glGetUniformLocation_func(Program, "scale");
|
||||
uTex = glGetUniformLocation_func(Program, "tex2d");
|
||||
if (uTex != -1) {
|
||||
glUniform1i_func(uTex, 0); /* tex unit 0 */
|
||||
}
|
||||
|
||||
glUseProgram_func(0);
|
||||
|
||||
glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_NORMALIZE);
|
||||
glEnable(GL_LIGHT0);
|
||||
|
||||
MakeBitmapTextures();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
glutInit(&argc, argv);
|
||||
glutInitWindowSize(WinWidth, WinHeight);
|
||||
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
|
||||
Win = glutCreateWindow(argv[0]);
|
||||
glutReshapeFunc(Reshape);
|
||||
glutKeyboardFunc(Key);
|
||||
glutSpecialFunc(SpecialKey);
|
||||
glutDisplayFunc(Redisplay);
|
||||
if (Anim)
|
||||
glutIdleFunc(Idle);
|
||||
Init();
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user