/************************************************************************** WRF files may specify overrides for the textures on a map. This is done through an ugly hack involving cutting the texture name down to just "page-NN", where NN is the page number, and replaceing the texture page with the same name if another file with this prefix is loaded. **************************************************************************/ int pie_ReplaceTexPage(iV_Image *s, const char *texPage, int maxTextureSize, bool useMipmaping) { int i = iV_GetTexture(texPage); ASSERT(i >= 0, "pie_ReplaceTexPage: Cannot find any %s to replace!", texPage); if (i < 0) { return -1; } glDeleteTextures(1, &_TEX_PAGE[i].id); debug(LOG_TEXTURE, "Reloading texture %s from index %d", texPage, i); _TEX_PAGE[i].name[0] = '\0'; pie_AddTexPage(s, texPage, i, maxTextureSize, useMipmaping); return i; }
// ppFileData is incremented to the end of the file on exit! static iIMDShape *iV_ProcessIMD(const QString &filename, const char **ppFileData, const char *FileDataEnd) { const char *pFileData = *ppFileData; char buffer[PATH_MAX], texfile[PATH_MAX], normalfile[PATH_MAX], specfile[PATH_MAX]; int cnt, nlevels; iIMDShape *shape; UDWORD level; int32_t imd_version; uint32_t imd_flags; bool bTextured = false; iIMDShape *objanimpie[ANIM_EVENT_COUNT]; memset(normalfile, 0, sizeof(normalfile)); memset(specfile, 0, sizeof(specfile)); if (sscanf(pFileData, "%255s %d%n", buffer, &imd_version, &cnt) != 2) { debug(LOG_ERROR, "%s: bad PIE version: (%s)", filename.toUtf8().constData(), buffer); assert(false); return nullptr; } pFileData += cnt; if (strcmp(PIE_NAME, buffer) != 0) { debug(LOG_ERROR, "%s: Not an IMD file (%s %d)", filename.toUtf8().constData(), buffer, imd_version); return nullptr; } //Now supporting version PIE_VER and PIE_FLOAT_VER files if (imd_version != PIE_VER && imd_version != PIE_FLOAT_VER) { debug(LOG_ERROR, "%s: Version %d not supported", filename.toUtf8().constData(), imd_version); return nullptr; } // Read flag if (sscanf(pFileData, "%255s %x%n", buffer, &imd_flags, &cnt) != 2) { debug(LOG_ERROR, "%s: bad flags: %s", filename.toUtf8().constData(), buffer); return nullptr; } pFileData += cnt; /* This can be either texture or levels */ if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2) { debug(LOG_ERROR, "%s: Expecting TEXTURE or LEVELS: %s", filename.toUtf8().constData(), buffer); return nullptr; } pFileData += cnt; // get texture page if specified if (strncmp(buffer, "TEXTURE", 7) == 0) { int i, pwidth, pheight; char ch, texType[PATH_MAX]; /* the first parameter for textures is always ignored; which is why we ignore * nlevels read in above */ ch = *pFileData++; // Run up to the dot or till the buffer is filled. Leave room for the extension. for (i = 0; i < PATH_MAX - 5 && (ch = *pFileData++) != '\0' && ch != '.'; ++i) { texfile[i] = ch; } texfile[i] = '\0'; if (sscanf(pFileData, "%255s%n", texType, &cnt) != 1) { debug(LOG_ERROR, "%s: Texture info corrupt: %s", filename.toUtf8().constData(), buffer); return nullptr; } pFileData += cnt; if (strcmp(texType, "png") != 0) { debug(LOG_ERROR, "%s: Only png textures supported", filename.toUtf8().constData()); return nullptr; } sstrcat(texfile, ".png"); if (sscanf(pFileData, "%d %d%n", &pwidth, &pheight, &cnt) != 2) { debug(LOG_ERROR, "%s: Bad texture size: %s", filename.toUtf8().constData(), buffer); return nullptr; } pFileData += cnt; /* Now read in LEVELS directive */ if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2) { debug(LOG_ERROR, "%s: Bad levels info: %s", filename.toUtf8().constData(), buffer); return nullptr; } pFileData += cnt; bTextured = true; } if (strncmp(buffer, "NORMALMAP", 9) == 0) { char ch, texType[PATH_MAX]; int i; /* the first parameter for textures is always ignored; which is why we ignore * nlevels read in above */ ch = *pFileData++; // Run up to the dot or till the buffer is filled. Leave room for the extension. for (i = 0; i < PATH_MAX - 5 && (ch = *pFileData++) != '\0' && ch != '.'; ++i) { normalfile[i] = ch; } normalfile[i] = '\0'; if (sscanf(pFileData, "%255s%n", texType, &cnt) != 1) { debug(LOG_ERROR, "%s: Normal map info corrupt: %s", filename.toUtf8().constData(), buffer); return nullptr; } pFileData += cnt; if (strcmp(texType, "png") != 0) { debug(LOG_ERROR, "%s: Only png normal maps supported", filename.toUtf8().constData()); return nullptr; } sstrcat(normalfile, ".png"); /* Now read in LEVELS directive */ if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2) { debug(LOG_ERROR, "%s: Bad levels info: %s", filename.toUtf8().constData(), buffer); return nullptr; } pFileData += cnt; } if (strncmp(buffer, "SPECULARMAP", 11) == 0) { char ch, texType[PATH_MAX]; int i; /* the first parameter for textures is always ignored; which is why we ignore nlevels read in above */ ch = *pFileData++; // Run up to the dot or till the buffer is filled. Leave room for the extension. for (i = 0; i < PATH_MAX - 5 && (ch = *pFileData++) != '\0' && ch != '.'; ++i) { specfile[i] = ch; } specfile[i] = '\0'; if (sscanf(pFileData, "%255s%n", texType, &cnt) != 1) { debug(LOG_ERROR, "%s specular map info corrupt: %s", filename.toUtf8().constData(), buffer); return nullptr; } pFileData += cnt; if (strcmp(texType, "png") != 0) { debug(LOG_ERROR, "%s: only png specular maps supported", filename.toUtf8().constData()); return nullptr; } sstrcat(specfile, ".png"); /* Try -again- to read in LEVELS directive */ if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2) { debug(LOG_ERROR, "%s: Bad levels info: %s", filename.toUtf8().constData(), buffer); return nullptr; } pFileData += cnt; } for (int i = 0; i < ANIM_EVENT_COUNT; i++) { objanimpie[i] = nullptr; } while (strncmp(buffer, "EVENT", 5) == 0) { char animpie[PATH_MAX]; ASSERT(nlevels < ANIM_EVENT_COUNT && nlevels >= 0, "Invalid event type %d", nlevels); pFileData++; if (sscanf(pFileData, "%255s%n", animpie, &cnt) != 1) { debug(LOG_ERROR, "%s animation model corrupt: %s", filename.toUtf8().constData(), buffer); return nullptr; } pFileData += cnt; objanimpie[nlevels] = modelGet(animpie); /* Try -yet again- to read in LEVELS directive */ if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2) { debug(LOG_ERROR, "%s: Bad levels info: %s", filename.toUtf8().constData(), buffer); return nullptr; } pFileData += cnt; } if (strncmp(buffer, "LEVELS", 6) != 0) { debug(LOG_ERROR, "%s: Expecting 'LEVELS' directive (%s)", filename.toUtf8().constData(), buffer); return nullptr; } /* Read first LEVEL directive */ if (sscanf(pFileData, "%255s %d%n", buffer, &level, &cnt) != 2) { debug(LOG_ERROR, "(_load_level) file corrupt -J"); return nullptr; } pFileData += cnt; if (strncmp(buffer, "LEVEL", 5) != 0) { debug(LOG_ERROR, "%s: Expecting 'LEVEL' directive (%s)", filename.toUtf8().constData(), buffer); return nullptr; } shape = _imd_load_level(filename, &pFileData, FileDataEnd, nlevels, imd_version, level); if (shape == nullptr) { debug(LOG_ERROR, "%s: Unsuccessful", filename.toUtf8().constData()); return nullptr; } // load texture page if specified if (bTextured) { int texpage = iV_GetTexture(texfile); int normalpage = iV_TEX_INVALID; int specpage = iV_TEX_INVALID; ASSERT_OR_RETURN(nullptr, texpage >= 0, "%s could not load tex page %s", filename.toUtf8().constData(), texfile); if (normalfile[0] != '\0') { debug(LOG_TEXTURE, "Loading normal map %s for %s", normalfile, filename.toUtf8().constData()); normalpage = iV_GetTexture(normalfile, false); ASSERT_OR_RETURN(nullptr, normalpage >= 0, "%s could not load tex page %s", filename.toUtf8().constData(), normalfile); } if (specfile[0] != '\0') { debug(LOG_TEXTURE, "Loading specular map %s for %s", specfile, filename.toUtf8().constData()); specpage = iV_GetTexture(specfile, false); ASSERT_OR_RETURN(nullptr, specpage >= 0, "%s could not load tex page %s", filename.toUtf8().constData(), specfile); } // assign tex pages and flags to all levels for (iIMDShape *psShape = shape; psShape != nullptr; psShape = psShape->next) { psShape->texpage = texpage; psShape->normalpage = normalpage; psShape->specularpage = specpage; psShape->flags = imd_flags; } // check if model should use team colour mask if (imd_flags & iV_IMD_TCMASK) { int texpage_mask; pie_MakeTexPageTCMaskName(texfile); sstrcat(texfile, ".png"); texpage_mask = iV_GetTexture(texfile); ASSERT_OR_RETURN(shape, texpage_mask >= 0, "%s could not load tcmask %s", filename.toUtf8().constData(), texfile); // Propagate settings through levels for (iIMDShape *psShape = shape; psShape != nullptr; psShape = psShape->next) { psShape->tcmaskpage = texpage_mask; } } } // copy over model-wide animation information, stored only in the first level for (int i = 0; i < ANIM_EVENT_COUNT; i++) { shape->objanimpie[i] = objanimpie[i]; } *ppFileData = pFileData; return shape; }
// ppFileData is incremented to the end of the file on exit! static iIMDShape *iV_ProcessIMD(const char **ppFileData, const char *FileDataEnd) { const char *pFileName = GetLastResourceFilename(); // Last loaded filename const char *pFileData = *ppFileData; char buffer[PATH_MAX], texfile[PATH_MAX], normalfile[PATH_MAX], specfile[PATH_MAX]; int cnt, nlevels; iIMDShape *shape; UDWORD level; int32_t imd_version; uint32_t imd_flags; bool bTextured = false; GLuint shader = 0; memset(normalfile, 0, sizeof(normalfile)); memset(specfile, 0, sizeof(specfile)); if (sscanf(pFileData, "%255s %d%n", buffer, &imd_version, &cnt) != 2) { debug(LOG_ERROR, "iV_ProcessIMD %s bad version: (%s)", pFileName, buffer); assert(false); return NULL; } pFileData += cnt; if (strcmp(PIE_NAME, buffer) != 0) { debug(LOG_ERROR, "iV_ProcessIMD %s not an IMD file (%s %d)", pFileName, buffer, imd_version); return NULL; } //Now supporting version PIE_VER and PIE_FLOAT_VER files if (imd_version != PIE_VER && imd_version != PIE_FLOAT_VER) { debug(LOG_ERROR, "iV_ProcessIMD %s version %d not supported", pFileName, imd_version); return NULL; } // Read flag if (sscanf(pFileData, "%255s %x%n", buffer, &imd_flags, &cnt) != 2) { debug(LOG_ERROR, "iV_ProcessIMD %s bad flags: %s", pFileName, buffer); return NULL; } pFileData += cnt; /* This can be either texture or levels */ if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2) { debug(LOG_ERROR, "iV_ProcessIMD %s expecting TEXTURE or LEVELS: %s", pFileName, buffer); return NULL; } pFileData += cnt; // get texture page if specified if (strncmp(buffer, "TEXTURE", 7) == 0) { int i, pwidth, pheight; char ch, texType[PATH_MAX]; /* the first parameter for textures is always ignored; which is why we ignore * nlevels read in above */ ch = *pFileData++; // Run up to the dot or till the buffer is filled. Leave room for the extension. for (i = 0; i < PATH_MAX - 5 && (ch = *pFileData++) != '\0' && ch != '.'; ++i) { texfile[i] = ch; } texfile[i] = '\0'; if (sscanf(pFileData, "%255s%n", texType, &cnt) != 1) { debug(LOG_ERROR, "iV_ProcessIMD %s texture info corrupt: %s", pFileName, buffer); return NULL; } pFileData += cnt; if (strcmp(texType, "png") != 0) { debug(LOG_ERROR, "iV_ProcessIMD %s: only png textures supported", pFileName); return NULL; } sstrcat(texfile, ".png"); if (sscanf(pFileData, "%d %d%n", &pwidth, &pheight, &cnt) != 2) { debug(LOG_ERROR, "iV_ProcessIMD %s bad texture size: %s", pFileName, buffer); return NULL; } pFileData += cnt; /* Now read in LEVELS directive */ if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2) { debug(LOG_ERROR, "iV_ProcessIMD %s bad levels info: %s", pFileName, buffer); return NULL; } pFileData += cnt; bTextured = true; } if (strncmp(buffer, "NORMALMAP", 9) == 0) { char ch, texType[PATH_MAX]; int i; /* the first parameter for textures is always ignored; which is why we ignore * nlevels read in above */ ch = *pFileData++; // Run up to the dot or till the buffer is filled. Leave room for the extension. for (i = 0; i < PATH_MAX - 5 && (ch = *pFileData++) != '\0' && ch != '.'; ++i) { normalfile[i] = ch; } normalfile[i] = '\0'; if (sscanf(pFileData, "%255s%n", texType, &cnt) != 1) { debug(LOG_ERROR, "iV_ProcessIMD %s normal map info corrupt: %s", pFileName, buffer); return NULL; } pFileData += cnt; if (strcmp(texType, "png") != 0) { debug(LOG_ERROR, "iV_ProcessIMD %s: only png normal maps supported", pFileName); return NULL; } sstrcat(normalfile, ".png"); /* Now read in LEVELS directive */ if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2) { debug(LOG_ERROR, "iV_ProcessIMD %s bad levels info: %s", pFileName, buffer); return NULL; } pFileData += cnt; } if (strncmp(buffer, "SPECULARMAP", 11) == 0) { char ch, texType[PATH_MAX]; int i; /* the first parameter for textures is always ignored; which is why we ignore nlevels read in above */ ch = *pFileData++; // Run up to the dot or till the buffer is filled. Leave room for the extension. for (i = 0; i < PATH_MAX - 5 && (ch = *pFileData++) != '\0' && ch != '.'; ++i) { specfile[i] = ch; } specfile[i] = '\0'; if (sscanf(pFileData, "%255s%n", texType, &cnt) != 1) { debug(LOG_ERROR, "%s specular map info corrupt: %s", pFileName, buffer); return NULL; } pFileData += cnt; if (strcmp(texType, "png") != 0) { debug(LOG_ERROR, "%s: only png specular maps supported", pFileName); return NULL; } sstrcat(specfile, ".png"); /* Try -again- to read in LEVELS directive */ if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2) { debug(LOG_ERROR, "iV_ProcessIMD %s bad levels info: %s", pFileName, buffer); return NULL; } pFileData += cnt; } // DEPRECATED SHADERS DIRECTIVE! Has been moved into levels block now. Remove me later. if (strncmp(buffer, "SHADERS", 7) == 0) { char vertex[PATH_MAX], fragment[PATH_MAX]; /* the first parameter for "textures" is always ignored; which is why we ignore nlevels read in above */ pFileData++; if (sscanf(pFileData, "%255s %255s%n", vertex, fragment, &cnt) != 2) { debug(LOG_ERROR, "%s shader corrupt: %s", pFileName, buffer); return NULL; } pFileData += cnt; shader = pie_LoadShader(pFileName, vertex, fragment); /* Try -yet again- to read in LEVELS directive */ if (sscanf(pFileData, "%255s %d%n", buffer, &nlevels, &cnt) != 2) { debug(LOG_ERROR, "iV_ProcessIMD %s bad levels info: %s", pFileName, buffer); return NULL; } pFileData += cnt; } if (strncmp(buffer, "LEVELS", 6) != 0) { debug(LOG_ERROR, "iV_ProcessIMD: expecting 'LEVELS' directive (%s)", buffer); return NULL; } /* Read first LEVEL directive */ if (sscanf(pFileData, "%255s %d%n", buffer, &level, &cnt) != 2) { debug(LOG_ERROR, "(_load_level) file corrupt -J"); return NULL; } pFileData += cnt; if (strncmp(buffer, "LEVEL", 5) != 0) { debug(LOG_ERROR, "iV_ProcessIMD(2): expecting 'LEVEL' directive (%s)", buffer); return NULL; } shape = _imd_load_level(&pFileData, FileDataEnd, nlevels, imd_version); if (shape == NULL) { debug(LOG_ERROR, "iV_ProcessIMD %s unsuccessful", pFileName); return NULL; } // assign shader to all levels, if old deprecated SHADERS directive used. FIXME remove this later. for (iIMDShape *psShape = shape; shader && psShape != NULL; psShape = psShape->next) { shape->shaderProgram = shader; } // load texture page if specified if (bTextured) { int texpage = iV_GetTexture(texfile); int normalpage = iV_TEX_INVALID; int specpage = iV_TEX_INVALID; ASSERT_OR_RETURN(NULL, texpage >= 0, "%s could not load tex page %s", pFileName, texfile); if (normalfile[0] != '\0') { debug(LOG_TEXTURE, "Loading normal map %s for %s", normalfile, pFileName); normalpage = iV_GetTexture(normalfile); ASSERT_OR_RETURN(NULL, normalpage >= 0, "%s could not load tex page %s", pFileName, normalfile); } if (specfile[0] != '\0') { debug(LOG_TEXTURE, "Loading specular map %s for %s", specfile, pFileName); specpage = iV_GetTexture(specfile); ASSERT_OR_RETURN(NULL, specpage >= 0, "%s could not load tex page %s", pFileName, specfile); } // assign tex pages and flags to all levels for (iIMDShape *psShape = shape; psShape != NULL; psShape = psShape->next) { psShape->texpage = texpage; psShape->normalpage = normalpage; psShape->specularpage = specpage; psShape->flags = imd_flags; } // check if model should use team colour mask if (imd_flags & iV_IMD_TCMASK) { int texpage_mask; pie_MakeTexPageTCMaskName(texfile); sstrcat(texfile, ".png"); texpage_mask = iV_GetTexture(texfile); ASSERT_OR_RETURN(shape, texpage_mask >= 0, "%s could not load tcmask %s", pFileName, texfile); // Propagate settings through levels for (iIMDShape *psShape = shape; psShape != NULL; psShape = psShape->next) { psShape->tcmaskpage = texpage_mask; } } } *ppFileData = pFileData; return shape; }
/** * 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(); }
// ppFileData is incremented to the end of the file on exit! iIMDShape *iV_ProcessIMD( const char *filename ) { const char *pFileData, *pFileDataEnd; char buffer[MAX_PATH] = "-_-", texfile[MAX_PATH]; int cnt, nlevels, filelength; iIMDShape *shape, *psShape; Uint32 level; Sint32 imd_version; Uint32 imd_flags; // FIXME UNUSED bool bTextured = false; FILE *FileToOpen = NULL; fprintf(stderr, "filename: %s", filename); printf("filename: %s", filename); FileToOpen = fopen(filename, "rb"); if (FileToOpen == NULL) { fprintf(stderr, "iV_ProcessIMD %s file doesn't exist: (%s)\n", filename); return NULL; } pFileData = (char*)malloc(1024*1024); filelength = fread((void*)pFileData, 1, 1024*1024,FileToOpen); pFileDataEnd = pFileData + filelength; if (sscanf(pFileData, "%s %d%n", buffer, &imd_version, &cnt) != 2) { fprintf(stderr, "iV_ProcessIMD %s bad version: (%s)\n", filename, buffer); return NULL; } pFileData += cnt; if (strcmp(IMD_NAME, buffer) != 0 && strcmp(PIE_NAME, buffer) !=0 ) { fprintf(stderr, "iV_ProcessIMD %s not an IMD file (%s %d)\n", filename, buffer, imd_version); return NULL; } //Now supporting version 4 files if (imd_version < 2 || imd_version > 5) { fprintf(stderr, "iV_ProcessIMD %s version %d not supported\n", filename, imd_version); return NULL; } /* Flags are ignored now. Reading them in just to pass the buffer. */ if (sscanf(pFileData, "%s %x%n", buffer, &imd_flags, &cnt) != 2) { fprintf(stderr, "iV_ProcessIMD %s bad flags: %s\n", filename, buffer); return NULL; } pFileData += cnt; /* This can be either texture or levels */ if (sscanf(pFileData, "%s %d%n", buffer, &nlevels, &cnt) != 2) { fprintf(stderr, "iV_ProcessIMD %s expecting TEXTURE or LEVELS: %s\n", filename, buffer); return NULL; } pFileData += cnt; // get texture page if specified if (strncmp(buffer, "TEXTURE", 7) == 0) { int i, pwidth, pheight; char ch, texType[MAX_PATH]; /* the first parameter for textures is always ignored; which is why we ignore * nlevels read in above */ ch = *pFileData++; // Run up to the dot or till the buffer is filled. Leave room for the extension. for( i = 0; i < MAX_PATH-5 && (ch = *pFileData++) != EOF && ch != '.'; i++ ) { texfile[i] = (char)ch; } texfile[i] = '\0'; if (sscanf(pFileData, "%s%n", texType, &cnt) != 1) { fprintf(stderr, "iV_ProcessIMD %s texture info corrupt: %s\n", filename, buffer); return NULL; } pFileData += cnt; //more texture types using SDL_Image if (!strcmp(texType, "png")) { strcat(texfile, ".png"); } else if (!strcmp(texType, "bmp")) { strcat(texfile, ".bmp"); } else if (!strcmp(texType, "pcx")) { strcat(texfile, ".pcx"); } else if (!strcmp(texType, "jpg")) { strcat(texfile, ".jpg"); } else if (!strcmp(texType, "gif")) { strcat(texfile, ".gif"); } else { fprintf(stderr, "iV_ProcessIMD %s: only png bmp pcx jpg gif textures supported\n", filename); return NULL; } //pie_MakeTexPageName(texfile); if (sscanf(pFileData, "%d %d%n", &pwidth, &pheight, &cnt) != 2) { fprintf(stderr, "iV_ProcessIMD %s bad texture size: %s\n", filename, buffer); return NULL; } pFileData += cnt; /* Now read in LEVELS directive */ if (sscanf(pFileData, "%s %d%n", buffer, &nlevels, &cnt) != 2) { fprintf(stderr, "iV_ProcessIMD %s bad levels info: %s\n", filename, buffer); return NULL; } pFileData += cnt; bTextured = true; } if (strncmp(buffer, "LEVELS", 6) != 0) { fprintf(stderr, "iV_ProcessIMD: expecting 'LEVELS' directive (%s)", buffer); return NULL; } /* Read first LEVEL directive */ if (sscanf(pFileData, "%s %d%n", buffer, &level, &cnt) != 2) { fprintf(stderr, "(_load_level) file corrupt -J\n"); return NULL; } pFileData += cnt; if (strncmp(buffer, "LEVEL", 5) != 0) { fprintf(stderr, "iV_ProcessIMD(2): expecting 'LEVELS' directive (%s)", buffer); return NULL; } shape = _imd_load_level(&pFileData, pFileDataEnd, nlevels); if (shape == NULL) { fprintf(stderr, "iV_ProcessIMD %s unsuccessful\n", filename); return NULL; } // load texture page if specified if (bTextured) { int texpage = iV_GetTexture(texfile); if (texpage < 0) { fprintf(stderr, "iV_ProcessIMD %s could not load tex page %s\n", filename, texfile); return NULL; } /* assign tex page to levels */ for (psShape = shape; psShape != NULL; psShape = psShape->next) { psShape->texpage = texpage; } } return shape; }