void pie_UniTransBoxFill(SDWORD x0,SDWORD y0, SDWORD x1, SDWORD y1, UDWORD rgb, UDWORD transparency) { UDWORD light; // pie_doWeirdBoxFX(x0,y0,x1,y1); // return; if (x0>psRendSurface->clip.right || x1<psRendSurface->clip.left || y0>psRendSurface->clip.bottom || y1<psRendSurface->clip.top) return; if (x0<psRendSurface->clip.left) x0 = psRendSurface->clip.left; if (x1>psRendSurface->clip.right) x1 = psRendSurface->clip.right; if (y0<psRendSurface->clip.top) y0 = psRendSurface->clip.top; if (y1>psRendSurface->clip.bottom) y1 = psRendSurface->clip.bottom; switch (pie_GetRenderEngine()) { case ENGINE_4101: case ENGINE_SR: TransBoxFill(x0,y0,x1,y1); break; case ENGINE_GLIDE: if(pie_SwirlyBoxes()) { pie_doWeirdBoxFX(x0,y0,x1,y1,rgb); } else { gl_IntelTransBoxFill(x0, y0, x1, y1, rgb, transparency); } break; case ENGINE_D3D: if (transparency == 0 ) { transparency = 127; } pie_SetTexturePage(-1); pie_SetRendMode(REND_ALPHA_FLAT); light = (rgb & 0x00ffffff) + (transparency << 24); pie_DrawRect(x0, y0, x1, y1, light, FALSE); default: break; } }
void pie_DrawViewingWindow(Vector3i *v, UDWORD x1, UDWORD y1, UDWORD x2, UDWORD y2, PIELIGHT colour) { CLIP_VERTEX pieVrts[pie_MAX_VERTICES_PER_POLYGON]; SDWORD i; pie_SetTexturePage(TEXPAGE_NONE); pie_SetRendMode(REND_ALPHA); pieVrts[0].pos.x = v[1].x; pieVrts[0].pos.y = v[1].y; //cull triangles with off screen points pieVrts[0].pos.z = INTERFACE_DEPTH; pieVrts[0].u = 0; pieVrts[0].v = 0; pieVrts[0].light = colour; pieVrts[1] = pieVrts[0]; pieVrts[2] = pieVrts[0]; pieVrts[3] = pieVrts[0]; pieVrts[4] = pieVrts[0]; pieVrts[1].pos.x = v[0].x; pieVrts[1].pos.y = v[0].y; pieVrts[2].pos.x = v[2].x; pieVrts[2].pos.y = v[2].y; pieVrts[3].pos.x = v[3].x; pieVrts[3].pos.y = v[3].y; glColor4ub(colour.byte.r, colour.byte.g, colour.byte.b, colour.byte.a >> 1); glBegin(GL_TRIANGLE_FAN); for (i = 0; i < 5; i++) { glVertex2f(pieVrts[i].pos.x, pieVrts[i].pos.y); } glEnd(); glColor4ub(colour.byte.r, colour.byte.g, colour.byte.b, colour.byte.a); glBegin(GL_LINE_STRIP); for (i = 0; i < 5; i++) { glVertex2f(pieVrts[i].pos.x, pieVrts[i].pos.y); } glVertex2f(pieVrts[0].pos.x, pieVrts[0].pos.y); glEnd(); }
void pie_TransColouredTriangle(Vector3f *vrt, PIELIGHT c) { UDWORD i; pie_SetTexturePage(TEXPAGE_NONE); pie_SetRendMode(REND_ADDITIVE); glColor4ub(c.byte.r, c.byte.g, c.byte.b, 128); glBegin(GL_TRIANGLE_FAN); for (i = 0; i < 3; ++i) { glVertex3f(vrt[i].x, vrt[i].y, vrt[i].z); } glEnd(); }
static void pie_DrawShadows(void) { const float width = pie_GetVideoBufferWidth(); const float height = pie_GetVideoBufferHeight(); pie_SetTexturePage(TEXPAGE_NONE); glPushMatrix(); pie_SetAlphaTest(false); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glDepthFunc(GL_LESS); glDepthMask(GL_FALSE); glEnable(GL_STENCIL_TEST); ShadowStencilFunc(); pie_SetRendMode(REND_ALPHA); glEnable(GL_CULL_FACE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilMask(~0); glStencilFunc(GL_LESS, 0, ~0); glColor4f(0, 0, 0, 0.5); pie_PerspectiveEnd(); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glBegin(GL_TRIANGLE_STRIP); glVertex2f(0, 0); glVertex2f(width, 0); glVertex2f(0, height); glVertex2f(width, height); glEnd(); pie_PerspectiveBegin(); pie_SetRendMode(REND_OPAQUE); glDisable(GL_STENCIL_TEST); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glPopMatrix(); scshapes.clear(); }
// Generate a new texture page both in the texture page table, and on the graphics card static int newPage(const char *name, int level, int width, int height, int count) { int texPage = firstPage + ((count + 1) / TILES_IN_PAGE); // debug(LOG_TEXTURE, "newPage: texPage=%d firstPage=%d %s %d (%d,%d) (count %d + 1) / %d _TEX_INDEX=%u", // texPage, firstPage, name, level, width, height, count, TILES_IN_PAGE, _TEX_INDEX); if (texPage == _TEX_INDEX) { // We need to create a new texture page; create it and increase texture table to store it glGenTextures(1, &_TEX_PAGE[texPage].id); _TEX_INDEX++; } terrainPage = texPage; ASSERT(_TEX_INDEX > texPage, "newPage: Index too low (%d > %d)", _TEX_INDEX, texPage); ASSERT(_TEX_INDEX < iV_TEX_MAX, "Too many texture pages used"); sstrcpy(_TEX_PAGE[texPage].name, name); pie_SetTexturePage(texPage); // Specify first and last mipmap level to be used glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipmap_levels - 1); // debug(LOG_TEXTURE, "newPage: glTexImage2D(page=%d, level=%d) opengl id=%u", texPage, level, _TEX_PAGE[texPage].id); glTexImage2D(GL_TEXTURE_2D, level, wz_texture_compression, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Use anisotropic filtering, if available, but only max 4.0 to reduce processor burden if (GLEW_EXT_texture_filter_anisotropic) { GLfloat max; glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, MIN(4.0f, max)); } return texPage; }
static void pie_Draw3DButton(iIMDShape *shape, PIELIGHT teamcolour) { const PIELIGHT colour = WZCOL_WHITE; pie_SetFogStatus(false); pie_SetDepthBufferStatus(DEPTH_CMP_LEQ_WRT_ON); SHADER_PROGRAM &program = pie_ActivateShader(SHADER_BUTTON, shape, teamcolour, colour); pie_SetRendMode(REND_OPAQUE); pie_SetTexturePage(shape->texpage); enableArray(shape->buffers[VBO_VERTEX], program.locVertex, 3, GL_FLOAT, false, 0, 0); enableArray(shape->buffers[VBO_NORMAL], program.locNormal, 3, GL_FLOAT, false, 0, 0); enableArray(shape->buffers[VBO_TEXCOORD], program.locTexCoord, 2, GL_FLOAT, false, 0, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shape->buffers[VBO_INDEX]); glDrawElements(GL_TRIANGLES, shape->npolys * 3, GL_UNSIGNED_SHORT, NULL); disableArrays(); polyCount += shape->npolys; pie_DeactivateShader(); pie_SetDepthBufferStatus(DEPTH_CMP_ALWAYS_WRT_ON); }
void iV_Box2(int x0, int y0, int x1, int y1, PIELIGHT first, PIELIGHT second) { pie_SetTexturePage(TEXPAGE_NONE); glColor4ubv(first.vector); glBegin(GL_LINES); glVertex2i(x0, y1); glVertex2i(x0, y0); glVertex2i(x0, y0); glVertex2i(x1, y0); glEnd(); glColor4ubv(second.vector); glBegin(GL_LINES); glVertex2i(x1, y0); glVertex2i(x1, y1); glVertex2i(x0, y1); glVertex2i(x1, y1); glEnd(); }
void pie_BoxFillIndex(int x0,int y0, int x1, int y1, UBYTE colour) { PIELIGHT light; iColour* psPalette; pie_SetRendMode(REND_FLAT); pie_SetTexturePage(-1); if (x0>psRendSurface->clip.right || x1<psRendSurface->clip.left || y0>psRendSurface->clip.bottom || y1<psRendSurface->clip.top) return; if (x0<psRendSurface->clip.left) x0 = psRendSurface->clip.left; if (x1>psRendSurface->clip.right) x1 = psRendSurface->clip.right; if (y0<psRendSurface->clip.top) y0 = psRendSurface->clip.top; if (y1>psRendSurface->clip.bottom) y1 = psRendSurface->clip.bottom; switch (pie_GetRenderEngine()) { case ENGINE_4101: case ENGINE_SR: iV_pBoxFill(x0,y0,x1,y1,colour); break; case ENGINE_GLIDE: gl_BoxFill(x0, y0, x1, y1, colour); break; case ENGINE_D3D: /* Get our colour values from the ivis palette */ psPalette = pie_GetGamePal(); light.byte.r = psPalette[colour].r; light.byte.g = psPalette[colour].g; light.byte.b = psPalette[colour].b; light.byte.a = MAX_UB_LIGHT; pie_DrawRect(x0, y0, x1, y1, light.argb, FALSE); default: break; } }
void iV_ShadowBox(int x0, int y0, int x1, int y1, int pad, PIELIGHT first, PIELIGHT second, PIELIGHT fill) { pie_SetRendMode(REND_OPAQUE); pie_SetTexturePage(TEXPAGE_NONE); pie_DrawRect(x0 + pad, y0 + pad, x1 - pad, y1 - pad, fill); // necessary side-effect: sets alpha test off glColor4ubv(first.vector); glBegin(GL_LINES); glVertex2i(x0, y1); glVertex2i(x0, y0); glVertex2i(x0, y0); glVertex2i(x1, y0); glEnd(); glColor4ubv(second.vector); glBegin(GL_LINES); glVertex2i(x1, y0); glVertex2i(x1, y1); glVertex2i(x0, y1); glVertex2i(x1, y1); glEnd(); }
void iV_DrawTextRotated(const char* string, float XPos, float YPos, float rotation) { pie_SetTexturePage(TEXPAGE_EXTERN); glDisable(GL_CULL_FACE); QPainter painter(WzMainWindow::instance()->context()->device()); painter.setPen(fontColor); if (rotation != 0.f) { painter.translate(XPos, YPos); painter.rotate(rotation); painter.drawText(0, 0, QString::fromUtf8(string)); } else { painter.drawText(XPos, YPos, QString::fromUtf8(string)); } painter.end(); glEnable(GL_CULL_FACE); rendStatesRendModeHack(); // rendStates.rendMode = REND_ALPHA; pie_SetRendMode(REND_OPAQUE); // beat state machinery into submission }
void screen_SetBackDropFromFile(const char* filename) { // HACK : We should use a resource handler here! const char *extension = strrchr(filename, '.');// determine the filetype iV_Image image; if(!extension) { debug(LOG_ERROR, "Image without extension: \"%s\"!", filename); return; // filename without extension... don't bother } // Make sure the current texture page is reloaded after we are finished // Otherwise WZ will think it is still loaded and not load it again pie_SetTexturePage(TEXPAGE_EXTERN); if( strcmp(extension,".png") == 0 ) { if (iV_loadImage_PNG( filename, &image ) ) { if (~backDropTexture == 0) glGenTextures(1, &backDropTexture); glBindTexture(GL_TEXTURE_2D, backDropTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0, iV_getPixelFormat(&image), GL_UNSIGNED_BYTE, image.bmp); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); iV_unloadImage(&image); } return; } else debug(LOG_ERROR, "Unknown extension \"%s\" for image \"%s\"!", extension, filename); }
void pie_BoxFill(int x0,int y0, int x1, int y1, uint32 colour) { PIELIGHT light; pie_SetRendMode(REND_FLAT); pie_SetTexturePage(-1); if (x0>psRendSurface->clip.right || x1<psRendSurface->clip.left || y0>psRendSurface->clip.bottom || y1<psRendSurface->clip.top) return; if (x0<psRendSurface->clip.left) x0 = psRendSurface->clip.left; if (x1>psRendSurface->clip.right) x1 = psRendSurface->clip.right; if (y0<psRendSurface->clip.top) y0 = psRendSurface->clip.top; if (y1>psRendSurface->clip.bottom) y1 = psRendSurface->clip.bottom; switch (pie_GetRenderEngine()) { case ENGINE_4101: case ENGINE_SR: light.argb = colour; iV_pBoxFill(x0,y0,x1,y1,pal_GetNearestColour(light.byte.r, light.byte.g, light.byte.b)); break; case ENGINE_GLIDE: gl_IntelTransBoxFill(x0,y0,x1,y1,colour, MAX_UB_LIGHT); break; case ENGINE_D3D: /* Get our colour values from the ivis palette */ light.argb = colour; light.byte.a = MAX_UB_LIGHT; pie_DrawRect(x0, y0, x1, y1, light.argb, FALSE); default: break; } }
void pie_ActivateShader_TCMask(PIELIGHT teamcolour, int maskpage) { GLfloat colour4f[4]; pie_SetShader(SHADER_COMPONENT); pal_PIELIGHTtoRGBA4f(&colour4f[0], teamcolour); glUniform4fv(locTeam, 1, &colour4f[0]); glUniform1f(locStretch, shaderStretch); glUniform1i(locTCMask, maskpage != iV_TEX_INVALID); glUniform1i(locFog, rendStates.fog); if (maskpage != iV_TEX_INVALID) { glActiveTexture(GL_TEXTURE1); pie_SetTexturePage(maskpage); } glActiveTexture(GL_TEXTURE0); #ifdef _DEBUG glErrors(); #endif }
void iV_DrawTextRotated(const char *string, float XPos, float YPos, float rotation) { GLint matrix_mode = 0; ASSERT_OR_RETURN(, string, "Couldn't render string!"); pie_SetTexturePage(TEXPAGE_EXTERN); glGetIntegerv(GL_MATRIX_MODE, &matrix_mode); glMatrixMode(GL_TEXTURE); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); if (rotation != 0.f) { rotation = 360.f - rotation; } glTranslatef(XPos, YPos, 0.f); glRotatef(180.f, 1.f, 0.f, 0.f); glRotatef(rotation, 0.f, 0.f, 1.f); glScalef(font_size, font_size, 0.f); glColor4fv(font_colour); glFrontFace(GL_CW); glcRenderString(string); glFrontFace(GL_CCW); glPopMatrix(); glMatrixMode(GL_TEXTURE); glPopMatrix(); glMatrixMode(matrix_mode); // Reset the current model view matrix glLoadIdentity(); }
// Generate a new texture page both in the texture page table, and on the graphics card static int newPage(const char *name, int level, int width, int height, int count) { int texPage = firstPage + ((count + 1) / TILES_IN_PAGE); if (texPage == pie_NumberOfPages()) { // We need to create a new texture page; create it and increase texture table to store it pie_ReserveTexture(name, width, height); pie_AssignTexture(texPage, gfx_api::context::get().create_texture(width, height, wz_texture_compression ? gfx_api::pixel_format::compressed_rgba : gfx_api::pixel_format::rgba)); } terrainPage = texPage; pie_SetTexturePage(texPage); // Specify first and last mipmap level to be used glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipmap_levels - 1); // debug(LOG_TEXTURE, "newPage: glTexImage2D(page=%d, level=%d) opengl id=%u", texPage, level, _TEX_PAGE[texPage].id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Use anisotropic filtering, if available, but only max 4.0 to reduce processor burden if (GLEW_EXT_texture_filter_anisotropic) { GLfloat max; glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, MIN(4.0f, max)); } return texPage; }
static void pie_Draw3DButton(iIMDShape *shape, PIELIGHT teamcolour) { const PIELIGHT colour = WZCOL_WHITE; pie_SetFogStatus(false); pie_SetDepthBufferStatus(DEPTH_CMP_LEQ_WRT_ON); pie_ActivateShader(SHADER_BUTTON, shape, teamcolour, colour); pie_SetRendMode(REND_OPAQUE); glColor4ubv(colour.vector); // Only need to set once for entire model pie_SetTexturePage(shape->texpage); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, shape->buffers[VBO_VERTEX]); glVertexPointer(3, GL_FLOAT, 0, NULL); glBindBuffer(GL_ARRAY_BUFFER, shape->buffers[VBO_NORMAL]); glNormalPointer(GL_FLOAT, 0, NULL); glBindBuffer(GL_ARRAY_BUFFER, shape->buffers[VBO_TEXCOORD]); glTexCoordPointer(2, GL_FLOAT, 0, NULL); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shape->buffers[VBO_INDEX]); glDrawElements(GL_TRIANGLES, shape->npolys * 3, GL_UNSIGNED_SHORT, NULL); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); polyCount += shape->npolys; pie_DeactivateShader(); pie_SetDepthBufferStatus(DEPTH_CMP_ALWAYS_WRT_ON); }
static void pie_DrawImage(IMAGEFILE *imageFile, int id, Vector2i size, const PIERECT *dest, PIELIGHT colour = WZCOL_WHITE) { ImageDef const &image2 = imageFile->imageDefs[id]; GLuint texPage = imageFile->pages[image2.TPageID].id; GLfloat invTextureSize = 1.f / imageFile->pages[image2.TPageID].size; int tu = image2.Tu; int tv = image2.Tv; pie_SetTexturePage(texPage); glColor4ubv(colour.vector); glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(tu * invTextureSize, tv * invTextureSize); glVertex2f(dest->x, dest->y); glTexCoord2f((tu + size.x) * invTextureSize, tv * invTextureSize); glVertex2f(dest->x + dest->w, dest->y); glTexCoord2f(tu * invTextureSize, (tv + size.y) * invTextureSize); glVertex2f(dest->x, dest->y + dest->h); glTexCoord2f((tu + size.x) * invTextureSize, (tv + size.y) * invTextureSize); glVertex2f(dest->x + dest->w, dest->y + dest->h); glEnd(); }
void pie_DrawImage(const PIEIMAGE *image, const PIERECT *dest, PIELIGHT colour) { /* Set transparent color to be 0 red, 0 green, 0 blue, 0 alpha */ polyCount++; pie_SetTexturePage(image->texPage); glColor4ubv(colour.vector); glBegin(GL_TRIANGLE_STRIP); //set up 4 pie verts glTexCoord2f(image->tu * image->invTextureSize, image->tv * image->invTextureSize); glVertex2f(dest->x, dest->y); glTexCoord2f((image->tu + image->tw) * image->invTextureSize, image->tv * image->invTextureSize); glVertex2f(dest->x + dest->w, dest->y); glTexCoord2f(image->tu * image->invTextureSize, (image->tv + image->th) * image->invTextureSize); glVertex2f(dest->x, dest->y + dest->h); glTexCoord2f((image->tu + image->tw) * image->invTextureSize, (image->tv + image->th) * image->invTextureSize); glVertex2f(dest->x + dest->w, dest->y + dest->h); glEnd(); }
void pie_UniTransBoxFill(float x0, float y0, float x1, float y1, PIELIGHT light) { pie_SetTexturePage(TEXPAGE_NONE); pie_SetRendMode(REND_ALPHA); pie_DrawRect(x0, y0, x1, y1, light); }
static void pie_Draw3DShape2(const iIMDShape *shape, int frame, PIELIGHT colour, PIELIGHT teamcolour, int pieFlag, int pieFlagData, glm::mat4 const &matrix) { bool light = true; /* Set fog status */ if (!(pieFlag & pie_FORCE_FOG) && (pieFlag & pie_ADDITIVE || pieFlag & pie_TRANSLUCENT || pieFlag & pie_PREMULTIPLIED)) { pie_SetFogStatus(false); } else { pie_SetFogStatus(true); } /* Set tranlucency */ if (pieFlag & pie_ADDITIVE) { pie_SetRendMode(REND_ADDITIVE); colour.byte.a = (UBYTE)pieFlagData; light = false; } else if (pieFlag & pie_TRANSLUCENT) { pie_SetRendMode(REND_ALPHA); colour.byte.a = (UBYTE)pieFlagData; light = false; } else if (pieFlag & pie_PREMULTIPLIED) { pie_SetRendMode(REND_PREMULTIPLIED); light = false; } else { pie_SetRendMode(REND_OPAQUE); } if (pieFlag & pie_ECM) { pie_SetRendMode(REND_ALPHA); light = true; pie_SetShaderEcmEffect(true); } glm::vec4 sceneColor(lighting0[LIGHT_EMISSIVE][0], lighting0[LIGHT_EMISSIVE][1], lighting0[LIGHT_EMISSIVE][2], lighting0[LIGHT_EMISSIVE][3]); glm::vec4 ambient(lighting0[LIGHT_AMBIENT][0], lighting0[LIGHT_AMBIENT][1], lighting0[LIGHT_AMBIENT][2], lighting0[LIGHT_AMBIENT][3]); glm::vec4 diffuse(lighting0[LIGHT_DIFFUSE][0], lighting0[LIGHT_DIFFUSE][1], lighting0[LIGHT_DIFFUSE][2], lighting0[LIGHT_DIFFUSE][3]); glm::vec4 specular(lighting0[LIGHT_SPECULAR][0], lighting0[LIGHT_SPECULAR][1], lighting0[LIGHT_SPECULAR][2], lighting0[LIGHT_SPECULAR][3]); SHADER_MODE mode = shape->shaderProgram == SHADER_NONE ? light ? SHADER_COMPONENT : SHADER_NOLIGHT : shape->shaderProgram; pie_internal::SHADER_PROGRAM &program = pie_ActivateShaderDeprecated(mode, shape, teamcolour, colour, matrix, pie_PerspectiveGet(), glm::vec4(currentSunPosition, 0.f), sceneColor, ambient, diffuse, specular); if (program.locations.size() >= 9) glUniform1i(program.locations[8], (pieFlag & pie_PREMULTIPLIED) == 0); pie_SetTexturePage(shape->texpage); frame %= std::max<int>(1, shape->numFrames); enableArray(shape->buffers[VBO_VERTEX], program.locVertex, 3, GL_FLOAT, false, 0, 0); enableArray(shape->buffers[VBO_NORMAL], program.locNormal, 3, GL_FLOAT, false, 0, 0); enableArray(shape->buffers[VBO_TEXCOORD], program.locTexCoord, 2, GL_FLOAT, false, 0, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shape->buffers[VBO_INDEX]); glDrawElements(GL_TRIANGLES, shape->npolys * 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(frame * shape->npolys * 3 * sizeof(uint16_t))); disableArrays(); polyCount += shape->npolys; pie_SetShaderEcmEffect(false); pie_DeactivateShader(); }
void pie_BoxFill(int x0,int y0, int x1, int y1, PIELIGHT colour) { pie_SetRendMode(REND_OPAQUE); pie_SetTexturePage(TEXPAGE_NONE); pie_DrawRect(x0, y0, x1, y1, colour); }
/** * Draw the water. */ void drawWater(const glm::mat4 &viewMatrix) { int x, y; const glm::vec4 paramsX(0, 0, -1.0f / world_coord(4), 0); const glm::vec4 paramsY(1.0f / world_coord(4), 0, 0, 0); const glm::vec4 paramsX2(0, 0, -1.0f / world_coord(5), 0); const glm::vec4 paramsY2(1.0f / world_coord(5), 0, 0, 0); const auto &renderState = getCurrentRenderState(); const auto &program = pie_ActivateShader(SHADER_WATER, viewMatrix, paramsX, paramsY, paramsX2, paramsY2, 0, 1, glm::translate(glm::vec3(waterOffset, 0.f, 0.f)), glm::mat4(1.f), renderState.fogEnabled, renderState.fogBegin, renderState.fogEnd); glDepthMask(GL_FALSE); // first texture unit pie_SetTexturePage(iV_GetTexture("page-80-water-1.png")); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // multiplicative blending pie_SetRendMode(REND_MULTIPLICATIVE); // second texture unit glActiveTexture(GL_TEXTURE1); pie_Texture(iV_GetTexture("page-81-water-2.png")).bind(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // bind the vertex buffer waterIndexVBO->bind(); waterVBO->bind(); glVertexAttribPointer(program.locVertex, 3, GL_FLOAT, GL_FALSE, sizeof(RenderVertex), BUFFER_OFFSET(0)); glEnableVertexAttribArray(program.locVertex); for (x = 0; x < xSectors; x++) { for (y = 0; y < ySectors; y++) { if (sectors[x * ySectors + y].draw) { addDrawRangeElements(GL_TRIANGLES, sectors[x * ySectors + y].geometryOffset, sectors[x * ySectors + y].geometryOffset + sectors[x * ySectors + y].geometrySize, sectors[x * ySectors + y].waterIndexSize, GL_UNSIGNED_INT, sectors[x * ySectors + y].waterIndexOffset); } } } finishDrawRangeElements(); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glDisableVertexAttribArray(program.locVertex); // move the water if (!gamePaused()) { waterOffset += graphicsTimeAdjustedIncrement(0.1f); } // disable second texture glActiveTexture(GL_TEXTURE0); // clean up glDepthMask(GL_TRUE); pie_DeactivateShader(); //glBindBuffer(GL_ARRAY_BUFFER, 0); // HACK Must unbind GL_ARRAY_BUFFER (don't know if it has to be unbound everywhere), otherwise text rendering may mysteriously crash. }
static void drawTerrainLayers(const glm::mat4 &ModelViewProjection, const glm::vec4 ¶msXLight, const glm::vec4 ¶msYLight, const glm::mat4 &textureMatrix) { const auto &renderState = getCurrentRenderState(); const glm::vec4 fogColor( renderState.fogColour.vector[0] / 255.f, renderState.fogColour.vector[1] / 255.f, renderState.fogColour.vector[2] / 255.f, renderState.fogColour.vector[3] / 255.f ); const auto &program = pie_ActivateShader(SHADER_TERRAIN, ModelViewProjection, glm::vec4(0.f), glm::vec4(0.f), paramsXLight, paramsYLight, 0, 1, glm::mat4(1.f), textureMatrix, renderState.fogEnabled, renderState.fogBegin, renderState.fogEnd, fogColor); // additive blending pie_SetRendMode(REND_ADDITIVE); // only draw colors glDepthMask(GL_FALSE); textureIndexVBO->bind(); // load the vertex (geometry) buffer geometryVBO->bind(); glVertexAttribPointer(program.locVertex, 3, GL_FLOAT, GL_FALSE, sizeof(RenderVertex), BUFFER_OFFSET(0)); glEnableVertexAttribArray(program.locVertex); textureVBO->bind(); ASSERT_OR_RETURN(, psGroundTypes, "Ground type was not set, no textures will be seen."); // draw each layer separately for (int layer = 0; layer < numGroundTypes; layer++) { const glm::vec4 paramsX(0, 0, -1.0f / world_coord(psGroundTypes[layer].textureSize), 0 ); const glm::vec4 paramsY(1.0f / world_coord(psGroundTypes[layer].textureSize), 0, 0, 0 ); pie_ActivateShader(SHADER_TERRAIN, ModelViewProjection, paramsX, paramsY, paramsXLight, paramsYLight, 0, 1, glm::mat4(1.f), textureMatrix, renderState.fogEnabled, renderState.fogBegin, renderState.fogEnd, fogColor); // load the texture int texPage = iV_GetTexture(psGroundTypes[layer].textureName); pie_SetTexturePage(texPage); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // load the color buffer glVertexAttribPointer(program.locColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(PIELIGHT), BUFFER_OFFSET(sizeof(PIELIGHT)*xSectors * ySectors * (sectorSize + 1) * (sectorSize + 1) * 2 * layer)); glEnableVertexAttribArray(program.locColor); for (int x = 0; x < xSectors; x++) { for (int y = 0; y < ySectors; y++) { if (sectors[x * ySectors + y].draw) { addDrawRangeElements(GL_TRIANGLES, sectors[x * ySectors + y].geometryOffset, sectors[x * ySectors + y].geometryOffset + sectors[x * ySectors + y].geometrySize, sectors[x * ySectors + y].textureIndexSize[layer], GL_UNSIGNED_INT, sectors[x * ySectors + y].textureIndexOffset[layer]); } } } finishDrawRangeElements(); } glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // we don't need this one anymore glDisableVertexAttribArray(program.locVertex); glDisableVertexAttribArray(program.locColor); pie_DeactivateShader(); }
static void pie_DrawShadows(void) { const float width = pie_GetVideoBufferWidth(); const float height = pie_GetVideoBufferHeight(); GLenum op_depth_pass_front = GL_INCR, op_depth_pass_back = GL_DECR; pie_SetTexturePage(TEXPAGE_NONE); glPushMatrix(); pie_SetAlphaTest(false); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glDepthFunc(GL_LESS); glDepthMask(GL_FALSE); glEnable(GL_STENCIL_TEST); // Check if we have the required extensions if (GLEE_EXT_stencil_wrap) { op_depth_pass_front = GL_INCR_WRAP_EXT; op_depth_pass_back = GL_DECR_WRAP_EXT; } // generic 1-pass version if (GLEE_EXT_stencil_two_side) { glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT); glDisable(GL_CULL_FACE); glStencilMask(~0); glActiveStencilFaceEXT(GL_BACK); glStencilOp(GL_KEEP, GL_KEEP, op_depth_pass_back); glStencilFunc(GL_ALWAYS, 0, ~0); glActiveStencilFaceEXT(GL_FRONT); glStencilOp(GL_KEEP, GL_KEEP, op_depth_pass_front); glStencilFunc(GL_ALWAYS, 0, ~0); pie_ShadowDrawLoop(); glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT); } // check for ATI-specific 1-pass version else if (GLEE_ATI_separate_stencil) { glDisable(GL_CULL_FACE); glStencilMask(~0); glStencilOpSeparateATI(GL_BACK, GL_KEEP, GL_KEEP, op_depth_pass_back); glStencilOpSeparateATI(GL_FRONT, GL_KEEP, GL_KEEP, op_depth_pass_front); glStencilFunc(GL_ALWAYS, 0, ~0); pie_ShadowDrawLoop(); } // fall back to default 2-pass version else { glStencilMask(~0); glStencilFunc(GL_ALWAYS, 0, ~0); glEnable(GL_CULL_FACE); // Setup stencil for front-facing polygons glCullFace(GL_BACK); glStencilOp(GL_KEEP, GL_KEEP, op_depth_pass_front); pie_ShadowDrawLoop(); // Setup stencil for back-facing polygons glCullFace(GL_FRONT); glStencilOp(GL_KEEP, GL_KEEP, op_depth_pass_back); pie_ShadowDrawLoop(); } pie_SetRendMode(REND_ALPHA); glEnable(GL_CULL_FACE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilMask(~0); glStencilFunc(GL_LESS, 0, ~0); glColor4f(0, 0, 0, 0.5); pie_PerspectiveEnd(); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glBegin(GL_TRIANGLE_STRIP); glVertex2f(0, 0); glVertex2f(width, 0); glVertex2f(0, height); glVertex2f(width, height); glEnd(); pie_PerspectiveBegin(); pie_SetRendMode(REND_OPAQUE); glDisable(GL_STENCIL_TEST); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glPopMatrix(); nb_scshapes = 0; }
static void pie_Draw3DShape2(iIMDShape *shape, int frame, PIELIGHT colour, PIELIGHT teamcolour, WZ_DECL_UNUSED PIELIGHT specular, int pieFlag, int pieFlagData) { iIMDPoly *pPolys; bool light = lighting; pie_SetAlphaTest(true); /* Set fog status */ if (!(pieFlag & pie_FORCE_FOG) && (pieFlag & pie_ADDITIVE || pieFlag & pie_TRANSLUCENT || pieFlag & pie_BUTTON)) { pie_SetFogStatus(false); } else { pie_SetFogStatus(true); } /* Set tranlucency */ if (pieFlag & pie_ADDITIVE) { pie_SetRendMode(REND_ADDITIVE); colour.byte.a = (UBYTE)pieFlagData; light = false; } else if (pieFlag & pie_TRANSLUCENT) { pie_SetRendMode(REND_ALPHA); colour.byte.a = (UBYTE)pieFlagData; light = false; } else { if (pieFlag & pie_BUTTON) { pie_SetDepthBufferStatus(DEPTH_CMP_LEQ_WRT_ON); } pie_SetRendMode(REND_OPAQUE); } if (light) { const float ambient[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; const float diffuse[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; const float specular[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; const float shininess = 10; glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess); } if (pieFlag & pie_HEIGHT_SCALED) // construct { glScalef(1.0f, (float)pieFlagData / (float)pie_RAISE_SCALE, 1.0f); } if (pieFlag & pie_RAISE) // collapse { glTranslatef(1.0f, (-shape->max.y * (pie_RAISE_SCALE - pieFlagData)) / pie_RAISE_SCALE, 1.0f); } glColor4ubv(colour.vector); // Only need to set once for entire model pie_SetTexturePage(shape->texpage); // Activate TCMask if needed if (shape->flags & iV_IMD_TCMASK && rendStates.rendMode == REND_OPAQUE) { #ifdef _DEBUG glErrors(); #endif if (pie_GetShadersStatus()) { pie_ActivateShader_TCMask(teamcolour, shape->tcmaskpage); } else { //Set the environment colour with tcmask GLfloat tc_env_colour[4]; pal_PIELIGHTtoRGBA4f(&tc_env_colour[0], teamcolour); // TU0 glActiveTexture(GL_TEXTURE0); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, tc_env_colour); // TU0 RGB glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD_SIGNED); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); // TU0 Alpha glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); // TU1 glActiveTexture(GL_TEXTURE1); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, _TEX_PAGE[shape->tcmaskpage].id); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); // TU1 RGB glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE0); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA); // TU1 Alpha glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA); // This is why we are doing in opaque mode. glEnable(GL_BLEND); glBlendFunc(GL_CONSTANT_COLOR, GL_ZERO); glBlendColor(colour.byte.r / 255.0, colour.byte.g / 255.0, colour.byte.b / 255.0, colour.byte.a / 255.0); } #ifdef _DEBUG glErrors(); #endif } for (pPolys = shape->polys; pPolys < shape->polys + shape->npolys; pPolys++) { Vector2f texCoords[pie_MAX_VERTICES_PER_POLYGON]; Vector3f vertexCoords[pie_MAX_VERTICES_PER_POLYGON]; unsigned int n; VERTEXID *index; for (n = 0, index = pPolys->pindex; n < pPolys->npnts; n++, index++) { vertexCoords[n].x = shape->points[*index].x; vertexCoords[n].y = shape->points[*index].y; vertexCoords[n].z = shape->points[*index].z; texCoords[n].x = pPolys->texCoord[n].x; texCoords[n].y = pPolys->texCoord[n].y; } polyCount++; // Run TextureAnimation (exluding the new teamcoloured models) if (frame && pPolys->flags & iV_IMD_TEXANIM && !(shape->flags & iV_IMD_TCMASK)) { frame %= shape->numFrames; if (frame > 0) { const int framesPerLine = OLD_TEXTURE_SIZE_FIX / (pPolys->texAnim.x * OLD_TEXTURE_SIZE_FIX); const int uFrame = (frame % framesPerLine) * (pPolys->texAnim.x * OLD_TEXTURE_SIZE_FIX); const int vFrame = (frame / framesPerLine) * (pPolys->texAnim.y * OLD_TEXTURE_SIZE_FIX); for (n = 0; n < pPolys->npnts; n++) { texCoords[n].x += uFrame / OLD_TEXTURE_SIZE_FIX; texCoords[n].y += vFrame / OLD_TEXTURE_SIZE_FIX; } } } glBegin(GL_TRIANGLE_FAN); if (light) { glNormal3fv((GLfloat*)&pPolys->normal); } for (n = 0; n < pPolys->npnts; n++) { glTexCoord2fv((GLfloat*)&texCoords[n]); if (shape->flags & iV_IMD_TCMASK && rendStates.rendMode == REND_OPAQUE && !pie_GetShadersStatus()) { glMultiTexCoord2fv(GL_TEXTURE1, (GLfloat*)&texCoords[n]); } glVertex3fv((GLfloat*)&vertexCoords[n]); } glEnd(); } // Deactivate TCMask if it was previously enabled if (shape->flags & iV_IMD_TCMASK && rendStates.rendMode == REND_OPAQUE) { if (pie_GetShadersStatus()) { pie_DeactivateShader(); } else { glDisable(GL_BLEND); glActiveTexture(GL_TEXTURE1); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_2D); glActiveTexture(GL_TEXTURE0); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } } if (pieFlag & pie_BUTTON) { pie_SetDepthBufferStatus(DEPTH_CMP_ALWAYS_WRT_ON); } if (light) { glDisable(GL_LIGHTING); glDisable(GL_NORMALIZE); } }
/************************************************************************** Add an image buffer given in s as a new texture page in the texture table. We check first if the given image has already been loaded, as a sanity check (should never happen). The texture numbers are stored in a special texture table, not in the resource system, for some unknown reason. Start looking for an available slot in the texture table at the given slot number. Returns the texture number of the image. **************************************************************************/ int pie_AddTexPage(iV_Image *s, const char* filename, int slot, int maxTextureSize, bool useMipmaping) { unsigned int i = 0; int width, height; void *bmp; bool scaleDown = false; GLint minfilter; /* Have we already loaded this one? Should not happen here. */ while (i < _TEX_INDEX) { if (strncmp(filename, _TEX_PAGE[i].name, iV_TEXNAME_MAX) == 0) { pie_PrintLoadedTextures(); } ASSERT(strncmp(filename, _TEX_PAGE[i].name, iV_TEXNAME_MAX) != 0, "pie_AddTexPage: %s loaded again! Already loaded as %s|%u", filename, _TEX_PAGE[i].name, i); i++; } /* Use first unused slot */ for (i = slot; i < iV_TEX_MAX && _TEX_PAGE[i].name[0] != '\0'; i++) {} if (i == _TEX_INDEX) { _TEX_INDEX++; // increase table } ASSERT(i != iV_TEX_MAX, "pie_AddTexPage: too many texture pages"); debug(LOG_TEXTURE, "pie_AddTexPage: %s page=%d", filename, _TEX_INDEX); assert(s != NULL); /* Stick the name into the tex page structures */ sstrcpy(_TEX_PAGE[i].name, filename); glGenTextures(1, &_TEX_PAGE[i].id); // FIXME: This function is used instead of glBindTexture, but we're juggling with difficult to trace global state here. Look into pie_SetTexturePage's definition for details. pie_SetTexturePage(i); width = s->width; height = s->height; bmp = s->bmp; if ((width & (width-1)) == 0 && (height & (height-1)) == 0) { if (maxTextureSize > 0 && width > maxTextureSize) { width = maxTextureSize; scaleDown = true; } if (maxTextureSize > 0 && height > maxTextureSize) { height = maxTextureSize; scaleDown = true; } if (scaleDown) { debug(LOG_TEXTURE, "scaling down texture %s from %ix%i to %ix%i", filename, s->width, s->height, width, height); bmp = malloc(4 * width * height); // FIXME: don't know for sure it is 4 bytes per pixel gluScaleImage(iV_getPixelFormat(s), s->width, s->height, GL_UNSIGNED_BYTE, s->bmp, width, height, GL_UNSIGNED_BYTE, bmp); free(s->bmp); } if (maxTextureSize) { // this is a 3D texture, use texture compression gluBuild2DMipmaps(GL_TEXTURE_2D, wz_texture_compression, width, height, iV_getPixelFormat(s), GL_UNSIGNED_BYTE, bmp); } else { // this is an interface texture, do not use compression gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, width, height, iV_getPixelFormat(s), GL_UNSIGNED_BYTE, bmp); } } else { debug(LOG_ERROR, "pie_AddTexPage: non POT texture %s", filename); } // it is uploaded, we do not need it anymore free(bmp); s->bmp = NULL; if (useMipmaping) { minfilter = GL_LINEAR_MIPMAP_LINEAR; } else { minfilter = GL_LINEAR; } glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Use anisotropic filtering, if available, but only max 4.0 to reduce processor burden if (GLEW_EXT_texture_filter_anisotropic) { GLfloat max; glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, MIN(4.0f, max)); } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); /* Send back the texpage number so we can store it in the IMD */ _TEX_INDEX++; return i; }
void pie_InitSkybox(SDWORD pageNum) { pie_SetTexturePage(pageNum); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); }
static void pie_Draw3DShape2(iIMDShape *shape, int frame, PIELIGHT colour, PIELIGHT teamcolour, int pieFlag, int pieFlagData) { iIMDPoly *pPolys; bool light = true; bool shaders = pie_GetShaderUsage(); pie_SetAlphaTest((pieFlag & pie_PREMULTIPLIED) == 0); /* Set fog status */ if (!(pieFlag & pie_FORCE_FOG) && (pieFlag & pie_ADDITIVE || pieFlag & pie_TRANSLUCENT || pieFlag & pie_BUTTON || pieFlag & pie_PREMULTIPLIED)) { pie_SetFogStatus(false); } else { pie_SetFogStatus(true); } /* Set tranlucency */ if (pieFlag & pie_ADDITIVE) { pie_SetRendMode(REND_ADDITIVE); colour.byte.a = (UBYTE)pieFlagData; light = false; } else if (pieFlag & pie_TRANSLUCENT) { pie_SetRendMode(REND_ALPHA); colour.byte.a = (UBYTE)pieFlagData; light = false; } else if (pieFlag & pie_PREMULTIPLIED) { pie_SetRendMode(REND_PREMULTIPLIED); light = false; } else { if (pieFlag & pie_BUTTON) { pie_SetDepthBufferStatus(DEPTH_CMP_LEQ_WRT_ON); light = false; if (shaders) { pie_ActivateShader(SHADER_BUTTON, shape, teamcolour, colour); } else { pie_ActivateFallback(SHADER_BUTTON, shape, teamcolour, colour); } } pie_SetRendMode(REND_OPAQUE); } if (pieFlag & pie_ECM) { pie_SetRendMode(REND_ALPHA); light = true; pie_SetShaderEcmEffect(true); } if (light) { glMaterialfv(GL_FRONT, GL_AMBIENT, shape->material[LIGHT_AMBIENT]); glMaterialfv(GL_FRONT, GL_DIFFUSE, shape->material[LIGHT_DIFFUSE]); glMaterialfv(GL_FRONT, GL_SPECULAR, shape->material[LIGHT_SPECULAR]); glMaterialf(GL_FRONT, GL_SHININESS, shape->shininess); glMaterialfv(GL_FRONT, GL_EMISSION, shape->material[LIGHT_EMISSIVE]); if (shaders) { pie_ActivateShader(SHADER_COMPONENT, shape, teamcolour, colour); } else { pie_ActivateFallback(SHADER_COMPONENT, shape, teamcolour, colour); } } if (pieFlag & pie_HEIGHT_SCALED) // construct { glScalef(1.0f, (float)pieFlagData / (float)pie_RAISE_SCALE, 1.0f); } if (pieFlag & pie_RAISE) // collapse { glTranslatef(1.0f, (-shape->max.y * (pie_RAISE_SCALE - pieFlagData)) * (1.0f / pie_RAISE_SCALE), 1.0f); } glColor4ubv(colour.vector); // Only need to set once for entire model pie_SetTexturePage(shape->texpage); frame %= MAX(1, shape->numFrames); glBegin(GL_TRIANGLES); for (pPolys = shape->polys; pPolys < shape->polys + shape->npolys; pPolys++) { Vector3f vertexCoords[3]; unsigned int n, frameidx = frame; int *index; if (!(pPolys->flags & iV_IMD_TEXANIM)) { frameidx = 0; } for (n = 0, index = pPolys->pindex; n < pPolys->npnts; n++, index++) { vertexCoords[n].x = shape->points[*index].x; vertexCoords[n].y = shape->points[*index].y; vertexCoords[n].z = shape->points[*index].z; } polyCount++; glNormal3fv((GLfloat*)&pPolys->normal); for (n = 0; n < pPolys->npnts; n++) { GLfloat* texCoord = (GLfloat*)&pPolys->texCoord[frameidx * pPolys->npnts + n]; glTexCoord2fv(texCoord); if (!shaders) { glMultiTexCoord2fv(GL_TEXTURE1, texCoord); } glVertex3fv((GLfloat*)&vertexCoords[n]); } } glEnd(); if (light || (pieFlag & pie_BUTTON)) { if (shaders) { pie_DeactivateShader(); } else { pie_DeactivateFallback(); } } pie_SetShaderEcmEffect(false); if (pieFlag & pie_BUTTON) { pie_SetDepthBufferStatus(DEPTH_CMP_ALWAYS_WRT_ON); } }
pie_internal::SHADER_PROGRAM &pie_ActivateShaderDeprecated(SHADER_MODE shaderMode, const iIMDShape *shape, PIELIGHT teamcolour, PIELIGHT colour, const glm::mat4 &ModelView, const glm::mat4 &Proj, const glm::vec4 &sunPos, const glm::vec4 &sceneColor, const glm::vec4 &ambient, const glm::vec4 &diffuse, const glm::vec4 &specular) { int maskpage = shape->tcmaskpage; int normalpage = shape->normalpage; int specularpage = shape->specularpage; pie_internal::SHADER_PROGRAM &program = pie_internal::shaderProgram[shaderMode]; if (shaderMode != pie_internal::currentShaderMode) { glUseProgram(program.program); // These do not change during our drawing pass glUniform1i(program.locations[4], rendStates.fog); glUniform1f(program.locations[9], timeState); pie_internal::currentShaderMode = shaderMode; } glUniform4fv(program.locations[0], 1, &pal_PIELIGHTtoVec4(colour)[0]); pie_SetTexturePage(shape->texpage); glUniform4fv(program.locations[1], 1, &pal_PIELIGHTtoVec4(teamcolour)[0]); glUniform1i(program.locations[3], maskpage != iV_TEX_INVALID); glUniform1i(program.locations[8], 0); glUniformMatrix4fv(program.locations[10], 1, GL_FALSE, glm::value_ptr(ModelView)); glUniformMatrix4fv(program.locations[11], 1, GL_FALSE, glm::value_ptr(Proj * ModelView)); glUniformMatrix4fv(program.locations[12], 1, GL_FALSE, glm::value_ptr(glm::transpose(glm::inverse(ModelView)))); glUniform4fv(program.locations[13], 1, &sunPos[0]); glUniform4fv(program.locations[14], 1, &sceneColor[0]); glUniform4fv(program.locations[15], 1, &ambient[0]); glUniform4fv(program.locations[16], 1, &diffuse[0]); glUniform4fv(program.locations[17], 1, &specular[0]); glUniform1f(program.locations[18], fogBegin); glUniform1f(program.locations[19], fogEnd); float color[4] = { rendStates.fogColour.vector[0] / 255.f, rendStates.fogColour.vector[1] / 255.f, rendStates.fogColour.vector[2] / 255.f, rendStates.fogColour.vector[3] / 255.f }; glUniform4fv(program.locations[20], 1, color); if (program.locations[2] >= 0) { glUniform1f(program.locations[2], shaderStretch); } if (program.locations[5] >= 0) { glUniform1i(program.locations[5], normalpage != iV_TEX_INVALID); } if (program.locations[6] >= 0) { glUniform1i(program.locations[6], specularpage != iV_TEX_INVALID); } if (program.locations[7] >= 0) { glUniform1i(program.locations[7], ecmState); } if (maskpage != iV_TEX_INVALID) { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, pie_Texture(maskpage)); } if (normalpage != iV_TEX_INVALID) { glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, pie_Texture(normalpage)); } if (specularpage != iV_TEX_INVALID) { glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, pie_Texture(specularpage)); } glActiveTexture(GL_TEXTURE0); return program; }
static void pie_Draw3DShape2(const iIMDShape *shape, int frame, PIELIGHT colour, PIELIGHT teamcolour, int pieFlag, int pieFlagData, glm::mat4 &matrix) { bool light = true; glLoadMatrixf(&matrix[0][0]); /* Set fog status */ if (!(pieFlag & pie_FORCE_FOG) && (pieFlag & pie_ADDITIVE || pieFlag & pie_TRANSLUCENT || pieFlag & pie_PREMULTIPLIED)) { pie_SetFogStatus(false); } else { pie_SetFogStatus(true); } /* Set tranlucency */ if (pieFlag & pie_ADDITIVE) { pie_SetRendMode(REND_ADDITIVE); colour.byte.a = (UBYTE)pieFlagData; light = false; } else if (pieFlag & pie_TRANSLUCENT) { pie_SetRendMode(REND_ALPHA); colour.byte.a = (UBYTE)pieFlagData; light = false; } else if (pieFlag & pie_PREMULTIPLIED) { pie_SetRendMode(REND_PREMULTIPLIED); light = false; } else { pie_SetRendMode(REND_OPAQUE); } if ((pieFlag & pie_PREMULTIPLIED) == 0) { glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.001f); } if (pieFlag & pie_ECM) { pie_SetRendMode(REND_ALPHA); light = true; pie_SetShaderEcmEffect(true); } if (light) { if (shape->shaderProgram) { pie_ActivateShader(shape->shaderProgram, shape, teamcolour, colour); } else { pie_ActivateShader(SHADER_COMPONENT, shape, teamcolour, colour); } } else { pie_DeactivateShader(); } glColor4ubv(colour.vector); // Only need to set once for entire model pie_SetTexturePage(shape->texpage); frame %= MAX(1, shape->numFrames); glBindBuffer(GL_ARRAY_BUFFER, shape->buffers[VBO_VERTEX]); glVertexPointer(3, GL_FLOAT, 0, NULL); glBindBuffer(GL_ARRAY_BUFFER, shape->buffers[VBO_NORMAL]); glNormalPointer(GL_FLOAT, 0, NULL); glBindBuffer(GL_ARRAY_BUFFER, shape->buffers[VBO_TEXCOORD]); glTexCoordPointer(2, GL_FLOAT, 0, NULL); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shape->buffers[VBO_INDEX]); glDrawElements(GL_TRIANGLES, shape->npolys * 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(frame * shape->npolys * 3 * sizeof(uint16_t))); polyCount += shape->npolys; pie_SetShaderEcmEffect(false); glDisable(GL_ALPHA_TEST); }