From 68c6936b25917e5b7bb283cf46bc6396bd2d3047 Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Fri, 10 Jun 2022 20:26:51 +0100 Subject: [PATCH] Add nehe10 sample --- CMakeLists.txt | 1 + samples/nehe10/main.c | 317 +++++++++++++++++++++++++++++++ samples/nehe10/romdisk/brick.bmp | Bin 0 -> 49290 bytes samples/nehe10/romdisk/world.txt | 160 ++++++++++++++++ 4 files changed, 478 insertions(+) create mode 100644 samples/nehe10/main.c create mode 100644 samples/nehe10/romdisk/brick.bmp create mode 100644 samples/nehe10/romdisk/world.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 13ca114..32a7d8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -148,6 +148,7 @@ gen_sample(nehe06 samples/nehe06/main.c samples/loadbmp.c) gen_sample(nehe06_vq samples/nehe06_vq/main.c) gen_sample(nehe06_4444twid samples/nehe06_4444twid/main.c) gen_sample(nehe08 samples/nehe08/main.c samples/nehe08/pvr-texture.c) +gen_sample(nehe10 samples/nehe10/main.c samples/loadbmp.c) gen_sample(nehe20 samples/nehe20/main.c samples/loadbmp.c) gen_sample(ortho2d samples/ortho2d/main.c) gen_sample(paletted samples/paletted/main.c) diff --git a/samples/nehe10/main.c b/samples/nehe10/main.c new file mode 100644 index 0000000..7aa1252 --- /dev/null +++ b/samples/nehe10/main.c @@ -0,0 +1,317 @@ +/* + KallistiOS 2.0.0 + + nehe08.c + (c)2021 Luke Benstead + (c)2014 Josh Pearson + (c)2001 Benoit Miller + (c)2000 Jeff Molofee +*/ + +#ifdef __DREAMCAST__ +#include +#endif + +#include +#include +#include + +#include + +#include "../loadbmp.h" + +#ifdef __DREAMCAST__ +extern uint8 romdisk[]; +KOS_INIT_ROMDISK(romdisk); +#define IMG_PATH "/rd/brick.bmp" +#else +#define IMG_PATH "../samples/nehe10/romdisk/brick.bmp" +#endif + +bool keys[256]; // Array Used For The Keyboard Routine +bool active = GL_TRUE; // Window Active Flag Set To TRUE By Default +bool fullscreen = GL_TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default +bool blend; // Blending ON/OFF +bool bp; // B Pressed? +bool fp; // F Pressed? + +const float piover180 = 0.0174532925f; +float heading; +float xpos; +float zpos; + +GLfloat yrot; // Y Rotation +GLfloat walkbias = 0; +GLfloat walkbiasangle = 0; +GLfloat lookupdown = 0.0f; +GLfloat z=0.0f; // Depth Into The Screen + +GLuint filter; // Which Filter To Use +GLuint texture[3]; // Storage For 3 Textures + +typedef struct tagVERTEX +{ + float x, y, z; + float u, v; +} VERTEX; + +typedef struct tagTRIANGLE +{ + VERTEX vertex[3]; +} TRIANGLE; + +typedef struct tagSECTOR +{ + int numtriangles; + TRIANGLE* triangle; +} SECTOR; + +SECTOR sector1; + +void readstr(FILE *f,char *string) +{ + do + { + fgets(string, 255, f); + } while ((string[0] == '/') || (string[0] == '\n')); + return; +} + +void SetupWorld() +{ + float x, y, z, u, v; + int numtriangles; + FILE *filein; + char oneline[255]; + filein = fopen("/rd/world.txt", "rt"); // File To Load World Data From + + readstr(filein,oneline); + sscanf(oneline, "NUMPOLLIES %d\n", &numtriangles); + + sector1.triangle = (TRIANGLE*) malloc(sizeof(TRIANGLE) * numtriangles); + sector1.numtriangles = numtriangles; + for (int loop = 0; loop < numtriangles; loop++) + { + for (int vert = 0; vert < 3; vert++) + { + readstr(filein,oneline); + sscanf(oneline, "%f %f %f %f %f", &x, &y, &z, &u, &v); + sector1.triangle[loop].vertex[vert].x = x; + sector1.triangle[loop].vertex[vert].y = y; + sector1.triangle[loop].vertex[vert].z = z; + sector1.triangle[loop].vertex[vert].u = u; + sector1.triangle[loop].vertex[vert].v = v; + } + } + fclose(filein); + return; +} + +int LoadGLTextures() // Load Bitmaps And Convert To Textures +{ + int Status = GL_FALSE; // Status Indicator + + Image image1; + + // Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit + if (ImageLoad(IMG_PATH, &image1)) + { + Status = GL_TRUE; // Set The Status To TRUE + + glGenTextures(3, &texture[0]); // Create Three Textures + + // Create Nearest Filtered Texture + glBindTexture(GL_TEXTURE_2D, texture[0]); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, 3, image1.sizeX, image1.sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image1.data); + + // Create Linear Filtered Texture + glBindTexture(GL_TEXTURE_2D, texture[1]); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, 3, image1.sizeX, image1.sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image1.data); + + // Create MipMapped Texture + glBindTexture(GL_TEXTURE_2D, texture[2]); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); + gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image1.sizeX, image1.sizeY, GL_RGB, GL_UNSIGNED_BYTE, image1.data); + } + + return Status; // Return The Status +} + +/* A general OpenGL initialization function. Sets all of the initial parameters. */ +GLboolean InitGL(int width, int height) // We call this right after our OpenGL window is created. +{ + glViewport(0, 0, width, height); // Reset The Current Viewport + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + glLoadIdentity(); // Reset The Projection Matrix + + // Calculate The Aspect Ratio Of The Window + gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + glLoadIdentity(); + + if (!LoadGLTextures()) // Jump To Texture Loading Routine + { + return GL_FALSE; // If Texture Didn't Load Return false + } + + glEnable(GL_TEXTURE_2D); // Enable Texture Mapping + glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Set The Blending Function For Translucency + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black + glClearDepth(1.0); // Enables Clearing Of The Depth Buffer + glDepthFunc(GL_LESS); // The Type Of Depth Test To Do + glEnable(GL_DEPTH_TEST); // Enables Depth Testing + glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations + + SetupWorld(); + + return GL_TRUE; +} + +void DrawGLScene(void) { + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer + glLoadIdentity(); // Reset The View + + GLfloat x_m, y_m, z_m, u_m, v_m; + GLfloat xtrans = -xpos; + GLfloat ztrans = -zpos; + GLfloat ytrans = -walkbias-0.25f; + GLfloat sceneroty = 360.0f - yrot; + + int numtriangles; + + glRotatef(lookupdown,1.0f,0,0); + glRotatef(sceneroty,0,1.0f,0); + + glTranslatef(xtrans, ytrans, ztrans); + glBindTexture(GL_TEXTURE_2D, texture[filter]); + + numtriangles = sector1.numtriangles; + + // Process Each Triangle + for (int loop_m = 0; loop_m < numtriangles; loop_m++) + { + glBegin(GL_TRIANGLES); + glNormal3f( 0.0f, 0.0f, 1.0f); + x_m = sector1.triangle[loop_m].vertex[0].x; + y_m = sector1.triangle[loop_m].vertex[0].y; + z_m = sector1.triangle[loop_m].vertex[0].z; + u_m = sector1.triangle[loop_m].vertex[0].u; + v_m = sector1.triangle[loop_m].vertex[0].v; + glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m); + + x_m = sector1.triangle[loop_m].vertex[1].x; + y_m = sector1.triangle[loop_m].vertex[1].y; + z_m = sector1.triangle[loop_m].vertex[1].z; + u_m = sector1.triangle[loop_m].vertex[1].u; + v_m = sector1.triangle[loop_m].vertex[1].v; + glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m); + + x_m = sector1.triangle[loop_m].vertex[2].x; + y_m = sector1.triangle[loop_m].vertex[2].y; + z_m = sector1.triangle[loop_m].vertex[2].z; + u_m = sector1.triangle[loop_m].vertex[2].u; + v_m = sector1.triangle[loop_m].vertex[2].v; + glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m); + glEnd(); + } + /* Finish the frame */ + glKosSwapBuffers(); +} + +int ReadController(void) { +#ifdef __DREAMCAST__ + maple_device_t *cont; + cont_state_t *state; + + cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER); + + /* Check key status */ + state = (cont_state_t *)maple_dev_status(cont); + if(!state) { + printf("Error reading controller\n"); + return 0; + } + + if(state->buttons & CONT_START) + return 0; + + if(state->buttons & CONT_DPAD_UP) { + xpos -= (float)sin(heading*piover180) * 0.05f; + zpos -= (float)cos(heading*piover180) * 0.05f; + if (walkbiasangle >= 359.0f) + { + walkbiasangle = 0.0f; + } + else + { + walkbiasangle+= 10; + } + walkbias = (float)sin(walkbiasangle * piover180)/20.0f; + } + + + if(state->buttons & CONT_DPAD_DOWN) { + xpos += (float)sin(heading*piover180) * 0.05f; + zpos += (float)cos(heading*piover180) * 0.05f; + if (walkbiasangle <= 1.0f) + { + walkbiasangle = 359.0f; + } + else + { + walkbiasangle-= 10; + } + walkbias = (float)sin(walkbiasangle * piover180)/20.0f; + } + + + if(state->buttons & CONT_DPAD_LEFT) { + heading += 1.0f; + yrot = heading; + } + + if(state->buttons & CONT_DPAD_RIGHT) { + heading -= 1.0f; + yrot = heading; + } + +#endif + + /* Switch to the blended polygon list if needed */ + if(blend) { + glEnable(GL_BLEND); + glDepthMask(0); + } + else { + glDisable(GL_BLEND); + glDepthMask(1); + } + + return 1; +} + +int main(int argc, char **argv) { + printf("nehe10 beginning\n"); + + /* Get basic stuff initialized */ + glKosInit(); + + InitGL(640, 480); + + while(1) { + if (!ReadController()) + break; + + DrawGLScene(); + } + + return 0; +} diff --git a/samples/nehe10/romdisk/brick.bmp b/samples/nehe10/romdisk/brick.bmp new file mode 100644 index 0000000000000000000000000000000000000000..54ac213a3504904da2f6d0d3b080874962b00d79 GIT binary patch literal 49290 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 literal 0 HcmV?d00001 diff --git a/samples/nehe10/romdisk/world.txt b/samples/nehe10/romdisk/world.txt new file mode 100644 index 0000000..a3368bb --- /dev/null +++ b/samples/nehe10/romdisk/world.txt @@ -0,0 +1,160 @@ + +NUMPOLLIES 36 + +// Floor 1 +-3.0 0.0 -3.0 0.0 6.0 +-3.0 0.0 3.0 0.0 0.0 + 3.0 0.0 3.0 6.0 0.0 + +-3.0 0.0 -3.0 0.0 6.0 + 3.0 0.0 -3.0 6.0 6.0 + 3.0 0.0 3.0 6.0 0.0 + +// Ceiling 1 +-3.0 1.0 -3.0 0.0 6.0 +-3.0 1.0 3.0 0.0 0.0 + 3.0 1.0 3.0 6.0 0.0 +-3.0 1.0 -3.0 0.0 6.0 + 3.0 1.0 -3.0 6.0 6.0 + 3.0 1.0 3.0 6.0 0.0 + +// A1 + +-2.0 1.0 -2.0 0.0 1.0 +-2.0 0.0 -2.0 0.0 0.0 +-0.5 0.0 -2.0 1.5 0.0 +-2.0 1.0 -2.0 0.0 1.0 +-0.5 1.0 -2.0 1.5 1.0 +-0.5 0.0 -2.0 1.5 0.0 + +// A2 + + 2.0 1.0 -2.0 2.0 1.0 + 2.0 0.0 -2.0 2.0 0.0 + 0.5 0.0 -2.0 0.5 0.0 + 2.0 1.0 -2.0 2.0 1.0 + 0.5 1.0 -2.0 0.5 1.0 + 0.5 0.0 -2.0 0.5 0.0 + +// B1 + +-2.0 1.0 2.0 2.0 1.0 +-2.0 0.0 2.0 2.0 0.0 +-0.5 0.0 2.0 0.5 0.0 +-2.0 1.0 2.0 2.0 1.0 +-0.5 1.0 2.0 0.5 1.0 +-0.5 0.0 2.0 0.5 0.0 + +// B2 + + 2.0 1.0 2.0 2.0 1.0 + 2.0 0.0 2.0 2.0 0.0 + 0.5 0.0 2.0 0.5 0.0 + 2.0 1.0 2.0 2.0 1.0 + 0.5 1.0 2.0 0.5 1.0 + 0.5 0.0 2.0 0.5 0.0 + +// C1 + +-2.0 1.0 -2.0 0.0 1.0 +-2.0 0.0 -2.0 0.0 0.0 +-2.0 0.0 -0.5 1.5 0.0 +-2.0 1.0 -2.0 0.0 1.0 +-2.0 1.0 -0.5 1.5 1.0 +-2.0 0.0 -0.5 1.5 0.0 + +// C2 + +-2.0 1.0 2.0 2.0 1.0 +-2.0 0.0 2.0 2.0 0.0 +-2.0 0.0 0.5 0.5 0.0 +-2.0 1.0 2.0 2.0 1.0 +-2.0 1.0 0.5 0.5 1.0 +-2.0 0.0 0.5 0.5 0.0 + +// D1 + +2.0 1.0 -2.0 0.0 1.0 +2.0 0.0 -2.0 0.0 0.0 +2.0 0.0 -0.5 1.5 0.0 +2.0 1.0 -2.0 0.0 1.0 +2.0 1.0 -0.5 1.5 1.0 +2.0 0.0 -0.5 1.5 0.0 + +// D2 + +2.0 1.0 2.0 2.0 1.0 +2.0 0.0 2.0 2.0 0.0 +2.0 0.0 0.5 0.5 0.0 +2.0 1.0 2.0 2.0 1.0 +2.0 1.0 0.5 0.5 1.0 +2.0 0.0 0.5 0.5 0.0 + +// Upper hallway - L +-0.5 1.0 -3.0 0.0 1.0 +-0.5 0.0 -3.0 0.0 0.0 +-0.5 0.0 -2.0 1.0 0.0 +-0.5 1.0 -3.0 0.0 1.0 +-0.5 1.0 -2.0 1.0 1.0 +-0.5 0.0 -2.0 1.0 0.0 + +// Upper hallway - R +0.5 1.0 -3.0 0.0 1.0 +0.5 0.0 -3.0 0.0 0.0 +0.5 0.0 -2.0 1.0 0.0 +0.5 1.0 -3.0 0.0 1.0 +0.5 1.0 -2.0 1.0 1.0 +0.5 0.0 -2.0 1.0 0.0 + +// Lower hallway - L +-0.5 1.0 3.0 0.0 1.0 +-0.5 0.0 3.0 0.0 0.0 +-0.5 0.0 2.0 1.0 0.0 +-0.5 1.0 3.0 0.0 1.0 +-0.5 1.0 2.0 1.0 1.0 +-0.5 0.0 2.0 1.0 0.0 + +// Lower hallway - R +0.5 1.0 3.0 0.0 1.0 +0.5 0.0 3.0 0.0 0.0 +0.5 0.0 2.0 1.0 0.0 +0.5 1.0 3.0 0.0 1.0 +0.5 1.0 2.0 1.0 1.0 +0.5 0.0 2.0 1.0 0.0 + + +// Left hallway - Lw + +-3.0 1.0 0.5 1.0 1.0 +-3.0 0.0 0.5 1.0 0.0 +-2.0 0.0 0.5 0.0 0.0 +-3.0 1.0 0.5 1.0 1.0 +-2.0 1.0 0.5 0.0 1.0 +-2.0 0.0 0.5 0.0 0.0 + +// Left hallway - Hi + +-3.0 1.0 -0.5 1.0 1.0 +-3.0 0.0 -0.5 1.0 0.0 +-2.0 0.0 -0.5 0.0 0.0 +-3.0 1.0 -0.5 1.0 1.0 +-2.0 1.0 -0.5 0.0 1.0 +-2.0 0.0 -0.5 0.0 0.0 + +// Right hallway - Lw + +3.0 1.0 0.5 1.0 1.0 +3.0 0.0 0.5 1.0 0.0 +2.0 0.0 0.5 0.0 0.0 +3.0 1.0 0.5 1.0 1.0 +2.0 1.0 0.5 0.0 1.0 +2.0 0.0 0.5 0.0 0.0 + +// Right hallway - Hi + +3.0 1.0 -0.5 1.0 1.0 +3.0 0.0 -0.5 1.0 0.0 +2.0 0.0 -0.5 0.0 0.0 +3.0 1.0 -0.5 1.0 1.0 +2.0 1.0 -0.5 0.0 1.0 +2.0 0.0 -0.5 0.0 0.0 \ No newline at end of file