vrchess

changeset 0:b326d53321f7

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 25 Apr 2014 05:20:53 +0300
parents
children cd7755e4663a
files .hgignore data/tiles.png src/camera.cc src/camera.h src/game.cc src/game.h src/image.cc src/image.h src/main.cc src/opengl.cc src/opengl.h src/sdr.c src/sdr.h src/texture.cc src/texture.h vrchess.sln vrchess.vcxproj vrchess.vcxproj.filters
diffstat 18 files changed, 1590 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/.hgignore	Fri Apr 25 05:20:53 2014 +0300
     1.3 @@ -0,0 +1,9 @@
     1.4 +\.o$
     1.5 +\.swp$
     1.6 +\.sln$
     1.7 +\.vcxproj$
     1.8 +sdf$
     1.9 +Debug/
    1.10 +Release/
    1.11 +\.suo$
    1.12 +\.dll$
     2.1 Binary file data/tiles.png has changed
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/camera.cc	Fri Apr 25 05:20:53 2014 +0300
     3.3 @@ -0,0 +1,207 @@
     3.4 +#include <stdio.h>
     3.5 +#include <math.h>
     3.6 +#include "camera.h"
     3.7 +
     3.8 +static void calc_sample_pos_rec(int sidx, float xsz, float ysz, float *pos);
     3.9 +
    3.10 +Camera::Camera()
    3.11 +{
    3.12 +	vfov = M_PI / 4.0;
    3.13 +	cached_matrix_valid = false;
    3.14 +
    3.15 +	rdir_cache_width = rdir_cache_height = 0;
    3.16 +	rdir_cache = 0;
    3.17 +}
    3.18 +
    3.19 +Camera::Camera(const Vector3 &p)
    3.20 +	: pos(p)
    3.21 +{
    3.22 +	vfov = M_PI / 4.0;
    3.23 +	cached_matrix_valid = false;
    3.24 +
    3.25 +	rdir_cache_width = rdir_cache_height = 0;
    3.26 +	rdir_cache = 0;
    3.27 +}
    3.28 +
    3.29 +Camera::~Camera()
    3.30 +{
    3.31 +	delete [] rdir_cache;
    3.32 +}
    3.33 +
    3.34 +void Camera::set_fov(float vfov)
    3.35 +{
    3.36 +	this->vfov = vfov;
    3.37 +
    3.38 +	// invalidate the dir cache
    3.39 +	delete [] rdir_cache;
    3.40 +}
    3.41 +
    3.42 +float Camera::get_fov() const
    3.43 +{
    3.44 +	return vfov;
    3.45 +}
    3.46 +
    3.47 +void Camera::set_position(const Vector3 &pos)
    3.48 +{
    3.49 +	this->pos = pos;
    3.50 +	cached_matrix_valid = false;	// invalidate the cached matrix
    3.51 +}
    3.52 +
    3.53 +const Vector3 &Camera::get_position() const
    3.54 +{
    3.55 +	return pos;
    3.56 +}
    3.57 +
    3.58 +const Matrix4x4 &Camera::get_matrix() const
    3.59 +{
    3.60 +	if(!cached_matrix_valid) {
    3.61 +		calc_matrix(&cached_matrix);
    3.62 +		cached_matrix_valid = true;
    3.63 +	}
    3.64 +	return cached_matrix;
    3.65 +}
    3.66 +
    3.67 +Vector2 Camera::calc_sample_pos(int x, int y, int xsz, int ysz, int sample) const
    3.68 +{
    3.69 +	float ppos[2];
    3.70 +	float aspect = (float)xsz / (float)ysz;
    3.71 +
    3.72 +	float pwidth = 2.0 * aspect / (float)xsz;
    3.73 +	float pheight = 2.0 / (float)ysz;
    3.74 +
    3.75 +	ppos[0] = (float)x * pwidth - aspect;
    3.76 +	ppos[1] = 1.0 - (float)y * pheight;
    3.77 +
    3.78 +	calc_sample_pos_rec(sample, pwidth, pheight, ppos);
    3.79 +	return Vector2(ppos[0], ppos[1]);
    3.80 +}
    3.81 +
    3.82 +Ray Camera::get_primary_ray(int x, int y, int xsz, int ysz, int sample) const
    3.83 +{
    3.84 +#pragma omp single
    3.85 +	{
    3.86 +		if(!rdir_cache || rdir_cache_width != xsz || rdir_cache_height != ysz) {
    3.87 +			printf("calculating primary ray direction cache\n");
    3.88 +
    3.89 +			delete [] rdir_cache;
    3.90 +			rdir_cache = new Vector3[xsz * ysz];
    3.91 +
    3.92 +#pragma omp parallel for
    3.93 +			for(int i=0; i<ysz; i++) {
    3.94 +				Vector3 *rdir = rdir_cache + i * xsz;
    3.95 +				for(int j=0; j<xsz; j++) {
    3.96 +					Vector2 ppos = calc_sample_pos(j, i, xsz, ysz, 0);
    3.97 +
    3.98 +					rdir->x = ppos.x;
    3.99 +					rdir->y = ppos.y;
   3.100 +					rdir->z = 1.0 / tan(vfov / 2.0);
   3.101 +					rdir->normalize();
   3.102 +
   3.103 +					rdir++;
   3.104 +				}
   3.105 +			}
   3.106 +			rdir_cache_width = xsz;
   3.107 +			rdir_cache_height = ysz;
   3.108 +		}
   3.109 +	}
   3.110 +
   3.111 +	Ray ray;
   3.112 +	ray.origin = pos;
   3.113 +	ray.dir = rdir_cache[y * xsz + x];
   3.114 +
   3.115 +	// transform the ray direction with the camera matrix
   3.116 +	Matrix4x4 mat = get_matrix();
   3.117 +	mat.m[0][3] = mat.m[1][3] = mat.m[2][3] = mat.m[3][0] = mat.m[3][1] = mat.m[3][2] = 0.0;
   3.118 +	mat.m[3][3] = 1.0;
   3.119 +
   3.120 +	ray.dir = ray.dir.transformed(mat);
   3.121 +	return ray;
   3.122 +}
   3.123 +
   3.124 +TargetCamera::TargetCamera() {}
   3.125 +
   3.126 +TargetCamera::TargetCamera(const Vector3 &pos, const Vector3 &targ)
   3.127 +	: Camera(pos), target(targ)
   3.128 +{
   3.129 +}
   3.130 +
   3.131 +void TargetCamera::set_target(const Vector3 &targ)
   3.132 +{
   3.133 +	target = targ;
   3.134 +	cached_matrix_valid = false; // invalidate the cached matrix
   3.135 +}
   3.136 +
   3.137 +const Vector3 &TargetCamera::get_target() const
   3.138 +{
   3.139 +	return target;
   3.140 +}
   3.141 +
   3.142 +void TargetCamera::calc_matrix(Matrix4x4 *mat) const
   3.143 +{
   3.144 +	Vector3 up(0, 1, 0);
   3.145 +	Vector3 dir = (target - pos).normalized();
   3.146 +	Vector3 right = cross_product(up, dir);
   3.147 +	up = cross_product(dir, right);
   3.148 +
   3.149 +	*mat = Matrix4x4(
   3.150 +			right.x, up.x, dir.x, pos.x,
   3.151 +			right.y, up.y, dir.y, pos.y,
   3.152 +			right.z, up.z, dir.z, pos.z,
   3.153 +			0.0, 0.0, 0.0, 1.0);
   3.154 +}
   3.155 +
   3.156 +void FlyCamera::input_move(float x, float y, float z)
   3.157 +{
   3.158 +	static const Vector3 vfwd(0, 0, 1), vright(1, 0, 0);
   3.159 +
   3.160 +	Vector3 k = vfwd.transformed(rot);
   3.161 +	Vector3	i = vright.transformed(rot);
   3.162 +	Vector3 j = cross_product(k, i);
   3.163 +
   3.164 +	pos += i * x + j * y + k * z;
   3.165 +	cached_matrix_valid = false;
   3.166 +}
   3.167 +
   3.168 +void FlyCamera::input_rotate(float x, float y, float z)
   3.169 +{
   3.170 +	Vector3 axis(x, y, z);
   3.171 +	float axis_len = axis.length();
   3.172 +	if(fabs(axis_len) < 1e-5) {
   3.173 +		return;
   3.174 +	}
   3.175 +	rot.rotate(axis / axis_len, -axis_len);
   3.176 +	rot.normalize();
   3.177 +
   3.178 +	cached_matrix_valid = false;
   3.179 +}
   3.180 +
   3.181 +void FlyCamera::calc_matrix(Matrix4x4 *mat) const
   3.182 +{
   3.183 +	Matrix4x4 tmat;
   3.184 +	tmat.set_translation(pos);
   3.185 +
   3.186 +	Matrix3x3 rmat = rot.get_rotation_matrix();
   3.187 +
   3.188 +	*mat = tmat * Matrix4x4(rmat);
   3.189 +}
   3.190 +
   3.191 +/* generates a sample position for sample number sidx, in the unit square
   3.192 + * by recursive subdivision and jittering
   3.193 + */
   3.194 +static void calc_sample_pos_rec(int sidx, float xsz, float ysz, float *pos)
   3.195 +{
   3.196 +    static const float subpt[4][2] = {
   3.197 +        {-0.25, -0.25}, {0.25, -0.25}, {-0.25, 0.25}, {0.25, 0.25}
   3.198 +    };
   3.199 +
   3.200 +    if(!sidx) {
   3.201 +        return;
   3.202 +    }
   3.203 +
   3.204 +    /* determine which quadrant to recurse into */
   3.205 +    int quadrant = ((sidx - 1) % 4);
   3.206 +    pos[0] += subpt[quadrant][0] * xsz;
   3.207 +    pos[1] += subpt[quadrant][1] * ysz;
   3.208 +
   3.209 +    calc_sample_pos_rec((sidx - 1) / 4, xsz / 2, ysz / 2, pos);
   3.210 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/camera.h	Fri Apr 25 05:20:53 2014 +0300
     4.3 @@ -0,0 +1,61 @@
     4.4 +#ifndef CAMERA_H_
     4.5 +#define CAMERA_H_
     4.6 +
     4.7 +#include "vmath/vmath.h"
     4.8 +
     4.9 +class Camera {
    4.10 +protected:
    4.11 +	Vector3 pos;
    4.12 +	float vfov;	// vertical field of view in radians
    4.13 +
    4.14 +	mutable Matrix4x4 cached_matrix;
    4.15 +	mutable bool cached_matrix_valid;
    4.16 +
    4.17 +	mutable Vector3 *rdir_cache;
    4.18 +	mutable int rdir_cache_width, rdir_cache_height;
    4.19 +
    4.20 +	virtual void calc_matrix(Matrix4x4 *mat) const = 0;
    4.21 +
    4.22 +	Vector2 calc_sample_pos(int x, int y, int xsz, int ysz, int sample) const;
    4.23 +
    4.24 +public:
    4.25 +	Camera();
    4.26 +	Camera(const Vector3 &pos);
    4.27 +	virtual ~Camera();
    4.28 +
    4.29 +	virtual void set_fov(float vfov);
    4.30 +	virtual float get_fov() const;
    4.31 +
    4.32 +	virtual void set_position(const Vector3 &pos);
    4.33 +	virtual const Vector3 &get_position() const;
    4.34 +	virtual const Matrix4x4 &get_matrix() const;
    4.35 +
    4.36 +	virtual Ray get_primary_ray(int x, int y, int xsz, int ysz, int sample = 0) const;
    4.37 +};
    4.38 +
    4.39 +class TargetCamera : public Camera {
    4.40 +protected:
    4.41 +	Vector3 target;
    4.42 +
    4.43 +	void calc_matrix(Matrix4x4 *mat) const;
    4.44 +
    4.45 +public:
    4.46 +	TargetCamera();
    4.47 +	TargetCamera(const Vector3 &pos, const Vector3 &targ);
    4.48 +
    4.49 +	virtual void set_target(const Vector3 &targ);
    4.50 +	virtual const Vector3 &get_target() const;
    4.51 +};
    4.52 +
    4.53 +class FlyCamera : public Camera {
    4.54 +protected:
    4.55 +	Quaternion rot;
    4.56 +
    4.57 +	void calc_matrix(Matrix4x4 *mat) const;
    4.58 +
    4.59 +public:
    4.60 +	void input_move(float x, float y, float z);
    4.61 +	void input_rotate(float x, float y, float z);
    4.62 +};
    4.63 +
    4.64 +#endif	// CAMERA_H_
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/game.cc	Fri Apr 25 05:20:53 2014 +0300
     5.3 @@ -0,0 +1,180 @@
     5.4 +#include "game.h"
     5.5 +#include "opengl.h"
     5.6 +#include "camera.h"
     5.7 +#include "texture.h"
     5.8 +#include "OVR_CAPI_GL.h"
     5.9 +
    5.10 +static void draw_scene();
    5.11 +
    5.12 +static const float move_speed = 10.0f;
    5.13 +
    5.14 +static int fb_width, fb_height;
    5.15 +static FlyCamera cam;
    5.16 +static Texture floor_tex;
    5.17 +static bool keystate[256];
    5.18 +
    5.19 +bool game_init()
    5.20 +{
    5.21 +	glEnable(GL_DEPTH_TEST);
    5.22 +	glEnable(GL_CULL_FACE);
    5.23 +	glEnable(GL_LIGHTING);
    5.24 +	glEnable(GL_LIGHT0);
    5.25 +
    5.26 +	glClearColor(0.1, 0.1, 0.1, 1);
    5.27 +
    5.28 +	if(!floor_tex.load("data/tiles.png")) {
    5.29 +		return false;
    5.30 +	}
    5.31 +
    5.32 +	cam.input_move(0, 0, 5);
    5.33 +	return true;
    5.34 +}
    5.35 +
    5.36 +void game_cleanup()
    5.37 +{
    5.38 +	floor_tex.destroy();
    5.39 +}
    5.40 +
    5.41 +
    5.42 +void game_update(unsigned int msec)
    5.43 +{
    5.44 +	static unsigned int prev_msec;
    5.45 +	float dt = (msec - prev_msec) / 1000.0f;
    5.46 +	float offs = dt * move_speed;
    5.47 +	prev_msec = msec;
    5.48 +
    5.49 +	Vector3 move;
    5.50 +	float roll = 0.0f;
    5.51 +
    5.52 +	if(keystate['d'] || keystate['D']) {
    5.53 +		move.x += offs;
    5.54 +	}
    5.55 +	if(keystate['a'] || keystate['A']) {
    5.56 +		move.x -= offs;
    5.57 +	}
    5.58 +	if(keystate['s'] || keystate['S']) {
    5.59 +		move.z += offs;
    5.60 +	}
    5.61 +	if(keystate['w'] || keystate['W']) {
    5.62 +		move.z -= offs;
    5.63 +	}
    5.64 +	if(keystate['e'] || keystate['E']) {
    5.65 +		roll += dt;
    5.66 +	}
    5.67 +	if(keystate['q'] || keystate['Q']) {
    5.68 +		roll -= dt;
    5.69 +	}
    5.70 +
    5.71 +	cam.input_move(move.x, move.y, move.z);
    5.72 +	cam.input_rotate(0, 0, roll);
    5.73 +}
    5.74 +
    5.75 +void game_render(int eye)
    5.76 +{
    5.77 +	Matrix4x4 view_matrix = cam.get_matrix().inverse();
    5.78 +
    5.79 +	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    5.80 +
    5.81 +	glMatrixMode(GL_PROJECTION);
    5.82 +	glLoadIdentity();
    5.83 +	gluPerspective(60.0, (float)fb_width / (float)fb_height, 0.5, 500.0);
    5.84 +
    5.85 +	glMatrixMode(GL_MODELVIEW);
    5.86 +	glLoadIdentity();
    5.87 +	glLoadTransposeMatrixf(view_matrix[0]);
    5.88 +
    5.89 +	draw_scene();
    5.90 +}
    5.91 +
    5.92 +void game_reshape(int x, int y)
    5.93 +{
    5.94 +	glViewport(0, 0, x, y);
    5.95 +	fb_width = x;
    5.96 +	fb_height = y;
    5.97 +}
    5.98 +
    5.99 +void game_keyboard(int key, bool pressed, int x, int y)
   5.100 +{
   5.101 +	if(pressed) {
   5.102 +		switch(key) {
   5.103 +		case 27:
   5.104 +			exit(0);
   5.105 +		}
   5.106 +	}
   5.107 +
   5.108 +	if(key < 256) {
   5.109 +		keystate[key] = pressed;
   5.110 +	}
   5.111 +}
   5.112 +
   5.113 +static int prev_x, prev_y;
   5.114 +static bool bnstate[32];
   5.115 +
   5.116 +void game_mouse(int bn, bool pressed, int x, int y)
   5.117 +{
   5.118 +	bnstate[bn] = pressed;
   5.119 +	prev_x = x;
   5.120 +	prev_y = y;
   5.121 +}
   5.122 +
   5.123 +void game_motion(int x, int y)
   5.124 +{
   5.125 +	int dx = x - prev_x;
   5.126 +	int dy = y - prev_y;
   5.127 +	prev_x = x;
   5.128 +	prev_y = y;
   5.129 +
   5.130 +	if(!dx && !dy) return;
   5.131 +
   5.132 +	if(bnstate[0]) {
   5.133 +		float xrot = dy * 0.5;
   5.134 +		float yrot = dx * 0.5;
   5.135 +		cam.input_rotate(DEG_TO_RAD(xrot), 0, 0);
   5.136 +		cam.input_rotate(0, DEG_TO_RAD(yrot), 0);
   5.137 +	}
   5.138 +}
   5.139 +
   5.140 +void game_6dof_move(float x, float y, float z)
   5.141 +{
   5.142 +	cam.input_move(x, y, z);
   5.143 +}
   5.144 +
   5.145 +void game_6dof_rotate(float x, float y, float z)
   5.146 +{
   5.147 +	cam.input_rotate(x, y, z);
   5.148 +}
   5.149 +
   5.150 +static void draw_scene()
   5.151 +{
   5.152 +	glMatrixMode(GL_MODELVIEW);
   5.153 +	glTranslatef(0, -1.5, 0);
   5.154 +
   5.155 +	float lpos[] = {-20, 30, 10, 1};
   5.156 +	glLightfv(GL_LIGHT0, GL_POSITION, lpos);
   5.157 +
   5.158 +	glEnable(GL_TEXTURE_2D);
   5.159 +	floor_tex.bind();
   5.160 +
   5.161 +	glMatrixMode(GL_TEXTURE);
   5.162 +	glScalef(8, 8, 8);
   5.163 +
   5.164 +	glBegin(GL_QUADS);
   5.165 +	glNormal3f(0, 1, 0);
   5.166 +	glTexCoord2f(0, 0); glVertex3f(-25, 0, 25);
   5.167 +	glTexCoord2f(1, 0); glVertex3f(25, 0, 25);
   5.168 +	glTexCoord2f(1, 1); glVertex3f(25, 0, -25);
   5.169 +	glTexCoord2f(0, 1); glVertex3f(-25, 0, -25);
   5.170 +	glEnd();
   5.171 +	glDisable(GL_TEXTURE_2D);
   5.172 +	glLoadIdentity();
   5.173 +
   5.174 +	glMatrixMode(GL_MODELVIEW);
   5.175 +	glPushMatrix();
   5.176 +	glTranslatef(0, 0.75, 0);
   5.177 +
   5.178 +	glFrontFace(GL_CW);
   5.179 +	glutSolidTeapot(1.0);
   5.180 +	glFrontFace(GL_CCW);
   5.181 +
   5.182 +	glPopMatrix();
   5.183 +}
   5.184 \ No newline at end of file
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/game.h	Fri Apr 25 05:20:53 2014 +0300
     6.3 @@ -0,0 +1,18 @@
     6.4 +#ifndef GAME_H_
     6.5 +#define GAME_H_
     6.6 +
     6.7 +bool game_init();
     6.8 +void game_cleanup();
     6.9 +
    6.10 +void game_update(unsigned int msec);
    6.11 +void game_render(int eye);
    6.12 +
    6.13 +void game_reshape(int x, int y);
    6.14 +void game_keyboard(int key, bool pressed, int x, int y);
    6.15 +void game_mouse(int bn, bool pressed, int x, int y);
    6.16 +void game_motion(int x, int y);
    6.17 +
    6.18 +void game_6dof_move(float x, float y, float z);
    6.19 +void game_6dof_rotate(float x, float y, float z);
    6.20 +
    6.21 +#endif	// GAME_H_
    6.22 \ No newline at end of file
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/image.cc	Fri Apr 25 05:20:53 2014 +0300
     7.3 @@ -0,0 +1,94 @@
     7.4 +#include <string.h>
     7.5 +#include "imago2.h"
     7.6 +#include "image.h"
     7.7 +
     7.8 +Image::Image()
     7.9 +{
    7.10 +	pixels = 0;
    7.11 +	own_pixels = true;
    7.12 +	width = height = 0;
    7.13 +}
    7.14 +
    7.15 +Image::~Image()
    7.16 +{
    7.17 +	destroy();
    7.18 +}
    7.19 +
    7.20 +Image::Image(const Image &img)
    7.21 +{
    7.22 +	pixels = 0;
    7.23 +	own_pixels = false;
    7.24 +
    7.25 +	create(img.width, img.height, img.pixels);
    7.26 +}
    7.27 +
    7.28 +Image &Image::operator =(const Image &img)
    7.29 +{
    7.30 +	if(this != &img) {
    7.31 +		destroy();
    7.32 +		create(img.width, img.height, img.pixels);
    7.33 +	}
    7.34 +	return *this;
    7.35 +}
    7.36 +
    7.37 +void Image::create(int xsz, int ysz, unsigned char *pixels)
    7.38 +{
    7.39 +	destroy();
    7.40 +
    7.41 +	this->pixels = new unsigned char[xsz * ysz * 4];
    7.42 +	if(pixels) {
    7.43 +		memcpy(this->pixels, pixels, xsz * ysz * 4);
    7.44 +	} else {
    7.45 +		memset(this->pixels, 0, xsz * ysz * 4);
    7.46 +	}
    7.47 +	width = xsz;
    7.48 +	height = ysz;
    7.49 +	own_pixels = true;
    7.50 +}
    7.51 +
    7.52 +void Image::destroy()
    7.53 +{
    7.54 +	if(own_pixels) {
    7.55 +		delete [] pixels;
    7.56 +	}
    7.57 +	pixels = 0;
    7.58 +	width = height = 0;
    7.59 +	own_pixels = true;
    7.60 +}
    7.61 +
    7.62 +int Image::get_width() const
    7.63 +{
    7.64 +	return width;
    7.65 +}
    7.66 +
    7.67 +int Image::get_height() const
    7.68 +{
    7.69 +	return height;
    7.70 +}
    7.71 +
    7.72 +void Image::set_pixels(int xsz, int ysz, unsigned char *pixels)
    7.73 +{
    7.74 +	destroy();
    7.75 +
    7.76 +	this->pixels = pixels;
    7.77 +	width = xsz;
    7.78 +	height = ysz;
    7.79 +	own_pixels = false;
    7.80 +}
    7.81 +
    7.82 +unsigned char *Image::get_pixels() const
    7.83 +{
    7.84 +	return pixels;
    7.85 +}
    7.86 +
    7.87 +bool Image::load(const char *fname)
    7.88 +{
    7.89 +	int xsz, ysz;
    7.90 +	unsigned char *pix = (unsigned char*)img_load_pixels(fname, &xsz, &ysz);
    7.91 +	if(!pix) {
    7.92 +		return false;
    7.93 +	}
    7.94 +
    7.95 +	create(xsz, ysz, pix);
    7.96 +	return true;
    7.97 +}
    7.98 \ No newline at end of file
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/image.h	Fri Apr 25 05:20:53 2014 +0300
     8.3 @@ -0,0 +1,29 @@
     8.4 +#ifndef IMAGE_H_
     8.5 +#define IMAGE_H_
     8.6 +
     8.7 +class Image {
     8.8 +private:
     8.9 +	int width, height;
    8.10 +	unsigned char *pixels;
    8.11 +	bool own_pixels;
    8.12 +
    8.13 +public:
    8.14 +	Image();
    8.15 +	~Image();
    8.16 +
    8.17 +	Image(const Image &img);
    8.18 +	Image &operator =(const Image &img);
    8.19 +
    8.20 +	void create(int xsz, int ysz, unsigned char *pix = 0);
    8.21 +	void destroy();
    8.22 +
    8.23 +	int get_width() const;
    8.24 +	int get_height() const;
    8.25 +
    8.26 +	void set_pixels(int xsz, int ysz, unsigned char *pix);
    8.27 +	unsigned char *get_pixels() const;
    8.28 +
    8.29 +	bool load(const char *fname);
    8.30 +};
    8.31 +
    8.32 +#endif	// IMAGE_H_
    8.33 \ No newline at end of file
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/main.cc	Fri Apr 25 05:20:53 2014 +0300
     9.3 @@ -0,0 +1,111 @@
     9.4 +#include <stdio.h>
     9.5 +#include <stdlib.h>
     9.6 +#include "opengl.h"
     9.7 +#include "game.h"
     9.8 +
     9.9 +static bool init();
    9.10 +static void cleanup();
    9.11 +
    9.12 +static void display();
    9.13 +static void idle();
    9.14 +static void reshape(int x, int y);
    9.15 +static void keyb(unsigned char key, int x, int y);
    9.16 +static void keyb_up(unsigned char key, int x, int y);
    9.17 +static void mouse(int bn, int st, int x, int y);
    9.18 +static void motion(int x, int y);
    9.19 +static void sball_motion(int x, int y, int z);
    9.20 +static void sball_rotate(int x, int y, int z);
    9.21 +
    9.22 +int main(int argc, char **argv)
    9.23 +{
    9.24 +	glutInitWindowSize(1024, 600);
    9.25 +	glutInit(&argc, argv);
    9.26 +	glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
    9.27 +	glutCreateWindow("VR Chess");
    9.28 +
    9.29 +	glutDisplayFunc(display);
    9.30 +	glutIdleFunc(idle);
    9.31 +	glutReshapeFunc(reshape);
    9.32 +	glutKeyboardFunc(keyb);
    9.33 +	glutKeyboardUpFunc(keyb_up);
    9.34 +	glutMouseFunc(mouse);
    9.35 +	glutMotionFunc(motion);
    9.36 +	glutSpaceballMotionFunc(sball_motion);
    9.37 +	glutSpaceballRotateFunc(sball_rotate);
    9.38 +
    9.39 +	if(!init()) {
    9.40 +		return 1;
    9.41 +	}
    9.42 +	atexit(cleanup);
    9.43 +
    9.44 +	glutMainLoop();
    9.45 +	return 0;
    9.46 +}
    9.47 +
    9.48 +static bool init()
    9.49 +{
    9.50 +	glewInit();
    9.51 +
    9.52 +	if(!game_init()) {
    9.53 +		return false;
    9.54 +	}
    9.55 +	return true;
    9.56 +}
    9.57 +
    9.58 +static void cleanup()
    9.59 +{
    9.60 +	game_cleanup();
    9.61 +}
    9.62 +
    9.63 +static void display()
    9.64 +{
    9.65 +	unsigned int msec = glutGet(GLUT_ELAPSED_TIME);
    9.66 +
    9.67 +	game_update(msec);
    9.68 +	game_render(0);
    9.69 +
    9.70 +	glutSwapBuffers();
    9.71 +}
    9.72 +
    9.73 +static void idle()
    9.74 +{
    9.75 +	glutPostRedisplay();
    9.76 +}
    9.77 +
    9.78 +static void reshape(int x, int y)
    9.79 +{
    9.80 +	game_reshape(x, y);
    9.81 +}
    9.82 +
    9.83 +static void keyb(unsigned char key, int x, int y)
    9.84 +{
    9.85 +	game_keyboard(key, true, x, y);
    9.86 +}
    9.87 +
    9.88 +static void keyb_up(unsigned char key, int x, int y)
    9.89 +{
    9.90 +	game_keyboard(key, false, x, y);
    9.91 +}
    9.92 +
    9.93 +static void mouse(int bn, int st, int x, int y)
    9.94 +{
    9.95 +	game_mouse(bn - GLUT_LEFT_BUTTON, st == GLUT_DOWN, x, y);
    9.96 +}
    9.97 +
    9.98 +static void motion(int x, int y)
    9.99 +{
   9.100 +	game_motion(x, y);
   9.101 +}
   9.102 +
   9.103 +#define SBALL_MOVE_SCALE	0.00025
   9.104 +#define SBALL_ROT_SCALE		0.01
   9.105 +
   9.106 +static void sball_motion(int x, int y, int z)
   9.107 +{
   9.108 +	game_6dof_move(x * SBALL_MOVE_SCALE, y * SBALL_MOVE_SCALE, z * SBALL_MOVE_SCALE);
   9.109 +}
   9.110 +
   9.111 +static void sball_rotate(int x, int y, int z)
   9.112 +{
   9.113 +	game_6dof_rotate(x * SBALL_ROT_SCALE, y * SBALL_ROT_SCALE, z * SBALL_ROT_SCALE);
   9.114 +}
   9.115 \ No newline at end of file
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/src/opengl.cc	Fri Apr 25 05:20:53 2014 +0300
    10.3 @@ -0,0 +1,61 @@
    10.4 +#include "opengl.h"
    10.5 +#include <vmath/vmath.h>
    10.6 +
    10.7 +void load_matrix(const Matrix4x4 &m)
    10.8 +{
    10.9 +#ifdef SINGLE_PRECISION_MATH
   10.10 +	if(glLoadTransposeMatrixfARB) {
   10.11 +		glLoadTransposeMatrixfARB((float*)&m);
   10.12 +	} else {
   10.13 +		Matrix4x4 tmat = m.transposed();
   10.14 +		glLoadMatrixf((float*)&tmat);
   10.15 +	}
   10.16 +#else
   10.17 +	if(glLoadTransposeMatrixdARB) {
   10.18 +		glLoadTransposeMatrixdARB((double*)&m);
   10.19 +	} else {
   10.20 +		Matrix4x4 tmat = m.transposed();
   10.21 +		glLoadMatrixd((double*)&tmat);
   10.22 +	}
   10.23 +#endif
   10.24 +}
   10.25 +
   10.26 +void mult_matrix(const Matrix4x4 &m)
   10.27 +{
   10.28 +#ifdef SINGLE_PRECISION_MATH
   10.29 +	if(glMultTransposeMatrixfARB) {
   10.30 +		glMultTransposeMatrixfARB((float*)&m);
   10.31 +	} else {
   10.32 +		Matrix4x4 tmat = m.transposed();
   10.33 +		glMultMatrixf((float*)&tmat);
   10.34 +	}
   10.35 +#else
   10.36 +	if(glMultTransposeMatrixdARB) {
   10.37 +		glMultTransposeMatrixdARB((double*)&m);
   10.38 +	} else {
   10.39 +		Matrix4x4 tmat = m.transposed();
   10.40 +		glMultMatrixd((double*)&tmat);
   10.41 +	}
   10.42 +#endif
   10.43 +}
   10.44 +
   10.45 +const char *strglerr(int err)
   10.46 +{
   10.47 +	static const char *errnames[] = {
   10.48 +		"GL_INVALID_ENUM",
   10.49 +		"GL_INVALID_VALUE",
   10.50 +		"GL_INVALID_OPERATION",
   10.51 +		"GL_STACK_OVERFLOW",
   10.52 +		"GL_STACK_UNDERFLOW",
   10.53 +		"GL_OUT_OF_MEMORY",
   10.54 +		"GL_INVALID_FRAMEBUFFER_OPERATION"
   10.55 +	};
   10.56 +
   10.57 +	if(!err) {
   10.58 +		return "GL_NO_ERROR";
   10.59 +	}
   10.60 +	if(err < GL_INVALID_ENUM || err > GL_OUT_OF_MEMORY) {
   10.61 +		return "<invalid gl error>";
   10.62 +	}
   10.63 +	return errnames[err - GL_INVALID_ENUM];
   10.64 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/opengl.h	Fri Apr 25 05:20:53 2014 +0300
    11.3 @@ -0,0 +1,29 @@
    11.4 +#ifndef OPENGL_H_
    11.5 +#define OPENGL_H_
    11.6 +
    11.7 +#include <GL/glew.h>
    11.8 +
    11.9 +#ifndef __APPLE__
   11.10 +#include <GL/glut.h>
   11.11 +#else
   11.12 +#include <GLUT/glut.h>
   11.13 +#endif
   11.14 +
   11.15 +#define CHECKGLERR	\
   11.16 +	do { \
   11.17 +		int err = glGetError(); \
   11.18 +		if(err) { \
   11.19 +			fprintf(stderr, "%s:%d: OpenGL error 0x%x: %s\n", __FILE__, __LINE__, err, strglerr(err)); \
   11.20 +			abort(); \
   11.21 +		} \
   11.22 +	} while(0)
   11.23 +
   11.24 +
   11.25 +class Matrix4x4;
   11.26 +
   11.27 +void load_matrix(const Matrix4x4 &m);
   11.28 +void mult_matrix(const Matrix4x4 &m);
   11.29 +
   11.30 +const char *strglerr(int err);
   11.31 +
   11.32 +#endif	/* OPENGL_H_ */
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/sdr.c	Fri Apr 25 05:20:53 2014 +0300
    12.3 @@ -0,0 +1,427 @@
    12.4 +/*
    12.5 +Printblobs - halftoning display hack
    12.6 +Copyright (C) 2013  John Tsiombikas <nuclear@member.fsf.org>
    12.7 +
    12.8 +This program is free software: you can redistribute it and/or modify
    12.9 +it under the terms of the GNU General Public License as published by
   12.10 +the Free Software Foundation, either version 3 of the License, or
   12.11 +(at your option) any later version.
   12.12 +
   12.13 +This program is distributed in the hope that it will be useful,
   12.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12.16 +GNU General Public License for more details.
   12.17 +
   12.18 +You should have received a copy of the GNU General Public License
   12.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   12.20 +*/
   12.21 +#include <stdio.h>
   12.22 +#include <stdlib.h>
   12.23 +#include <string.h>
   12.24 +#include <errno.h>
   12.25 +#include <stdarg.h>
   12.26 +#include <assert.h>
   12.27 +#include <GL/glew.h>
   12.28 +
   12.29 +#if defined(unix) || defined(__unix__)
   12.30 +#include <unistd.h>
   12.31 +#include <sys/stat.h>
   12.32 +#endif	/* unix */
   12.33 +
   12.34 +#include "sdr.h"
   12.35 +
   12.36 +static const char *sdrtypestr(unsigned int sdrtype);
   12.37 +
   12.38 +unsigned int create_vertex_shader(const char *src)
   12.39 +{
   12.40 +	return create_shader(src, GL_VERTEX_SHADER);
   12.41 +}
   12.42 +
   12.43 +unsigned int create_pixel_shader(const char *src)
   12.44 +{
   12.45 +	return create_shader(src, GL_FRAGMENT_SHADER);
   12.46 +}
   12.47 +
   12.48 +unsigned int create_tessctl_shader(const char *src)
   12.49 +{
   12.50 +	return create_shader(src, GL_TESS_CONTROL_SHADER);
   12.51 +}
   12.52 +
   12.53 +unsigned int create_tesseval_shader(const char *src)
   12.54 +{
   12.55 +	return create_shader(src, GL_TESS_EVALUATION_SHADER);
   12.56 +}
   12.57 +
   12.58 +unsigned int create_geometry_shader(const char *src)
   12.59 +{
   12.60 +	return create_shader(src, GL_GEOMETRY_SHADER);
   12.61 +}
   12.62 +
   12.63 +unsigned int create_shader(const char *src, unsigned int sdr_type)
   12.64 +{
   12.65 +	unsigned int sdr;
   12.66 +	int success, info_len;
   12.67 +	char *info_str = 0;
   12.68 +	GLenum err;
   12.69 +
   12.70 +	sdr = glCreateShader(sdr_type);
   12.71 +	assert(glGetError() == GL_NO_ERROR);
   12.72 +	glShaderSource(sdr, 1, &src, 0);
   12.73 +	err = glGetError();
   12.74 +	assert(err == GL_NO_ERROR);
   12.75 +	glCompileShader(sdr);
   12.76 +	assert(glGetError() == GL_NO_ERROR);
   12.77 +
   12.78 +	glGetShaderiv(sdr, GL_COMPILE_STATUS, &success);
   12.79 +	assert(glGetError() == GL_NO_ERROR);
   12.80 +	glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len);
   12.81 +	assert(glGetError() == GL_NO_ERROR);
   12.82 +
   12.83 +	if(info_len) {
   12.84 +		if((info_str = malloc(info_len + 1))) {
   12.85 +			glGetShaderInfoLog(sdr, info_len, 0, info_str);
   12.86 +			assert(glGetError() == GL_NO_ERROR);
   12.87 +		}
   12.88 +	}
   12.89 +
   12.90 +	if(success) {
   12.91 +		fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str);
   12.92 +	} else {
   12.93 +		fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str);
   12.94 +		glDeleteShader(sdr);
   12.95 +		sdr = 0;
   12.96 +	}
   12.97 +
   12.98 +	free(info_str);
   12.99 +	return sdr;
  12.100 +}
  12.101 +
  12.102 +void free_shader(unsigned int sdr)
  12.103 +{
  12.104 +	glDeleteShader(sdr);
  12.105 +}
  12.106 +
  12.107 +unsigned int load_vertex_shader(const char *fname)
  12.108 +{
  12.109 +	return load_shader(fname, GL_VERTEX_SHADER);
  12.110 +}
  12.111 +
  12.112 +unsigned int load_pixel_shader(const char *fname)
  12.113 +{
  12.114 +	return load_shader(fname, GL_FRAGMENT_SHADER);
  12.115 +}
  12.116 +
  12.117 +unsigned int load_tessctl_shader(const char *fname)
  12.118 +{
  12.119 +	return load_shader(fname, GL_TESS_CONTROL_SHADER);
  12.120 +}
  12.121 +
  12.122 +unsigned int load_tesseval_shader(const char *fname)
  12.123 +{
  12.124 +	return load_shader(fname, GL_TESS_EVALUATION_SHADER);
  12.125 +}
  12.126 +
  12.127 +unsigned int load_geometry_shader(const char *fname)
  12.128 +{
  12.129 +	return load_shader(fname, GL_GEOMETRY_SHADER);
  12.130 +}
  12.131 +
  12.132 +unsigned int load_shader(const char *fname, unsigned int sdr_type)
  12.133 +{
  12.134 +#if defined(unix) || defined(__unix__)
  12.135 +	struct stat st;
  12.136 +#endif
  12.137 +	unsigned int sdr;
  12.138 +	size_t filesize;
  12.139 +	FILE *fp;
  12.140 +	char *src;
  12.141 +
  12.142 +	if(!(fp = fopen(fname, "r"))) {
  12.143 +		fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno));
  12.144 +		return 0;
  12.145 +	}
  12.146 +
  12.147 +#if defined(unix) || defined(__unix__)
  12.148 +	fstat(fileno(fp), &st);
  12.149 +	filesize = st.st_size;
  12.150 +#else
  12.151 +	fseek(fp, 0, SEEK_END);
  12.152 +	filesize = ftell(fp);
  12.153 +	fseek(fp, 0, SEEK_SET);
  12.154 +#endif	/* unix */
  12.155 +
  12.156 +	if(!(src = malloc(filesize + 1))) {
  12.157 +		fclose(fp);
  12.158 +		return 0;
  12.159 +	}
  12.160 +	fread(src, 1, filesize, fp);
  12.161 +	src[filesize] = 0;
  12.162 +	fclose(fp);
  12.163 +
  12.164 +	fprintf(stderr, "compiling %s shader: %s... ", sdrtypestr(sdr_type), fname);
  12.165 +	sdr = create_shader(src, sdr_type);
  12.166 +
  12.167 +	free(src);
  12.168 +	return sdr;
  12.169 +}
  12.170 +
  12.171 +
  12.172 +unsigned int get_vertex_shader(const char *fname)
  12.173 +{
  12.174 +	return get_shader(fname, GL_VERTEX_SHADER);
  12.175 +}
  12.176 +
  12.177 +unsigned int get_pixel_shader(const char *fname)
  12.178 +{
  12.179 +	return get_shader(fname, GL_FRAGMENT_SHADER);
  12.180 +}
  12.181 +
  12.182 +unsigned int get_tessctl_shader(const char *fname)
  12.183 +{
  12.184 +	return get_shader(fname, GL_TESS_CONTROL_SHADER);
  12.185 +}
  12.186 +
  12.187 +unsigned int get_tesseval_shader(const char *fname)
  12.188 +{
  12.189 +	return get_shader(fname, GL_TESS_EVALUATION_SHADER);
  12.190 +}
  12.191 +
  12.192 +unsigned int get_geometry_shader(const char *fname)
  12.193 +{
  12.194 +	return get_shader(fname, GL_GEOMETRY_SHADER);
  12.195 +}
  12.196 +
  12.197 +unsigned int get_shader(const char *fname, unsigned int sdr_type)
  12.198 +{
  12.199 +	unsigned int sdr;
  12.200 +	if(!(sdr = load_shader(fname, sdr_type))) {
  12.201 +		return 0;
  12.202 +	}
  12.203 +	return sdr;
  12.204 +}
  12.205 +
  12.206 +
  12.207 +/* ---- gpu programs ---- */
  12.208 +
  12.209 +unsigned int create_program(void)
  12.210 +{
  12.211 +	unsigned int prog = glCreateProgram();
  12.212 +	assert(glGetError() == GL_NO_ERROR);
  12.213 +	return prog;
  12.214 +}
  12.215 +
  12.216 +unsigned int create_program_link(unsigned int sdr0, ...)
  12.217 +{
  12.218 +	unsigned int prog, sdr;
  12.219 +	va_list ap;
  12.220 +
  12.221 +	if(!(prog = create_program())) {
  12.222 +		return 0;
  12.223 +	}
  12.224 +
  12.225 +	attach_shader(prog, sdr0);
  12.226 +	if(glGetError()) {
  12.227 +		return 0;
  12.228 +	}
  12.229 +
  12.230 +	va_start(ap, sdr0);
  12.231 +	while((sdr = va_arg(ap, unsigned int))) {
  12.232 +		attach_shader(prog, sdr);
  12.233 +		if(glGetError()) {
  12.234 +			return 0;
  12.235 +		}
  12.236 +	}
  12.237 +	va_end(ap);
  12.238 +
  12.239 +	if(link_program(prog) == -1) {
  12.240 +		free_program(prog);
  12.241 +		return 0;
  12.242 +	}
  12.243 +	return prog;
  12.244 +}
  12.245 +
  12.246 +unsigned int create_program_load(const char *vfile, const char *pfile)
  12.247 +{
  12.248 +	unsigned int vs = 0, ps = 0;
  12.249 +
  12.250 +	if(vfile && *vfile && !(vs = get_vertex_shader(vfile))) {
  12.251 +		return 0;
  12.252 +	}
  12.253 +	if(pfile && *pfile && !(ps = get_pixel_shader(pfile))) {
  12.254 +		return 0;
  12.255 +	}
  12.256 +	return create_program_link(vs, ps, 0);
  12.257 +}
  12.258 +
  12.259 +void free_program(unsigned int sdr)
  12.260 +{
  12.261 +	glDeleteProgram(sdr);
  12.262 +}
  12.263 +
  12.264 +void attach_shader(unsigned int prog, unsigned int sdr)
  12.265 +{
  12.266 +	glAttachShader(prog, sdr);
  12.267 +	assert(glGetError() == GL_NO_ERROR);
  12.268 +}
  12.269 +
  12.270 +int link_program(unsigned int prog)
  12.271 +{
  12.272 +	int linked, info_len, retval = 0;
  12.273 +	char *info_str = 0;
  12.274 +
  12.275 +	glLinkProgram(prog);
  12.276 +	assert(glGetError() == GL_NO_ERROR);
  12.277 +	glGetProgramiv(prog, GL_LINK_STATUS, &linked);
  12.278 +	assert(glGetError() == GL_NO_ERROR);
  12.279 +	glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len);
  12.280 +	assert(glGetError() == GL_NO_ERROR);
  12.281 +
  12.282 +	if(info_len) {
  12.283 +		if((info_str = malloc(info_len + 1))) {
  12.284 +			glGetProgramInfoLog(prog, info_len, 0, info_str);
  12.285 +			assert(glGetError() == GL_NO_ERROR);
  12.286 +		}
  12.287 +	}
  12.288 +
  12.289 +	if(linked) {
  12.290 +		fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str);
  12.291 +	} else {
  12.292 +		fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str);
  12.293 +		retval = -1;
  12.294 +	}
  12.295 +
  12.296 +	free(info_str);
  12.297 +	return retval;
  12.298 +}
  12.299 +
  12.300 +int bind_program(unsigned int prog)
  12.301 +{
  12.302 +	GLenum err;
  12.303 +
  12.304 +	glUseProgram(prog);
  12.305 +	if(prog && (err = glGetError()) != GL_NO_ERROR) {
  12.306 +		/* maybe the program is not linked, try linking first */
  12.307 +		if(err == GL_INVALID_OPERATION) {
  12.308 +			if(link_program(prog) == -1) {
  12.309 +				return -1;
  12.310 +			}
  12.311 +			glUseProgram(prog);
  12.312 +			return glGetError() == GL_NO_ERROR ? 0 : -1;
  12.313 +		}
  12.314 +		return -1;
  12.315 +	}
  12.316 +	return 0;
  12.317 +}
  12.318 +
  12.319 +/* ugly but I'm not going to write the same bloody code over and over */
  12.320 +#define BEGIN_UNIFORM_CODE \
  12.321 +	int loc, curr_prog; \
  12.322 +	glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \
  12.323 +	if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { \
  12.324 +		return -1; \
  12.325 +	} \
  12.326 +	if((loc = glGetUniformLocation(prog, name)) != -1)
  12.327 +
  12.328 +#define END_UNIFORM_CODE \
  12.329 +	if((unsigned int)curr_prog != prog) { \
  12.330 +		bind_program(curr_prog); \
  12.331 +	} \
  12.332 +	return loc == -1 ? -1 : 0
  12.333 +
  12.334 +int set_uniform_int(unsigned int prog, const char *name, int val)
  12.335 +{
  12.336 +	BEGIN_UNIFORM_CODE {
  12.337 +		glUniform1i(loc, val);
  12.338 +	}
  12.339 +	END_UNIFORM_CODE;
  12.340 +}
  12.341 +
  12.342 +int set_uniform_float(unsigned int prog, const char *name, float val)
  12.343 +{
  12.344 +	BEGIN_UNIFORM_CODE {
  12.345 +		glUniform1f(loc, val);
  12.346 +	}
  12.347 +	END_UNIFORM_CODE;
  12.348 +}
  12.349 +
  12.350 +int set_uniform_float2(unsigned int prog, const char *name, float x, float y)
  12.351 +{
  12.352 +	BEGIN_UNIFORM_CODE {
  12.353 +		glUniform2f(loc, x, y);
  12.354 +	}
  12.355 +	END_UNIFORM_CODE;
  12.356 +}
  12.357 +
  12.358 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z)
  12.359 +{
  12.360 +	BEGIN_UNIFORM_CODE {
  12.361 +		glUniform3f(loc, x, y, z);
  12.362 +	}
  12.363 +	END_UNIFORM_CODE;
  12.364 +}
  12.365 +
  12.366 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w)
  12.367 +{
  12.368 +	BEGIN_UNIFORM_CODE {
  12.369 +		glUniform4f(loc, x, y, z, w);
  12.370 +	}
  12.371 +	END_UNIFORM_CODE;
  12.372 +}
  12.373 +
  12.374 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat)
  12.375 +{
  12.376 +	BEGIN_UNIFORM_CODE {
  12.377 +		glUniformMatrix4fv(loc, 1, GL_FALSE, mat);
  12.378 +	}
  12.379 +	END_UNIFORM_CODE;
  12.380 +}
  12.381 +
  12.382 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat)
  12.383 +{
  12.384 +	BEGIN_UNIFORM_CODE {
  12.385 +		glUniformMatrix4fv(loc, 1, GL_TRUE, mat);
  12.386 +	}
  12.387 +	END_UNIFORM_CODE;
  12.388 +}
  12.389 +
  12.390 +int get_attrib_loc(unsigned int prog, const char *name)
  12.391 +{
  12.392 +	int loc, curr_prog;
  12.393 +
  12.394 +	glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog);
  12.395 +	if((unsigned int)curr_prog != prog && bind_program(prog) == -1) {
  12.396 +		return -1;
  12.397 +	}
  12.398 +
  12.399 +	loc = glGetAttribLocation(prog, (char*)name);
  12.400 +
  12.401 +	if((unsigned int)curr_prog != prog) {
  12.402 +		bind_program(curr_prog);
  12.403 +	}
  12.404 +	return loc;
  12.405 +}
  12.406 +
  12.407 +void set_attrib_float3(int attr_loc, float x, float y, float z)
  12.408 +{
  12.409 +	glVertexAttrib3f(attr_loc, x, y, z);
  12.410 +}
  12.411 +
  12.412 +static const char *sdrtypestr(unsigned int sdrtype)
  12.413 +{
  12.414 +	switch(sdrtype) {
  12.415 +	case GL_VERTEX_SHADER:
  12.416 +		return "vertex";
  12.417 +	case GL_FRAGMENT_SHADER:
  12.418 +		return "pixel";
  12.419 +	case GL_TESS_CONTROL_SHADER:
  12.420 +		return "tessellation control";
  12.421 +	case GL_TESS_EVALUATION_SHADER:
  12.422 +		return "tessellation evaluation";
  12.423 +	case GL_GEOMETRY_SHADER:
  12.424 +		return "geometry";
  12.425 +
  12.426 +	default:
  12.427 +		break;
  12.428 +	}
  12.429 +	return "<unknown>";
  12.430 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/sdr.h	Fri Apr 25 05:20:53 2014 +0300
    13.3 @@ -0,0 +1,76 @@
    13.4 +/*
    13.5 +Printblobs - halftoning display hack
    13.6 +Copyright (C) 2013  John Tsiombikas <nuclear@member.fsf.org>
    13.7 +
    13.8 +This program is free software: you can redistribute it and/or modify
    13.9 +it under the terms of the GNU General Public License as published by
   13.10 +the Free Software Foundation, either version 3 of the License, or
   13.11 +(at your option) any later version.
   13.12 +
   13.13 +This program is distributed in the hope that it will be useful,
   13.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13.16 +GNU General Public License for more details.
   13.17 +
   13.18 +You should have received a copy of the GNU General Public License
   13.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
   13.20 +*/
   13.21 +#ifndef SDR_H_
   13.22 +#define SDR_H_
   13.23 +
   13.24 +#ifdef __cplusplus
   13.25 +extern "C" {
   13.26 +#endif	/* __cplusplus */
   13.27 +
   13.28 +/* ---- shaders ---- */
   13.29 +unsigned int create_vertex_shader(const char *src);
   13.30 +unsigned int create_pixel_shader(const char *src);
   13.31 +unsigned int create_tessctl_shader(const char *src);
   13.32 +unsigned int create_tesseval_shader(const char *src);
   13.33 +unsigned int create_geometry_shader(const char *src);
   13.34 +unsigned int create_shader(const char *src, unsigned int sdr_type);
   13.35 +void free_shader(unsigned int sdr);
   13.36 +
   13.37 +unsigned int load_vertex_shader(const char *fname);
   13.38 +unsigned int load_pixel_shader(const char *fname);
   13.39 +unsigned int load_tessctl_shader(const char *fname);
   13.40 +unsigned int load_tesseval_shader(const char *fname);
   13.41 +unsigned int load_geometry_shader(const char *fname);
   13.42 +unsigned int load_shader(const char *src, unsigned int sdr_type);
   13.43 +
   13.44 +unsigned int get_vertex_shader(const char *fname);
   13.45 +unsigned int get_pixel_shader(const char *fname);
   13.46 +unsigned int get_tessctl_shader(const char *fname);
   13.47 +unsigned int get_tesseval_shader(const char *fname);
   13.48 +unsigned int get_geometry_shader(const char *fname);
   13.49 +unsigned int get_shader(const char *fname, unsigned int sdr_type);
   13.50 +
   13.51 +int add_shader(const char *fname, unsigned int sdr);
   13.52 +int remove_shader(const char *fname);
   13.53 +
   13.54 +/* ---- gpu programs ---- */
   13.55 +unsigned int create_program(void);
   13.56 +unsigned int create_program_link(unsigned int sdr0, ...);
   13.57 +unsigned int create_program_load(const char *vfile, const char *pfile);
   13.58 +void free_program(unsigned int sdr);
   13.59 +
   13.60 +void attach_shader(unsigned int prog, unsigned int sdr);
   13.61 +int link_program(unsigned int prog);
   13.62 +int bind_program(unsigned int prog);
   13.63 +
   13.64 +int set_uniform_int(unsigned int prog, const char *name, int val);
   13.65 +int set_uniform_float(unsigned int prog, const char *name, float val);
   13.66 +int set_uniform_float2(unsigned int prog, const char *name, float x, float y);
   13.67 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z);
   13.68 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w);
   13.69 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat);
   13.70 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat);
   13.71 +
   13.72 +int get_attrib_loc(unsigned int prog, const char *name);
   13.73 +void set_attrib_float3(int attr_loc, float x, float y, float z);
   13.74 +
   13.75 +#ifdef __cplusplus
   13.76 +}
   13.77 +#endif	/* __cplusplus */
   13.78 +
   13.79 +#endif	/* SDR_H_ */
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/src/texture.cc	Fri Apr 25 05:20:53 2014 +0300
    14.3 @@ -0,0 +1,77 @@
    14.4 +#include "texture.h"
    14.5 +#include "opengl.h"
    14.6 +
    14.7 +Texture::Texture()
    14.8 +{
    14.9 +	tex = 0;
   14.10 +	type = GL_TEXTURE_2D;
   14.11 +}
   14.12 +
   14.13 +Texture::~Texture()
   14.14 +{
   14.15 +	destroy();
   14.16 +}
   14.17 +
   14.18 +void Texture::create2d(int xsz, int ysz)
   14.19 +{
   14.20 +	destroy();
   14.21 +
   14.22 +	type = GL_TEXTURE_2D;
   14.23 +	img.create(xsz, ysz);
   14.24 +
   14.25 +	if(!tex) {
   14.26 +		glGenTextures(1, &tex);
   14.27 +	}
   14.28 +	glBindTexture(type, tex);
   14.29 +	glTexParameteri(type, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   14.30 +	glTexParameteri(type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   14.31 +	glTexImage2D(type, 0, GL_RGBA, xsz, ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
   14.32 +}
   14.33 +
   14.34 +void Texture::destroy()
   14.35 +{
   14.36 +	if(tex) {
   14.37 +		glDeleteTextures(1, &tex);
   14.38 +	}
   14.39 +}
   14.40 +
   14.41 +void Texture::set_image(const Image &img)
   14.42 +{
   14.43 +	this->img = img;
   14.44 +	create2d(img.get_width(), img.get_height());
   14.45 +
   14.46 +	glTexSubImage2D(type, 0, 0, 0, img.get_width(), img.get_height(),
   14.47 +			GL_RGBA, GL_UNSIGNED_BYTE, img.get_pixels());
   14.48 +}
   14.49 +
   14.50 +Image &Texture::get_image()
   14.51 +{
   14.52 +	return img;
   14.53 +}
   14.54 +
   14.55 +const Image &Texture::get_image() const
   14.56 +{
   14.57 +	return img;
   14.58 +}
   14.59 +
   14.60 +unsigned int Texture::get_texture_id() const
   14.61 +{
   14.62 +	return tex;
   14.63 +}
   14.64 +
   14.65 +void Texture::bind(int tunit) const
   14.66 +{
   14.67 +	glActiveTextureARB(GL_TEXTURE0_ARB + tunit);
   14.68 +	glBindTexture(type, tex);
   14.69 +	glActiveTextureARB(GL_TEXTURE0_ARB);
   14.70 +}
   14.71 +
   14.72 +bool Texture::load(const char *fname)
   14.73 +{
   14.74 +	Image image;
   14.75 +	if(!image.load(fname)) {
   14.76 +		return false;
   14.77 +	}
   14.78 +	set_image(image);
   14.79 +	return true;
   14.80 +}
   14.81 \ No newline at end of file
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/src/texture.h	Fri Apr 25 05:20:53 2014 +0300
    15.3 @@ -0,0 +1,29 @@
    15.4 +#ifndef TEXTURE_H_
    15.5 +#define TEXTURE_H_
    15.6 +
    15.7 +#include "image.h"
    15.8 +
    15.9 +class Texture {
   15.10 +private:
   15.11 +	Image img;
   15.12 +	unsigned int tex;
   15.13 +	unsigned int type;
   15.14 +
   15.15 +public:
   15.16 +	Texture();
   15.17 +	~Texture();
   15.18 +
   15.19 +	void create2d(int xsz, int ysz);
   15.20 +	void destroy();
   15.21 +
   15.22 +	void set_image(const Image &img);
   15.23 +	Image &get_image();
   15.24 +	const Image &get_image() const;
   15.25 +
   15.26 +	unsigned int get_texture_id() const;
   15.27 +	void bind(int tunit = 0) const;
   15.28 +
   15.29 +	bool load(const char *fname);
   15.30 +};
   15.31 +
   15.32 +#endif	// TEXTURE_H_
   15.33 \ No newline at end of file
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/vrchess.sln	Fri Apr 25 05:20:53 2014 +0300
    16.3 @@ -0,0 +1,20 @@
    16.4 +
    16.5 +Microsoft Visual Studio Solution File, Format Version 12.00
    16.6 +# Visual Studio 2012
    16.7 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vrchess", "vrchess.vcxproj", "{714906B6-FD4C-4ECC-990C-247FA46B8801}"
    16.8 +EndProject
    16.9 +Global
   16.10 +	GlobalSection(SolutionConfigurationPlatforms) = preSolution
   16.11 +		Debug|Win32 = Debug|Win32
   16.12 +		Release|Win32 = Release|Win32
   16.13 +	EndGlobalSection
   16.14 +	GlobalSection(ProjectConfigurationPlatforms) = postSolution
   16.15 +		{714906B6-FD4C-4ECC-990C-247FA46B8801}.Debug|Win32.ActiveCfg = Debug|Win32
   16.16 +		{714906B6-FD4C-4ECC-990C-247FA46B8801}.Debug|Win32.Build.0 = Debug|Win32
   16.17 +		{714906B6-FD4C-4ECC-990C-247FA46B8801}.Release|Win32.ActiveCfg = Release|Win32
   16.18 +		{714906B6-FD4C-4ECC-990C-247FA46B8801}.Release|Win32.Build.0 = Release|Win32
   16.19 +	EndGlobalSection
   16.20 +	GlobalSection(SolutionProperties) = preSolution
   16.21 +		HideSolutionNode = FALSE
   16.22 +	EndGlobalSection
   16.23 +EndGlobal
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/vrchess.vcxproj	Fri Apr 25 05:20:53 2014 +0300
    17.3 @@ -0,0 +1,102 @@
    17.4 +<?xml version="1.0" encoding="utf-8"?>
    17.5 +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    17.6 +  <ItemGroup Label="ProjectConfigurations">
    17.7 +    <ProjectConfiguration Include="Debug|Win32">
    17.8 +      <Configuration>Debug</Configuration>
    17.9 +      <Platform>Win32</Platform>
   17.10 +    </ProjectConfiguration>
   17.11 +    <ProjectConfiguration Include="Release|Win32">
   17.12 +      <Configuration>Release</Configuration>
   17.13 +      <Platform>Win32</Platform>
   17.14 +    </ProjectConfiguration>
   17.15 +  </ItemGroup>
   17.16 +  <PropertyGroup Label="Globals">
   17.17 +    <ProjectGuid>{714906B6-FD4C-4ECC-990C-247FA46B8801}</ProjectGuid>
   17.18 +    <Keyword>Win32Proj</Keyword>
   17.19 +    <RootNamespace>vrchess</RootNamespace>
   17.20 +  </PropertyGroup>
   17.21 +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   17.22 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
   17.23 +    <ConfigurationType>Application</ConfigurationType>
   17.24 +    <UseDebugLibraries>true</UseDebugLibraries>
   17.25 +    <PlatformToolset>v90</PlatformToolset>
   17.26 +    <CharacterSet>Unicode</CharacterSet>
   17.27 +  </PropertyGroup>
   17.28 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
   17.29 +    <ConfigurationType>Application</ConfigurationType>
   17.30 +    <UseDebugLibraries>false</UseDebugLibraries>
   17.31 +    <PlatformToolset>v90</PlatformToolset>
   17.32 +    <WholeProgramOptimization>true</WholeProgramOptimization>
   17.33 +    <CharacterSet>Unicode</CharacterSet>
   17.34 +  </PropertyGroup>
   17.35 +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   17.36 +  <ImportGroup Label="ExtensionSettings">
   17.37 +  </ImportGroup>
   17.38 +  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
   17.39 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   17.40 +  </ImportGroup>
   17.41 +  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   17.42 +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   17.43 +  </ImportGroup>
   17.44 +  <PropertyGroup Label="UserMacros" />
   17.45 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
   17.46 +    <LinkIncremental>true</LinkIncremental>
   17.47 +  </PropertyGroup>
   17.48 +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   17.49 +    <LinkIncremental>false</LinkIncremental>
   17.50 +  </PropertyGroup>
   17.51 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
   17.52 +    <ClCompile>
   17.53 +      <PrecompiledHeader>
   17.54 +      </PrecompiledHeader>
   17.55 +      <WarningLevel>Level3</WarningLevel>
   17.56 +      <Optimization>Disabled</Optimization>
   17.57 +      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
   17.58 +      <DisableSpecificWarnings>4996;4244;4305</DisableSpecificWarnings>
   17.59 +    </ClCompile>
   17.60 +    <Link>
   17.61 +      <SubSystem>Console</SubSystem>
   17.62 +      <GenerateDebugInformation>true</GenerateDebugInformation>
   17.63 +      <AdditionalDependencies>opengl32.lib;glut32.lib;glew32.lib;libvmath.lib;libimago2.lib;jpeglib.lib;libpng.lib;zlib.lib;libovrd.lib;%(AdditionalDependencies)</AdditionalDependencies>
   17.64 +    </Link>
   17.65 +  </ItemDefinitionGroup>
   17.66 +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   17.67 +    <ClCompile>
   17.68 +      <WarningLevel>Level3</WarningLevel>
   17.69 +      <PrecompiledHeader>
   17.70 +      </PrecompiledHeader>
   17.71 +      <Optimization>MaxSpeed</Optimization>
   17.72 +      <FunctionLevelLinking>true</FunctionLevelLinking>
   17.73 +      <IntrinsicFunctions>true</IntrinsicFunctions>
   17.74 +      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
   17.75 +      <DisableSpecificWarnings>4996;4244;4305</DisableSpecificWarnings>
   17.76 +    </ClCompile>
   17.77 +    <Link>
   17.78 +      <SubSystem>Console</SubSystem>
   17.79 +      <GenerateDebugInformation>true</GenerateDebugInformation>
   17.80 +      <EnableCOMDATFolding>true</EnableCOMDATFolding>
   17.81 +      <OptimizeReferences>true</OptimizeReferences>
   17.82 +      <AdditionalDependencies>opengl32.lib;glut32.lib;glew32.lib;libvmath.lib;libimago2.lib;jpeglib.lib;libpng.lib;zlib.lib;libovr.lib;%(AdditionalDependencies)</AdditionalDependencies>
   17.83 +    </Link>
   17.84 +  </ItemDefinitionGroup>
   17.85 +  <ItemGroup>
   17.86 +    <ClCompile Include="src\camera.cc" />
   17.87 +    <ClCompile Include="src\game.cc" />
   17.88 +    <ClCompile Include="src\image.cc" />
   17.89 +    <ClCompile Include="src\main.cc" />
   17.90 +    <ClCompile Include="src\opengl.cc" />
   17.91 +    <ClCompile Include="src\sdr.c" />
   17.92 +    <ClCompile Include="src\texture.cc" />
   17.93 +  </ItemGroup>
   17.94 +  <ItemGroup>
   17.95 +    <ClInclude Include="src\camera.h" />
   17.96 +    <ClInclude Include="src\game.h" />
   17.97 +    <ClInclude Include="src\image.h" />
   17.98 +    <ClInclude Include="src\opengl.h" />
   17.99 +    <ClInclude Include="src\sdr.h" />
  17.100 +    <ClInclude Include="src\texture.h" />
  17.101 +  </ItemGroup>
  17.102 +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  17.103 +  <ImportGroup Label="ExtensionTargets">
  17.104 +  </ImportGroup>
  17.105 +</Project>
  17.106 \ No newline at end of file
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/vrchess.vcxproj.filters	Fri Apr 25 05:20:53 2014 +0300
    18.3 @@ -0,0 +1,60 @@
    18.4 +<?xml version="1.0" encoding="utf-8"?>
    18.5 +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    18.6 +  <ItemGroup>
    18.7 +    <Filter Include="Source Files">
    18.8 +      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
    18.9 +      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
   18.10 +    </Filter>
   18.11 +    <Filter Include="Header Files">
   18.12 +      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
   18.13 +      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
   18.14 +    </Filter>
   18.15 +    <Filter Include="Resource Files">
   18.16 +      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
   18.17 +      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
   18.18 +    </Filter>
   18.19 +  </ItemGroup>
   18.20 +  <ItemGroup>
   18.21 +    <ClCompile Include="src\main.cc">
   18.22 +      <Filter>Source Files</Filter>
   18.23 +    </ClCompile>
   18.24 +    <ClCompile Include="src\camera.cc">
   18.25 +      <Filter>Source Files</Filter>
   18.26 +    </ClCompile>
   18.27 +    <ClCompile Include="src\opengl.cc">
   18.28 +      <Filter>Source Files</Filter>
   18.29 +    </ClCompile>
   18.30 +    <ClCompile Include="src\sdr.c">
   18.31 +      <Filter>Source Files</Filter>
   18.32 +    </ClCompile>
   18.33 +    <ClCompile Include="src\game.cc">
   18.34 +      <Filter>Source Files</Filter>
   18.35 +    </ClCompile>
   18.36 +    <ClCompile Include="src\image.cc">
   18.37 +      <Filter>Source Files</Filter>
   18.38 +    </ClCompile>
   18.39 +    <ClCompile Include="src\texture.cc">
   18.40 +      <Filter>Source Files</Filter>
   18.41 +    </ClCompile>
   18.42 +  </ItemGroup>
   18.43 +  <ItemGroup>
   18.44 +    <ClInclude Include="src\camera.h">
   18.45 +      <Filter>Header Files</Filter>
   18.46 +    </ClInclude>
   18.47 +    <ClInclude Include="src\sdr.h">
   18.48 +      <Filter>Header Files</Filter>
   18.49 +    </ClInclude>
   18.50 +    <ClInclude Include="src\opengl.h">
   18.51 +      <Filter>Header Files</Filter>
   18.52 +    </ClInclude>
   18.53 +    <ClInclude Include="src\game.h">
   18.54 +      <Filter>Header Files</Filter>
   18.55 +    </ClInclude>
   18.56 +    <ClInclude Include="src\image.h">
   18.57 +      <Filter>Header Files</Filter>
   18.58 +    </ClInclude>
   18.59 +    <ClInclude Include="src\texture.h">
   18.60 +      <Filter>Header Files</Filter>
   18.61 +    </ClInclude>
   18.62 +  </ItemGroup>
   18.63 +</Project>
   18.64 \ No newline at end of file