diff --git a/lighting/Makefile b/lighting/Makefile new file mode 100644 index 0000000..c5213ff --- /dev/null +++ b/lighting/Makefile @@ -0,0 +1,10 @@ +export SCONSFLAGS := -Q + +all: + @scons + +install: + @scons $@ + +clean: + @scons -c diff --git a/lighting/SConstruct b/lighting/SConstruct new file mode 100644 index 0000000..6a5771b --- /dev/null +++ b/lighting/SConstruct @@ -0,0 +1,8 @@ +# vim:filetype=python + +env = Environment(LIBS = ['GL']) +env.ParseConfig('sdl-config --cflags --libs') + +sources = Glob('*.cc') + +env.Program('test', sources) diff --git a/lighting/f_shader.glsl b/lighting/f_shader.glsl new file mode 100644 index 0000000..db724ca --- /dev/null +++ b/lighting/f_shader.glsl @@ -0,0 +1,5 @@ + +void main(void) +{ + gl_FragColor = gl_Color; +} diff --git a/lighting/test.cc b/lighting/test.cc new file mode 100644 index 0000000..73db8bb --- /dev/null +++ b/lighting/test.cc @@ -0,0 +1,230 @@ + +#define GL_GLEXT_PROTOTYPES +#include +#include +#include +#include +#include +#include + +using namespace std; + +#define WIDTH 800 +#define HEIGHT 600 + +#define STRIDE(a, b) ((unsigned long)(b) - (unsigned long)(a)) +#define OFFSET(a, b) ((const GLvoid *)STRIDE((a), (b))) + +const GLfloat data[][2][3] = { + {{-1.0, -0.6, 0.0}, {1, 0, 0}}, + {{-0.2, -0.6, 0.0}, {0, 1, 0}}, + {{-0.6, 0.6, 0.0}, {0, 0, 1}}, + {{0.2, -0.6, 0.0}, {1, 0, 0}}, + {{1.0, -0.6, 0.0}, {0, 1, 0}}, + {{0.6, 0.6, -10.0}, {0, 0, 1}} +}; +const GLushort indices[] = { + 0, 1, 2, 3, 4, 5 +}; +GLuint program, vs, fs, data_vbo, index_vbo; +enum Locations { + LOC_POSITION, + LOC_COLOR +}; + +char * loadFile(const char *fname) +{ + struct stat st; + if (stat(fname, &st) != 0) + return NULL; + if (st.st_size <= 0) + return NULL; + char * buff = new char[st.st_size + 1]; + int fd = open(fname, O_RDONLY); + read(fd, buff, st.st_size); + close(fd); + buff[st.st_size] = '\0'; + return buff; +} + +char *getShaderLog(GLuint id) +{ + GLint log_length; + glGetShaderiv(id, GL_INFO_LOG_LENGTH, &log_length); + if (log_length > 0) + { + char *log = new char[log_length]; + glGetShaderInfoLog(id, log_length, &log_length, log); + return log; + } + return NULL; +} + +char *getProgramLog(GLuint id) +{ + GLint log_length; + glGetProgramiv(id, GL_INFO_LOG_LENGTH, &log_length); + if (log_length > 0) + { + char *log = new char[log_length]; + glGetProgramInfoLog(id, log_length, &log_length, log); + return log; + } + return NULL; +} + +GLuint makeShader(GLenum shaderType, const char *fname) +{ + GLuint id; + const char *source; + GLint status; + + id = glCreateShader(shaderType); + if (id <= 0) + { + cerr << "Error creating shader object" << endl; + goto out; + } + + source = loadFile(fname); + if (source == NULL) + { + fprintf(stderr, "Error reading file '%s'\n", fname); + goto cleanup_shader; + } + + glShaderSource(id, 1, &source, NULL); + delete[] source; + + glCompileShader(id); + + glGetShaderiv(id, GL_COMPILE_STATUS, &status); + if (status != GL_TRUE) + { + cerr << "Error compiling shader" << endl; + char *log = getShaderLog(id); + cerr << "Shader Log:" << endl << log << endl; + delete[] log; + goto cleanup_shader; + } + + return id; + +cleanup_shader: + glDeleteShader(id); +out: + return 0; +} + +GLuint makeBuffer(GLenum target, const void *ptr, size_t sz) +{ + GLuint id; + glGenBuffers(1, &id); + glBindBuffer(target, id); + glBufferData(target, sz, ptr, GL_STATIC_DRAW); + return id; +} + +bool init(int width, int height) +{ + glClearColor (0.0, 0.0, 0.0, 0.0); + glEnable(GL_DEPTH_TEST); + glViewport(0, 0, WIDTH, HEIGHT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + float near = 0.1; + float scale = near * 0.577 * 2; + float aspect = (float)width / (float)height; + glFrustum(-aspect * scale, aspect * scale, -scale, scale, near, 1000.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, 0, -1); + + vs = makeShader(GL_VERTEX_SHADER, "v_shader.glsl"); + fs = makeShader(GL_FRAGMENT_SHADER, "f_shader.glsl"); + + if (vs <= 0 || fs <= 0) + { + return false; + } + + program = glCreateProgram(); + glAttachShader(program, vs); + glAttachShader(program, fs); + + glBindAttribLocation(program, LOC_POSITION, "pos"); + glBindAttribLocation(program, LOC_COLOR, "color"); + + glLinkProgram(program); + + GLint link_status; + glGetProgramiv(program, GL_LINK_STATUS, &link_status); + if (link_status != GL_TRUE) + { + char *log = getProgramLog(program); + cerr << "Program log:" << endl << log << endl; + delete[] log; + glDeleteShader(vs); + glDeleteShader(fs); + return false; + } + + data_vbo = makeBuffer(GL_ARRAY_BUFFER, data, sizeof(data)); + index_vbo = makeBuffer(GL_ELEMENT_ARRAY_BUFFER, indices, sizeof(indices)); + + return true; +} + +void display(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glUseProgram(program); + glBindBuffer(GL_ARRAY_BUFFER, data_vbo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_vbo); + glEnableVertexAttribArray(LOC_POSITION); + glEnableVertexAttribArray(LOC_COLOR); + glVertexAttribPointer(LOC_POSITION, 3, GL_FLOAT, GL_FALSE, + STRIDE(&data[0], &data[1]), OFFSET(&data[0], &data[0][0])); + glVertexAttribPointer(LOC_COLOR, 3, GL_FLOAT, GL_FALSE, + STRIDE(&data[0], &data[1]), OFFSET(&data[0], &data[0][1])); + glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(indices[0]), + GL_UNSIGNED_SHORT, OFFSET(&indices, &indices[0])); + SDL_GL_SwapBuffers(); +} + +int main(int argc, char *argv[]) +{ + if (SDL_Init(SDL_INIT_VIDEO)) + { + printf("Failed to initialize SDL!\n"); + return 1; + } + + atexit(SDL_Quit); + + SDL_Surface *screen; + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + if (!(screen = SDL_SetVideoMode(WIDTH, HEIGHT, 16, SDL_OPENGL))) + { + printf("Failed to set video mode!\n"); + SDL_Quit(); + return 2; + } + SDL_WM_SetCaption(argv[0], argv[0]); + + if (!init(WIDTH, HEIGHT)) + return 2; + + display(); + SDL_Event event; + while (SDL_WaitEvent(&event)) + { + if (event.type == SDL_QUIT) + break; + else if (event.type == SDL_KEYDOWN) + { + if (event.key.keysym.sym == SDLK_ESCAPE) + break; + } + } +} diff --git a/lighting/v_shader.glsl b/lighting/v_shader.glsl new file mode 100644 index 0000000..c76673f --- /dev/null +++ b/lighting/v_shader.glsl @@ -0,0 +1,9 @@ + +attribute vec3 pos; +attribute vec3 color; + +void main(void) +{ + gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 1); + gl_FrontColor = vec4(color, 1); +}