diff --git a/GL/flush.c b/GL/flush.c index ce4fce4..0b9dd8b 100644 --- a/GL/flush.c +++ b/GL/flush.c @@ -41,7 +41,7 @@ static void pvr_list_submit(void *src, int n) { static void _glInitPVR() { pvr_init_params_t params = { /* Enable opaque and translucent polygons with size 32 and 32 */ - { PVR_BINSIZE_32, PVR_BINSIZE_0, PVR_BINSIZE_32, PVR_BINSIZE_0, PVR_BINSIZE_32 }, + {PVR_BINSIZE_32, PVR_BINSIZE_0, PVR_BINSIZE_32, PVR_BINSIZE_0, PVR_BINSIZE_32}, PVR_VERTEX_BUF_SIZE, /* Vertex buffer size */ 0, /* No DMA */ 0, /* No FSAA */ @@ -55,6 +55,8 @@ static void _glInitPVR() { PolyList* _glActivePolyList() { if(_glIsBlendingEnabled()) { return &TR_LIST; + } else if(_glIsAlphaTestEnabled()) { + return &PT_LIST; } else { return &OP_LIST; } diff --git a/GL/private.h b/GL/private.h index e7258fe..7465bc5 100644 --- a/GL/private.h +++ b/GL/private.h @@ -152,6 +152,8 @@ GLboolean _glIsSharedTexturePaletteEnabled(); void _glApplyColorTable(TexturePalette *palette); GLboolean _glIsBlendingEnabled(); +GLboolean _glIsAlphaTestEnabled(); + GLboolean _glIsMipmapComplete(const TextureObject* obj); GLubyte* _glGetMipmapLocation(TextureObject* obj, GLuint level); GLuint _glGetMipmapLevelCount(TextureObject* obj); diff --git a/GL/state.c b/GL/state.c index 879c7e0..50a5656 100644 --- a/GL/state.c +++ b/GL/state.c @@ -30,6 +30,9 @@ static GLboolean COLOR_MATERIAL_ENABLED = GL_FALSE; /* Is the shared texture palette enabled? */ static GLboolean SHARED_PALETTE_ENABLED = GL_FALSE; +static GLboolean ALPHA_TEST_ENABLED = GL_FALSE; + + GLboolean _glIsSharedTexturePaletteEnabled() { return SHARED_PALETTE_ENABLED; } @@ -84,6 +87,10 @@ GLboolean _glIsBlendingEnabled() { return BLEND_ENABLED; } +GLboolean _glIsAlphaTestEnabled() { + return ALPHA_TEST_ENABLED; +} + static int _calcPVRBlendFactor(GLenum factor) { switch(factor) { case GL_ZERO: @@ -311,6 +318,9 @@ GLAPI void APIENTRY glEnable(GLenum cap) { SHARED_PALETTE_ENABLED = GL_TRUE; } break; + case GL_ALPHA_TEST: { + ALPHA_TEST_ENABLED = GL_TRUE; + } break; case GL_LIGHT0: case GL_LIGHT1: case GL_LIGHT2: @@ -362,6 +372,9 @@ GLAPI void APIENTRY glDisable(GLenum cap) { SHARED_PALETTE_ENABLED = GL_FALSE; } break; + case GL_ALPHA_TEST: { + ALPHA_TEST_ENABLED = GL_FALSE; + } break; case GL_LIGHT0: case GL_LIGHT1: case GL_LIGHT2: @@ -457,8 +470,20 @@ GLAPI void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) { _updatePVRBlend(&GL_CONTEXT); } -void glAlphaFunc(GLenum func, GLclampf ref) { - ; +#define PT_ALPHA_REF 0x011c + +GLAPI void APIENTRY glAlphaFunc(GLenum func, GLclampf ref) { + GLenum validFuncs[] = { + GL_GREATER, + 0 + }; + + if(_glCheckValidEnum(func, validFuncs, __func__) != 0) { + return; + } + + GLubyte val = (GLubyte)(ref * 255.0f); + PVR_SET(PT_ALPHA_REF, val); } void glLineWidth(GLfloat width) { diff --git a/GL/texture.c b/GL/texture.c index c58b627..eda9642 100644 --- a/GL/texture.c +++ b/GL/texture.c @@ -822,7 +822,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, } if(!TEXTURE_UNITS[ACTIVE_TEXTURE]) { - _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); + _glKosThrowError(GL_INVALID_OPERATION, __func__); } GLboolean isPaletted = (internalFormat == GL_COLOR_INDEX8_EXT) ? GL_TRUE : GL_FALSE; diff --git a/samples/paletted_pcx/main.c b/samples/paletted_pcx/main.c index d98c5da..8cb52fc 100644 --- a/samples/paletted_pcx/main.c +++ b/samples/paletted_pcx/main.c @@ -15,7 +15,7 @@ KOS_INIT_ROMDISK(romdisk); /* floats for x rotation, y rotation, z rotation */ float xrot, yrot, zrot; -int textures[2]; +int textures[3]; typedef struct { unsigned int height; @@ -131,9 +131,13 @@ int LoadPalettedPCX(const char* filename, Image* image) { // Load Bitmaps And Convert To Textures void LoadGLTextures() { // Load Texture - Image image1; + Image image1, image2; - if (!LoadPalettedPCX("/rd/NeHe.pcx", &image1)) { + if(!LoadPalettedPCX("/rd/NeHe.pcx", &image1)) { + exit(1); + } + + if(!LoadPalettedPCX("/rd/NeHe-Alpha.pcx", &image2)) { exit(1); } @@ -154,7 +158,7 @@ void LoadGLTextures() { glColorTableEXT(GL_SHARED_TEXTURE_PALETTE_1_KOS, GL_RGBA8, image1.palette_width, GL_RGB, GL_UNSIGNED_BYTE, inversed_palette); // Create Texture - glGenTextures(2, textures); + glGenTextures(3, textures); glBindTexture(GL_TEXTURE_2D, textures[0]); // 2d texture (x and y size) glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); // scale linearly when image bigger than texture @@ -165,7 +169,6 @@ void LoadGLTextures() { glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, image1.width, image1.height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, image1.data); glBindTexture(GL_TEXTURE_2D, textures[1]); // 2d texture (x and y size) - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); // scale linearly when image bigger than texture glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); // scale linearly when image smalled than texture @@ -175,6 +178,22 @@ void LoadGLTextures() { // 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image, // border 0 (normal), rgb color data, unsigned byte data, and finally the data itself. glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, image1.width, image1.height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, image1.data); + + glBindTexture(GL_TEXTURE_2D, textures[2]); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + char* new_palette = (char*) malloc(image2.palette_width * 4); + for(i = 0; i < image2.palette_width; ++i) { + new_palette[(i * 4) + 0] = image2.palette[(i * 3) + 0]; + new_palette[(i * 4) + 1] = image2.palette[(i * 3) + 1]; + new_palette[(i * 4) + 2] = image2.palette[(i * 3) + 2]; + new_palette[(i * 4) + 3] = (i == 2) ? 0 : 255; + } + + glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, image2.palette_width, GL_RGBA, GL_UNSIGNED_BYTE, new_palette); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, image2.width, image2.height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, image2.data); } /* A general OpenGL initialization function. Sets all of the initial parameters. */ @@ -184,7 +203,7 @@ void InitGL(int Width, int Height) // We call this right after our OpenG glEnable(GL_TEXTURE_2D); 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 + glDepthFunc(GL_LEQUAL); // The Type Of Depth Test To Do glEnable(GL_DEPTH_TEST); // Enables Depth Testing glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading @@ -262,7 +281,9 @@ void DrawGLScene() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer glLoadIdentity(); // Reset The View - glTranslatef(-1.5f,0.0f,-5.0f); // move 5 units into the screen. + glEnable(GL_SHARED_TEXTURE_PALETTE_EXT); + + glTranslatef(-1.5f,0.0f,-8.0f); // move 5 units into the screen. glPushMatrix(); glRotatef(xrot,1.0f,0.0f,0.0f); // Rotate On The X Axis @@ -279,10 +300,25 @@ void DrawGLScene() DrawPolygon(); glPopMatrix(); + glDisable(GL_SHARED_TEXTURE_PALETTE_EXT); + glBindTexture(GL_TEXTURE_2D, textures[1]); glTranslatef(3.0, 0, 0); DrawPolygon(); + static float x = 0.0f; + x += 0.05f; + if(x > 5.0f) { + x = 0.0f; + } + + glAlphaFunc(GL_GREATER, 0.666f); + glEnable(GL_ALPHA_TEST); + glBindTexture(GL_TEXTURE_2D, textures[2]); + glTranslatef(x - 3.0, 0, 3.0); + DrawPolygon(); + glDisable(GL_ALPHA_TEST); + xrot+=1.5f; // X Axis Rotation yrot+=1.5f; // Y Axis Rotation zrot+=1.5f; // Z Axis Rotation diff --git a/samples/paletted_pcx/romdisk/NeHe-Alpha.pcx b/samples/paletted_pcx/romdisk/NeHe-Alpha.pcx new file mode 100644 index 0000000..e489567 Binary files /dev/null and b/samples/paletted_pcx/romdisk/NeHe-Alpha.pcx differ