Last active
August 18, 2024 17:37
-
-
Save yne/5095dbc85b1ba34ca3a2079006b9931c to your computer and use it in GitHub Desktop.
mode7 style tilemap X11+GL (require a 32x32 ./sprite.bmp)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//c99 main.c -o ../main -lX11 -lGL -lGLU && cd .. && ./main | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <X11/X.h> | |
#include <GL/gl.h> | |
#include <GL/glx.h> | |
GLuint texture[1]; | |
int initGL(GLfloat width,GLfloat height){ | |
typedef uint8_t Sprite[32*32*3]; | |
Sprite pixels[2]; | |
FILE*f=fopen("sprite.bmp","rb"); | |
fseek(f,122,SEEK_SET); | |
fread(pixels,1,sizeof(pixels),f); | |
fclose(f); | |
glGenTextures(1, &texture[0]); | |
glBindTexture(GL_TEXTURE_2D, texture[0]); | |
glTexImage2D(GL_TEXTURE_2D, 0, 3, 32, 64, 0, GL_BGR, GL_UNSIGNED_BYTE, pixels); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
glEnable(GL_TEXTURE_2D); | |
glShadeModel(GL_SMOOTH); | |
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); | |
glClearDepth(1.0f); | |
glEnable(GL_DEPTH_TEST); | |
glDepthFunc(GL_LEQUAL); | |
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); | |
GLfloat ratio = (GLfloat)width / (GLfloat)height; | |
glViewport(0, 0, (GLint)width, (GLint)height); | |
glMatrixMode(GL_PROJECTION); | |
glLoadIdentity(); | |
GLdouble fH = 0.06854;//tan(fovY/360*pi)*zNear; | |
GLdouble fW = fH * ratio; | |
glFrustum( -fW, fW, -fH, fH, 0.1f, 100.0f ); | |
glMatrixMode(GL_MODELVIEW); | |
glLoadIdentity(); | |
return 1; | |
} | |
GLfloat xpos=.0,ypos=.0,zpos=-3.,xrot=.0,yrot=.0,zrot=.0; | |
int drawGLScene(GLvoid){ | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
glLoadIdentity(); | |
glTranslatef(xpos, ypos, zpos); | |
glRotatef(xrot*10,0,1,0); | |
glBindTexture(GL_TEXTURE_2D, texture[0]); | |
glBegin(GL_QUADS); | |
typedef struct{float tx,ty,vx,vy,vz;}Node; | |
Node nodes[2][4]={{ | |
{0, 0,-.5,-.5, .5}, | |
{1, 0, .5,-.5, .5}, | |
{1,.5, .5,-.5,-.5}, | |
{0,.5,-.5,-.5,-.5}, | |
},{ | |
{0,.5,-.5,-.5, .5}, | |
{1,.5, .5,-.5, .5}, | |
{1, 1, .5,-.5,-.5}, | |
{0, 1,-.5,-.5,-.5}, | |
}}; | |
int tex[]={ | |
1,1,1,1, | |
1,0,0,1, | |
1,0,0,1, | |
1,1,1,1, | |
}; | |
for(int i=0;i<16;i++){ | |
for(Node*n=nodes[tex[i]];n<nodes[tex[i]]+(sizeof(nodes[tex[i]])/sizeof(**nodes));n++){ | |
glTexCoord2f(n->tx, n->ty),glVertex3f(n->vx+(i%4), n->vy, n->vz+(i/4)); | |
} | |
} | |
glEnd(); | |
return(1); | |
} | |
int main(int argc, char *argv[]) { | |
#define SCREEN_WIDTH 640 | |
#define SCREEN_HEIGHT 480 | |
Display*dpy = XOpenDisplay(NULL); | |
Window root = DefaultRootWindow(dpy); | |
XVisualInfo*vi = glXChooseVisual(dpy, 0, (GLint[]){GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None}); | |
XSetWindowAttributes swa={ | |
.colormap = XCreateColormap(dpy, root, vi->visual, AllocNone), | |
.event_mask = ExposureMask | KeyPressMask | |
}; | |
Window win = XCreateWindow(dpy, root, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa); | |
XMapWindow(dpy, win); | |
GLXContext glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); | |
glXMakeCurrent(dpy, win, glc); | |
initGL(SCREEN_WIDTH,SCREEN_HEIGHT); | |
while(1){ | |
XEvent xev; | |
if(XCheckWindowEvent(dpy, win, KeyPressMask, &xev)){ | |
if(xev.type == KeyPress){ | |
if(xev.xkey.keycode==9)break; | |
if(xev.xkey.keycode>=110 && xev.xkey.keycode<=117) | |
*((GLfloat*[]){&xrot,&zpos,&ypos,&xpos,&xpos,&xrot,&zpos,&ypos}[xev.xkey.keycode-110])+=xev.xkey.keycode&1?.1f:-.1f; | |
else | |
printf("unk code %i\n",xev.xkey.keycode); | |
printf("pos<%.2f %.2f %.2f> rot<%.2f %.2f %.2f>\n",xpos,ypos,zpos,xrot,yrot,zrot); | |
}else if(xev.type == Expose){ | |
XWindowAttributes gwa; | |
XGetWindowAttributes(dpy, win, &gwa); | |
} | |
} | |
drawGLScene(); | |
glXSwapBuffers(dpy, win); | |
} | |
glXMakeCurrent(dpy, None, NULL); | |
glXDestroyContext(dpy, glc); | |
XDestroyWindow(dpy, win); | |
XCloseDisplay(dpy); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment