static void pie_Draw3DButton(iIMDShape *shape) { const PIELIGHT colour = WZCOL_WHITE; const PIELIGHT teamcolour = pal_GetTeamColour(NetPlay.players[selectedPlayer].colour); 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 drawDecals(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_DECALS, ModelViewProjection, paramsXLight, paramsYLight, 0, 1, textureMatrix, renderState.fogEnabled, renderState.fogBegin, renderState.fogEnd, fogColor); // select the terrain texture page pie_SetTexturePage(terrainPage); // use the alpha to blend pie_SetRendMode(REND_ALPHA); // and the texture coordinates buffer decalVBO->bind(); glVertexAttribPointer(program.locVertex, 3, GL_FLOAT, GL_FALSE, sizeof(DecalVertex), BUFFER_OFFSET(0)); glEnableVertexAttribArray(program.locVertex); glVertexAttribPointer(program.locTexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(DecalVertex), BUFFER_OFFSET(12)); glEnableVertexAttribArray(program.locTexCoord); glBindBuffer(GL_ARRAY_BUFFER, 0); int size = 0; int offset = 0; for (int x = 0; x < xSectors; x++) { for (int y = 0; y < ySectors + 1; y++) { if (y < ySectors && offset + size == sectors[x * ySectors + y].decalOffset && sectors[x * ySectors + y].draw) { // append size += sectors[x * ySectors + y].decalSize; continue; } // can't append, so draw what we have and start anew if (size > 0) { glDrawArrays(GL_TRIANGLES, offset, size); } size = 0; if (y < ySectors && sectors[x * ySectors + y].draw) { offset = sectors[x * ySectors + y].decalOffset; size = sectors[x * ySectors + y].decalSize; } } } glDepthMask(GL_TRUE); glDisableVertexAttribArray(program.locTexCoord); glDisableVertexAttribArray(program.locVertex); pie_DeactivateShader(); }
static void drawDepthOnly(const glm::mat4 &ModelViewProjection, const glm::vec4 ¶msXLight, const glm::vec4 ¶msYLight) { const auto &program = pie_ActivateShader(SHADER_TERRAIN_DEPTH, ModelViewProjection, paramsXLight, paramsYLight, 1, glm::mat4(1.f), glm::mat4(1.f)); pie_SetTexturePage(TEXPAGE_NONE); pie_SetRendMode(REND_OPAQUE); // we only draw in the depth buffer of using fog of war, as the clear color is black then if (!pie_GetFogStatus()) { glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); } // draw slightly higher distance than it actually is so it will not // by accident obscure the actual terrain glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(0.1f, 1.0f); // bind the vertex buffer geometryIndexVBO->bind(); geometryVBO->bind(); glVertexAttribPointer(program.locVertex, 3, GL_FLOAT, GL_FALSE, sizeof(RenderVertex), BUFFER_OFFSET(0)); glEnableVertexAttribArray(program.locVertex); 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].geometryIndexSize, GL_UNSIGNED_INT, sectors[x * ySectors + y].geometryIndexOffset); } } } finishDrawRangeElements(); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); if (!pie_GetFogStatus()) { glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } // disable the depth offset glDisable(GL_POLYGON_OFFSET_FILL); glDisableVertexAttribArray(program.locVertex); pie_DeactivateShader(); }
void pie_TransColouredTriangle(const std::array<Vector3f, 3> &vrt, PIELIGHT c, const glm::mat4 &modelViewMatrix) { pie_SetTexturePage(TEXPAGE_NONE); pie_SetRendMode(REND_ADDITIVE); glm::vec4 color(c.byte.r / 255.f, c.byte.g / 255.f, c.byte.b / 255.f, 128.f / 255.f); const auto &program = pie_ActivateShader(SHADER_GENERIC_COLOR, pie_PerspectiveGet() * modelViewMatrix, color); static glBufferWrapper buffer; glBindBuffer(GL_ARRAY_BUFFER, buffer.id); glBufferData(GL_ARRAY_BUFFER, 3 * sizeof(Vector3f), vrt.data(), GL_STREAM_DRAW); glVertexAttribPointer(program.locVertex, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glEnableVertexAttribArray(program.locVertex); glDrawArrays(GL_TRIANGLE_FAN, 0, 3); glDisableVertexAttribArray(program.locVertex); }
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); }
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); }
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); } }
/** * 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(); }
/// Draw the shadow for a shape static void pie_DrawShadow(iIMDShape *shape, int flag, int flag_data, const glm::vec4 &light, const glm::mat4 &modelViewMatrix) { static std::vector<EDGE> edgelist; // Static, to save allocations. static std::vector<EDGE> edgelistFlipped; // Static, to save allocations. static std::vector<EDGE> edgelistFiltered; // Static, to save allocations. EDGE *drawlist = NULL; unsigned edge_count; Vector3f *pVertices = shape->points; if (flag & pie_STATIC_SHADOW && shape->shadowEdgeList) { drawlist = shape->shadowEdgeList; edge_count = shape->nShadowEdges; } else { edgelist.clear(); iIMDPoly *end = shape->polys + shape->npolys; for (iIMDPoly *pPolys = shape->polys; pPolys != end; ++pPolys) { glm::vec3 p[3]; for (int j = 0; j < 3; ++j) { int current = pPolys->pindex[j]; p[j] = glm::vec3(pVertices[current].x, scale_y(pVertices[current].y, flag, flag_data), pVertices[current].z); } if (glm::dot(glm::cross(p[2] - p[0], p[1] - p[0]), glm::vec3(light)) > 0.0f) { for (int n = 0; n < 3; ++n) { // Add the edges edgelist.push_back({pPolys->pindex[n], pPolys->pindex[(n + 1)%3]}); } } } // Remove duplicate pairs from the edge list. For example, in the list ((1 2), (2 6), (6 2), (3, 4)), remove (2 6) and (6 2). edgelistFlipped = edgelist; std::for_each(edgelistFlipped.begin(), edgelistFlipped.end(), flipEdge); std::sort(edgelist.begin(), edgelist.end(), edgeLessThan); std::sort(edgelistFlipped.begin(), edgelistFlipped.end(), edgeLessThan); edgelistFiltered.resize(edgelist.size()); edgelistFiltered.erase(std::set_difference(edgelist.begin(), edgelist.end(), edgelistFlipped.begin(), edgelistFlipped.end(), edgelistFiltered.begin(), edgeLessThan), edgelistFiltered.end()); drawlist = &edgelistFiltered[0]; edge_count = edgelistFiltered.size(); //debug(LOG_WARNING, "we have %i edges", edge_count); if (flag & pie_STATIC_SHADOW) { // then store it in the imd shape->nShadowEdges = edge_count; shape->shadowEdgeList = (EDGE *)realloc(shape->shadowEdgeList, sizeof(EDGE) * shape->nShadowEdges); std::copy(drawlist, drawlist + edge_count, shape->shadowEdgeList); } } std::vector<Vector3f> vertexes; for (unsigned i = 0; i < edge_count; i++) { int a = drawlist[i].from, b = drawlist[i].to; glm::vec3 v1(pVertices[b].x, scale_y(pVertices[b].y, flag, flag_data), pVertices[b].z); glm::vec3 v2(pVertices[b].x + light[0], scale_y(pVertices[b].y, flag, flag_data) + light[1], pVertices[b].z + light[2]); glm::vec3 v3(pVertices[a].x + light[0], scale_y(pVertices[a].y, flag, flag_data) + light[1], pVertices[a].z + light[2]); glm::vec3 v4(pVertices[a].x, scale_y(pVertices[a].y, flag, flag_data), pVertices[a].z); vertexes.push_back(v1); vertexes.push_back(v2); vertexes.push_back(v3); vertexes.push_back(v3); vertexes.push_back(v4); vertexes.push_back(v1); } // draw the shadow volume const auto &program = pie_ActivateShader(SHADER_GENERIC_COLOR, pie_PerspectiveGet() * modelViewMatrix, glm::vec4()); static glBufferWrapper buffer; glBindBuffer(GL_ARRAY_BUFFER, buffer.id); glBufferData(GL_ARRAY_BUFFER, sizeof(Vector3f) * vertexes.size(), vertexes.data(), GL_STREAM_DRAW); glEnableVertexAttribArray(program.locVertex); glVertexAttribPointer(program.locVertex, 3, GL_FLOAT, GL_FALSE, 0, nullptr); glDrawArrays(GL_TRIANGLES, 0, edge_count * 2 * 3); glDisableVertexAttribArray(program.locVertex); pie_DeactivateShader(); }
static void pie_Draw3DShape2(const iIMDShape *shape, int frame, PIELIGHT colour, PIELIGHT teamcolour, int pieFlag, int pieFlagData, glm::mat4 const &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_ECM) { pie_SetRendMode(REND_ALPHA); light = true; pie_SetShaderEcmEffect(true); } SHADER_MODE mode = shape->shaderProgram == SHADER_NONE ? light ? SHADER_COMPONENT : SHADER_NOLIGHT : shape->shaderProgram; SHADER_PROGRAM &program = pie_ActivateShader(mode, shape, teamcolour, colour); glUniform1i(program.locAlphaTest, (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); }