|
@@ -0,0 +1,233 @@
|
|
|
+/*
|
|
|
+
|
|
|
+ This file is part of glstart.
|
|
|
+
|
|
|
+ glstart is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
|
+
|
|
|
+ glstart is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
+
|
|
|
+ You should have received a copy of the GNU General Public License along with Foobar. If not, see <https://www.gnu.org/licenses/>.
|
|
|
+*/
|
|
|
+
|
|
|
+
|
|
|
+#include <stdio.h>
|
|
|
+#include <stdlib.h>
|
|
|
+#include <math.h>
|
|
|
+#include <string.h>
|
|
|
+#include <X11/X.h>
|
|
|
+#include <X11/keysymdef.h>
|
|
|
+#include <X11/Xlib.h>
|
|
|
+
|
|
|
+#define GL_GLEXT_PROTOTYPES
|
|
|
+
|
|
|
+#include <GL/gl.h>
|
|
|
+#include <GL/glx.h>
|
|
|
+#include <GL/glu.h>
|
|
|
+#include <GL/glext.h>
|
|
|
+#include <GL/glcorearb.h>
|
|
|
+#include "vertexes.h"
|
|
|
+#include "shaders.h"
|
|
|
+#include "textures.h"
|
|
|
+#include "obj3d.h"
|
|
|
+#include "objmtl.h"
|
|
|
+#include "marray.h"
|
|
|
+
|
|
|
+Display* dpy;
|
|
|
+Window root;
|
|
|
+GLint att[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None};
|
|
|
+XVisualInfo* vi;
|
|
|
+Colormap cmap;
|
|
|
+XSetWindowAttributes swa;
|
|
|
+Window win;
|
|
|
+GLXContext glc;
|
|
|
+XWindowAttributes gwa;
|
|
|
+XEvent xev;
|
|
|
+
|
|
|
+int main(int argc, char* argv[]) {
|
|
|
+
|
|
|
+ if(argc != 5) {
|
|
|
+ printf("syntax: %s <vertex shader file> <fragment shader file> <bmp file> <obj file>\n", argv[0]);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ dpy = XOpenDisplay(NULL);
|
|
|
+ if(dpy == NULL) {
|
|
|
+ printf("\n\tCannot connect to X server\n\n");
|
|
|
+ exit(0);
|
|
|
+ };
|
|
|
+
|
|
|
+ root = DefaultRootWindow(dpy);
|
|
|
+ vi = glXChooseVisual(dpy, 0, att);
|
|
|
+ if(vi == NULL) {
|
|
|
+ printf("\n\tno appropriate visual found\n\n");
|
|
|
+ exit(0);
|
|
|
+ } else {
|
|
|
+ printf("\n\tvisual %p selected\n", (void*)vi->visualid);
|
|
|
+ };
|
|
|
+
|
|
|
+ cmap = XCreateColormap(dpy, root, vi->visual, AllocNone);
|
|
|
+ swa.colormap = cmap;
|
|
|
+ swa.event_mask = KeyPressMask | PointerMotionMask;
|
|
|
+
|
|
|
+ win = XCreateWindow(dpy, root, 0, 0, 600, 600, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa);
|
|
|
+ XMapWindow(dpy, win);
|
|
|
+ XStoreName(dpy, win, "OpenGL Mouse Look");
|
|
|
+
|
|
|
+ glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
|
|
|
+ glXMakeCurrent(dpy, win, glc);
|
|
|
+
|
|
|
+ glEnable(GL_DEPTH_TEST);
|
|
|
+
|
|
|
+
|
|
|
+ Obj3D o3d;
|
|
|
+
|
|
|
+ OBJFILE* ofile = readOBJFILE(argv[4]);
|
|
|
+ MArray* hvbo = makeVBO(ofile);
|
|
|
+
|
|
|
+ float verts[] = { 0.0f, 0.9f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, -1.0f,
|
|
|
+ 0.9f, -0.9f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f,
|
|
|
+ -0.9f, -0.9f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -1.0f,
|
|
|
+ };
|
|
|
+
|
|
|
+ obj3dInit(&o3d, CreateShaderProgram(argv[1], argv[2]),
|
|
|
+ CreateVAO(hvbo->d, hvbo->size, NULL, 0),
|
|
|
+ hvbo->size/(sizeof(float)*8), loadBmpTexture(argv[3]));
|
|
|
+
|
|
|
+ freeMArray(hvbo);
|
|
|
+ freeOBJFILE(ofile);
|
|
|
+
|
|
|
+ float n = 0.05f;
|
|
|
+ float f = 1000.0f;
|
|
|
+ float l = 0.05f;
|
|
|
+ float t = 0.05f;
|
|
|
+ float cx = 0.0f;
|
|
|
+ float cz = 0.0f;
|
|
|
+ float angleh = 0.0f;
|
|
|
+ float anglev = 0.0f;
|
|
|
+
|
|
|
+
|
|
|
+ float pers[] = {
|
|
|
+ 2*n/l, 0.0f, 0.0f, 0.0f,
|
|
|
+ 0.0f, 2*n/t, 0.0f, 0.0f,
|
|
|
+ 0.0f, 0.0f, (n+f)/(n-f), 2*n*f/(n-f),
|
|
|
+ 0.0f, 0.0f, -1.0f, 0.0f,
|
|
|
+ };
|
|
|
+
|
|
|
+ float view[] = {
|
|
|
+ 1.0f, 0.0f, 0.0f, 0.0f,
|
|
|
+ 0.0f, 1.0f, 0.0f, 0.0f,
|
|
|
+ 0.0f, 0.0f, 1.0f, 0.0f,
|
|
|
+ 0.0f, 0.0f, 0.0f, 1.0f
|
|
|
+ };
|
|
|
+
|
|
|
+ //XGrabPointer(dpy, win, True, PointerMotionMask, GrabModeAsync, GrabModeAsync, win, None, CurrentTime);
|
|
|
+
|
|
|
+ while(1) {
|
|
|
+ if(XCheckTypedWindowEvent(dpy, win, KeyPress, &xev)) {
|
|
|
+ KeySym sym = XLookupKeysym(&xev.xkey, 0);
|
|
|
+ switch(sym) {
|
|
|
+ case XK_Escape:
|
|
|
+ glXMakeCurrent(dpy, None, NULL);
|
|
|
+ glXDestroyContext(dpy, glc);
|
|
|
+ XDestroyWindow(dpy, win);
|
|
|
+ XCloseDisplay(dpy);
|
|
|
+ exit(0);
|
|
|
+ break;
|
|
|
+ case XK_w:
|
|
|
+ cz += -0.1f*cos(angleh);
|
|
|
+ cx += -0.1f*sin(angleh);
|
|
|
+ break;
|
|
|
+ case XK_s:
|
|
|
+ cz += 0.1f*cos(angleh);
|
|
|
+ cx += 0.1f*sin(angleh);
|
|
|
+ break;
|
|
|
+ case XK_a:
|
|
|
+ cx += -0.1f;
|
|
|
+ break;
|
|
|
+ case XK_d:
|
|
|
+ cx += 0.1f;
|
|
|
+ break;
|
|
|
+ case XK_q:
|
|
|
+ angleh += 0.01f;
|
|
|
+ break;
|
|
|
+ case XK_e:
|
|
|
+ angleh += -0.01f;
|
|
|
+ break;
|
|
|
+ case XK_z:
|
|
|
+ anglev += 0.01f;
|
|
|
+ break;
|
|
|
+ case XK_c:
|
|
|
+ anglev += -0.01f;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ };
|
|
|
+ };
|
|
|
+
|
|
|
+ view[11] = -cz;
|
|
|
+ view[3] = -cx;
|
|
|
+
|
|
|
+ if(angleh > 3.14f) angleh -= 6.28f;
|
|
|
+ if(angleh < -3.14f) angleh += 6.28f;
|
|
|
+
|
|
|
+ if(anglev > 3.14f*0.5f) anglev = 3.14f*0.5f;
|
|
|
+ if(anglev < -3.14f*0.5f) anglev = -3.14f*0.5f;
|
|
|
+
|
|
|
+ float roth[] = {
|
|
|
+ cos(-angleh), 0.0f, sin(-angleh), 0.0f,
|
|
|
+ 0.0f, 1.0f, 0.0f, 0.0f,
|
|
|
+ -sin(-angleh), 0.0f, cos(-angleh), 0.0f,
|
|
|
+ 0.0f, 0.0f, 0.0f, 1.0f
|
|
|
+ };
|
|
|
+
|
|
|
+ float rotv[] = {
|
|
|
+ 1.0f, 0.0f, 0.0f, 0.0f,
|
|
|
+ 0.0f, cos(-anglev), -sin(-anglev), 0.0f,
|
|
|
+ 0.0f, sin(-anglev), cos(-anglev), 0.0f,
|
|
|
+ 0.0f, 0.0f, 0.0f, 1.0f
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ XGetWindowAttributes(dpy, win, &gwa);
|
|
|
+
|
|
|
+ short mx = gwa.width/2;
|
|
|
+ short my = gwa.height/2;
|
|
|
+ int dx = 0;
|
|
|
+ int dy = 0;
|
|
|
+
|
|
|
+ Window r_w, c_w;
|
|
|
+ int root_x_return, root_y_return;
|
|
|
+ unsigned int mask_return;
|
|
|
+ if(True == XQueryPointer(dpy, win, &r_w, &c_w, &root_x_return, &root_y_return, &dx, &dy, &mask_return)) {
|
|
|
+ dx = mx - dx;
|
|
|
+ dy = my - dy;
|
|
|
+ float dangle_xz = ((float)dx)/1000.0f;
|
|
|
+ float dangle_yz = ((float)dy)/1000.0f;
|
|
|
+ angleh += dangle_xz;
|
|
|
+ anglev += dangle_yz;
|
|
|
+ };
|
|
|
+
|
|
|
+ XWarpPointer(dpy, win, win, 0, 0, gwa.width, gwa.height, gwa.width/2, gwa.height/2);
|
|
|
+
|
|
|
+ glViewport(0, 0, gwa.width, gwa.height);
|
|
|
+
|
|
|
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
|
|
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
+
|
|
|
+ glUseProgram(o3d.shaderProgram);
|
|
|
+ glUniform1i(glGetUniformLocation(o3d.shaderProgram, "tex1"), 0);
|
|
|
+ glUniformMatrix4fv(glGetUniformLocation(o3d.shaderProgram, "roth"), 1, GL_TRUE, roth);
|
|
|
+ glUniformMatrix4fv(glGetUniformLocation(o3d.shaderProgram, "rotv"), 1, GL_TRUE, rotv);
|
|
|
+ glUniformMatrix4fv(glGetUniformLocation(o3d.shaderProgram, "pers"), 1, GL_TRUE, pers);
|
|
|
+ glUniformMatrix4fv(glGetUniformLocation(o3d.shaderProgram, "view"), 1, GL_TRUE, view);
|
|
|
+ glUniformMatrix4fv(glGetUniformLocation(o3d.shaderProgram, "trans"), 1, GL_TRUE, o3d.transform);
|
|
|
+ glActiveTexture(GL_TEXTURE0);
|
|
|
+ glBindTexture(GL_TEXTURE_2D, o3d.tex);
|
|
|
+
|
|
|
+ glBindVertexArray(o3d.VAO);
|
|
|
+ glDrawArrays(GL_TRIANGLES, 0, o3d.vao_size);
|
|
|
+
|
|
|
+ glXSwapBuffers(dpy, win);
|
|
|
+ };
|
|
|
+};
|