void fontSprite (bool flip, int x, int y, sprite & single, const spritePalette & fontPal) { float tx1 = (float)(single.tex_x-0.5) / fontPal.tex_w[single.texNum]; float ty1 = 0.0; float tx2 = (float)(single.tex_x + single.width+(flip ? 1.0 : 0.5)) / fontPal.tex_w[single.texNum]; float ty2 = (float)(single.height+2)/fontPal.tex_h[single.texNum]; float x1 = (float)x - (float)single.xhot/cameraZoom; float y1 = (float)y - (float)single.yhot/cameraZoom; float x2 = x1 + (float)single.width/cameraZoom; float y2 = y1 + (float)single.height/cameraZoom; GLfloat vertices[] = { x1, y1, 0.0f, x2, y1, 0.0f, x1, y2, 0.0f, x2, y2, 0.0f }; if (flip) { vertices[0] = x2; vertices[3] = x1; vertices[6] = x2; vertices[9] = x1; } const GLfloat texCoords[] = { tx1, ty1, tx2, ty1, tx1, ty2, tx2, ty2 }; //glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // GL_MODULATE instead of decal mixes the colours! setPrimaryColor(fontPal.originalRed/255.f, fontPal.originalGreen/255.f, fontPal.originalBlue/255.f, 1.0f); glBindTexture (GL_TEXTURE_2D, fontPal.tex_names[single.texNum]); glUseProgram(shader.smartScaler); GLuint uniform = glGetUniformLocation(shader.smartScaler, "useLightTexture"); if (uniform >= 0) glUniform1i(uniform, 0); setPMVMatrix(shader.smartScaler); if (gameSettings.antiAlias == 1) { glUniform1i(glGetUniformLocation(shader.smartScaler, "antialias"), 1); } else { glUniform1i(glGetUniformLocation(shader.smartScaler, "antialias"), 0); } glEnable(GL_BLEND); drawQuad(shader.smartScaler, vertices, 1, texCoords); glDisable(GL_BLEND); glUseProgram(0); }
void hardScroll (int distance) { if (abs (distance) >= sceneHeight) { blankScreen (0, 0, sceneWidth, sceneHeight); return; } if (! distance) return; const GLfloat backdropTexCoords[] = { 0.0f, 0.0f, backdropTexW, 0.0f, 0.0f, backdropTexH, backdropTexW, backdropTexH }; setPixelCoords (true); unsigned int xoffset = 0; while (xoffset < sceneWidth) { int w = (sceneWidth-xoffset < viewportWidth) ? sceneWidth-xoffset : viewportWidth; unsigned int yoffset = 0; while (yoffset < sceneHeight) { int h = (sceneHeight-yoffset < viewportHeight) ? sceneHeight-yoffset : viewportHeight; glClear(GL_COLOR_BUFFER_BIT); // Clear The Screen // Render the backdrop glBindTexture (GL_TEXTURE_2D, backdropTextureName); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); const GLfloat vertices[] = { (GLfloat)-xoffset, (GLfloat)-distance-yoffset, 0., (GLfloat)sceneWidth-xoffset, (GLfloat)-distance-yoffset, 0., (GLfloat)-xoffset, (GLfloat)sceneHeight-distance-yoffset, 0., (GLfloat)sceneWidth-xoffset, (GLfloat)sceneHeight-distance-yoffset, 0. }; glUseProgram(shader.texture); setPMVMatrix(shader.texture); drawQuad(shader.texture, vertices, 1, backdropTexCoords); glUseProgram(0); // Copy Our ViewPort To The Texture copyTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, viewportOffsetX, viewportOffsetY, w, h, backdropTextureName); yoffset += viewportHeight; } xoffset += viewportWidth; } setPixelCoords (false); }
void blankScreen (int x1, int y1, int x2, int y2) { if (y1 < 0) y1 = 0; if (x1 < 0) x1 = 0; if (x2 > (int) sceneWidth) x2 = (int)sceneWidth; if (y2 > (int) sceneHeight) y2 = (int)sceneHeight; int picWidth = x2-x1; int picHeight = y2-y1; setPixelCoords (true); int xoffset = 0; while (xoffset < picWidth) { int w = (picWidth-xoffset < viewportWidth) ? picWidth-xoffset : viewportWidth; int yoffset = 0; while (yoffset < picHeight) { int h = (picHeight-yoffset < viewportHeight) ? picHeight-yoffset : viewportHeight; // Render the scene const GLfloat vertices[] = { -10.325f, -1.325f, 0.0f, w+1.325f, -1.325f, 0.0f, -10.325f, h+1.325f, 0.0f, w+1.325f, h+1.325f, 0.0f }; glUseProgram(shader.color); setPMVMatrix(shader.color); setPrimaryColor(redValue(currentBlankColour)/255.0f, greenValue(currentBlankColour)/255.0f, blueValue(currentBlankColour)/255.0f, 1.0f); drawQuad(shader.color, vertices, 0); glUseProgram(0); // Copy Our ViewPort To The Texture copyTexSubImage2D(GL_TEXTURE_2D, 0, x1+xoffset, y1+yoffset, viewportOffsetX, viewportOffsetY, w, h, backdropTextureName); yoffset += viewportHeight; } xoffset += viewportWidth; } setPixelCoords (false); }
bool loadHSI (FILE * fp, int x, int y, bool reserve) { int t1, t2, n; unsigned short c; GLubyte * target; int32_t transCol = reserve ? -1 : 63519; int picWidth; int picHeight; int realPicWidth, realPicHeight; long file_pointer = ftell (fp); png_structp png_ptr; png_infop info_ptr, end_info; int fileIsPNG = true; // Is this a PNG file? char tmp[10]; size_t bytes_read = fread(tmp, 1, 8, fp); if (bytes_read != 8 && ferror (fp)) { debugOut("Reading error in loadHSI.\n"); } if (png_sig_cmp((png_byte *) tmp, 0, 8)) { // No, it's old-school HSI fileIsPNG = false; fseek(fp, file_pointer, SEEK_SET); picWidth = realPicWidth = get2bytes (fp); picHeight = realPicHeight = get2bytes (fp); } else { // Read the PNG header png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { return false; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); return false; } end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return false; } png_init_io(png_ptr, fp); // Tell libpng which file to read png_set_sig_bytes(png_ptr, 8); // 8 bytes already read png_read_info(png_ptr, info_ptr); png_uint_32 width, height; int bit_depth, color_type, interlace_type, compression_type, filter_method; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method); picWidth = realPicWidth = width; picHeight = realPicHeight = height; if (bit_depth < 8) png_set_packing(png_ptr); png_set_expand(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); if (bit_depth == 16) png_set_strip_16(png_ptr); png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER); png_read_update_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method); //int rowbytes = png_get_rowbytes(png_ptr, info_ptr); } GLfloat texCoordW = 1.0; GLfloat texCoordH = 1.0; if (! NPOT_textures) { picWidth = getNextPOT(picWidth); picHeight = getNextPOT(picHeight); texCoordW = ((double)realPicWidth) / picWidth; texCoordH = ((double)realPicHeight) / picHeight; } if (reserve) { if (! resizeBackdrop (realPicWidth, realPicHeight)) return false; } if (x == IN_THE_CENTRE) x = (sceneWidth - realPicWidth) >> 1; if (y == IN_THE_CENTRE) y = (sceneHeight - realPicHeight) >> 1; if (x < 0 || x + realPicWidth > sceneWidth || y < 0 || y + realPicHeight > sceneHeight) return false; if (fileIsPNG) { unsigned char * row_pointers[realPicHeight]; for (int i = 0; i<realPicHeight; i++) row_pointers[i] = backdropTexture + 4*i*picWidth; png_read_image(png_ptr, (png_byte **) row_pointers); png_read_end(png_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); } else { for (t2 = 0; t2 < realPicHeight; t2 ++) { t1 = 0; while (t1 < realPicWidth) { c = (unsigned short) get2bytes (fp); if (c & 32) { n = fgetc (fp) + 1; c -= 32; } else { n = 1; } while (n --) { target = backdropTexture + 4*picWidth*t2 + t1*4; if (c == transCol || c == 2015) { target[0] = (GLubyte) 0; target[1] = (GLubyte) 0; target[2] = (GLubyte) 0; target[3] = (GLubyte) 0; } else { target[0] = (GLubyte) redValue(c); target[1] = (GLubyte) greenValue(c); target[2] = (GLubyte) blueValue(c); target[3] = (GLubyte) 255; } t1++; } } } } GLuint tmpTex; glGenTextures (1, &tmpTex); glBindTexture(GL_TEXTURE_2D, tmpTex); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (gameSettings.antiAlias < 0) { glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } else { glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } texImage2D (GL_TEXTURE_2D, 0, GL_RGBA, picWidth, picHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, backdropTexture, tmpTex); //glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); float btx1; float btx2; float bty1; float bty2; if (! NPOT_textures) { btx1 = backdropTexW * x / sceneWidth; btx2 = backdropTexW * (x+realPicWidth) / sceneWidth; bty1 = backdropTexH * y / sceneHeight; bty2 = backdropTexH * (y+realPicHeight) / sceneHeight; } else { btx1 = (float) x / sceneWidth; btx2 = (float) (x+realPicWidth) / sceneWidth; bty1 = (float) y / sceneHeight; bty2 = (float) (y+realPicHeight) / sceneHeight; } const GLfloat btexCoords[] = { btx1, bty1, btx2, bty1, btx1, bty2, btx2, bty2 }; setPixelCoords (true); int xoffset = 0; while (xoffset < realPicWidth) { int w = (realPicWidth-xoffset < viewportWidth) ? realPicWidth-xoffset : viewportWidth; int yoffset = 0; while (yoffset < realPicHeight) { int h = (realPicHeight-yoffset < viewportHeight) ? realPicHeight-yoffset : viewportHeight; glClear(GL_COLOR_BUFFER_BIT); // Clear The Screen const GLfloat vertices[] = { (GLfloat)-xoffset, (GLfloat)-yoffset, 0., (GLfloat)realPicWidth-xoffset, (GLfloat)-yoffset, 0., (GLfloat)-xoffset, (GLfloat)-yoffset+realPicHeight, 0., (GLfloat)realPicWidth-xoffset, (GLfloat)-yoffset+realPicHeight, 0. }; const GLfloat texCoords[] = { 0.0f, 0.0f, texCoordW, 0.0f, 0.0f, texCoordH, texCoordW, texCoordH }; if (backdropExists) { // Render the sprite to the backdrop // (using mulitexturing, so the old backdrop is seen where alpha < 1.0) glActiveTexture(GL_TEXTURE2); glBindTexture (GL_TEXTURE_2D, backdropTextureName); glActiveTexture(GL_TEXTURE0); glUseProgram(shader.paste); GLint uniform = glGetUniformLocation(shader.paste, "useLightTexture"); if (uniform >= 0) glUniform1i(uniform, 0); // No lighting setPMVMatrix(shader.paste); setPrimaryColor(1.0, 1.0, 1.0, 1.0); glBindTexture(GL_TEXTURE_2D, tmpTex); //glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); drawQuad(shader.paste, vertices, 3, texCoords, NULL, btexCoords); glUseProgram(0); } else { // It's all new - nothing special to be done. glUseProgram(shader.texture); setPMVMatrix(shader.texture); glBindTexture(GL_TEXTURE_2D, tmpTex); setPrimaryColor(1.0, 0.0, 0.0, 0.0); drawQuad(shader.texture, vertices, 1, texCoords); glUseProgram(0); } // Copy Our ViewPort To The Texture copyTexSubImage2D(GL_TEXTURE_2D, 0, x+xoffset, y+yoffset, viewportOffsetX, viewportOffsetY, w, h, backdropTextureName); yoffset += viewportHeight; } xoffset += viewportWidth; } deleteTextures(1, &tmpTex); setPixelCoords (false); backdropExists = true; return true; }
void drawBackDrop () { setPrimaryColor(1.0, 1.0, 1.0, 1.0); //glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable(GL_BLEND); glUseProgram(shader.smartScaler); GLuint uniform = glGetUniformLocation(shader.smartScaler, "useLightTexture"); if (uniform >= 0) glUniform1i(uniform, 0); setPMVMatrix(shader.smartScaler); if (gameSettings.antiAlias == 1) { glUniform1i(glGetUniformLocation(shader.smartScaler, "antialias"), 1); } else { glUniform1i(glGetUniformLocation(shader.smartScaler, "antialias"), 0); } if (parallaxStuff) { parallaxLayer * ps = parallaxStuff; while (ps->next) ps = ps->next; while (ps) { ps -> cameraX = sortOutPCamera (cameraX, ps -> fractionX, (int)(sceneWidth - (float)winWidth/cameraZoom), (int)(ps -> width - (float)winWidth/cameraZoom)); ps -> cameraY = sortOutPCamera (cameraY, ps -> fractionY, (int)(sceneHeight - (float)winHeight/cameraZoom), (int)(ps -> height - (float)winHeight/cameraZoom)); glBindTexture (GL_TEXTURE_2D, ps->textureName); float w = (ps->wrapS) ? sceneWidth : ps->width; float h = (ps->wrapT) ? sceneHeight : ps->height; float texw; float texh; if (! NPOT_textures) { texw = (ps->wrapS) ? (float) sceneWidth / ps->width: (float) ps->width / getNextPOT(ps->width); texh = (ps->wrapT) ? (float) sceneHeight / ps->height: (float) ps->height / getNextPOT(ps->height); } else { texw = (ps->wrapS) ? (float) sceneWidth / ps->width: 1.0; texh = (ps->wrapT) ? (float) sceneHeight / ps->height: 1.0; } const GLfloat vertices[] = { (GLfloat)-ps -> cameraX, (GLfloat)-ps -> cameraY, 0.1f, w -ps -> cameraX, (GLfloat)-ps -> cameraY, 0.1f, (GLfloat)-ps -> cameraX, h -ps -> cameraY, 0.1f, w -ps -> cameraX, h -ps -> cameraY, 0.1f }; const GLfloat texCoords[] = { 0.0f, 0.0f, texw, 0.0f, 0.0f, texh, texw, texh }; drawQuad(shader.smartScaler, vertices, 1, texCoords); ps = ps -> prev; } } glBindTexture (GL_TEXTURE_2D, backdropTextureName); const GLfloat backdropTexCoords[] = { 0.0f, 0.0f, backdropTexW, 0.0f, 0.0f, backdropTexH, backdropTexW, backdropTexH }; const GLfloat vertices[] = { (GLfloat)-cameraX, (GLfloat)-cameraY, 0., (GLfloat)sceneWidth- (GLfloat)cameraX, (GLfloat)-cameraY, 0., (GLfloat)-cameraX, (GLfloat)sceneHeight- (GLfloat)cameraY, 0., (GLfloat)sceneWidth- (GLfloat)cameraX, (GLfloat)sceneHeight- (GLfloat)cameraY, 0. }; drawQuad(shader.smartScaler, vertices, 1, backdropTexCoords); glDisable(GL_BLEND); glUseProgram(0); }
void darkScreen () { setPixelCoords (true); int xoffset = 0; while (xoffset < sceneWidth) { int w = (sceneWidth-xoffset < viewportWidth) ? sceneWidth-xoffset : viewportWidth; int yoffset = 0; while (yoffset < sceneHeight) { int h = (sceneHeight-yoffset < viewportHeight) ? sceneHeight-yoffset : viewportHeight; // Render the scene - first the old backdrop //glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glBindTexture (GL_TEXTURE_2D, backdropTextureName); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); const GLfloat vertices[] = { (GLfloat)-xoffset, (GLfloat)-yoffset, 0., (GLfloat)sceneWidth-xoffset, (GLfloat)-yoffset, 0., (GLfloat)-xoffset, (GLfloat)sceneHeight-yoffset, 0., (GLfloat)sceneWidth-xoffset, (GLfloat)sceneHeight-yoffset, 0. }; const GLfloat texCoords[] = { 0.0f, 0.0f, backdropTexW, 0.0f, 0.0f, backdropTexH, backdropTexW, backdropTexH }; glUseProgram(shader.texture); setPMVMatrix(shader.texture); drawQuad(shader.texture, vertices, 1, texCoords); // Then the darkness glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); glEnable(GL_BLEND); glUseProgram(shader.color); setPMVMatrix(shader.color); setPrimaryColor(0.0f, 0.0f, 0.0f, 0.5f); drawQuad(shader.color, vertices, 0); glUseProgram(0); glDisable(GL_BLEND); glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Copy Our ViewPort To The Texture copyTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, viewportOffsetX, viewportOffsetY, w, h, backdropTextureName); yoffset += h; glClear(GL_COLOR_BUFFER_BIT); } xoffset += w; } setPixelCoords (false); }
void saveCoreHSI (FILE * writer, GLuint texture, int w, int h) { GLint tw, th; glBindTexture (GL_TEXTURE_2D, texture); getTextureDimensions(texture, &tw, &th); GLushort* image = new GLushort [tw*th]; if (! checkNew (image)) return; glPixelStorei (GL_PACK_ALIGNMENT, 1); // glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, image); setPixelCoords (true); //glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); const GLfloat texCoords[] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }; int xoffset = 0; while (xoffset < tw) { int w = (tw-xoffset < viewportWidth) ? tw-xoffset : viewportWidth; int yoffset = 0; while (yoffset < th) { int h = (th-yoffset < viewportHeight) ? th-yoffset : viewportHeight; glClear(GL_COLOR_BUFFER_BIT); // Clear The Screen const GLfloat vertices[] = { (GLfloat)-xoffset, (GLfloat)-yoffset, 0., (GLfloat)w-xoffset, (GLfloat)-yoffset, 0., (GLfloat)-xoffset, (GLfloat)-yoffset+h, 0., (GLfloat)w-xoffset, (GLfloat)-yoffset+h, 0. }; glUseProgram(shader.texture); setPMVMatrix(shader.texture); drawQuad(shader.texture, vertices, 1, texCoords); glUseProgram(0); for (int i = 0; i<h; i++) { glReadPixels(viewportOffsetX, viewportOffsetY+i, w, 1, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, image+xoffset+(yoffset+i)*tw); } yoffset += viewportHeight; } xoffset += viewportWidth; } //glReadPixels(viewportOffsetX, viewportOffsetY, tw, th, GL_RGBA, GL_UNSIGNED_BYTE, data); setPixelCoords (false); int x, y, lookAhead; unsigned short int * fromHere, * lookPointer; put2bytes (w, writer); put2bytes (h, writer); for (y = 0; y < h; y ++) { fromHere = image +(y*tw); x = 0; while (x < w) { lookPointer = fromHere + 1; for (lookAhead = x + 1; lookAhead < w; lookAhead ++) { if (lookAhead - x == 256) break; if (* fromHere != * lookPointer) break; lookPointer ++; } if (lookAhead == x + 1) { put2bytes ((* fromHere) & 65503, writer); } else { put2bytes (* fromHere | 32, writer); fputc (lookAhead - x - 1, writer); } fromHere = lookPointer; x = lookAhead; } } delete [] image; image = NULL; }
void saveCorePNG (FILE * writer, GLuint texture, int w, int h) { GLint tw, th; glBindTexture (GL_TEXTURE_2D, texture); getTextureDimensions(texture, &tw, &th); GLubyte* image = new GLubyte [tw*th*4]; if (! checkNew (image)) return; glPixelStorei (GL_PACK_ALIGNMENT, 1); // glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, image); setPixelCoords (true); //glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); const GLfloat texCoords[] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }; int xoffset = 0; while (xoffset < tw) { int w = (tw-xoffset < viewportWidth) ? tw-xoffset : viewportWidth; int yoffset = 0; while (yoffset < th) { int h = (th-yoffset < viewportHeight) ? th-yoffset : viewportHeight; glClear(GL_COLOR_BUFFER_BIT); // Clear The Screen const GLfloat vertices[] = { (GLfloat)-xoffset, (GLfloat)-yoffset, 0., (GLfloat)tw-xoffset, (GLfloat)-yoffset, 0., (GLfloat)-xoffset, (GLfloat)-yoffset+th, 0., (GLfloat)tw-xoffset, (GLfloat)-yoffset+th, 0. }; glUseProgram(shader.texture); setPMVMatrix(shader.texture); drawQuad(shader.texture, vertices, 1, texCoords); glUseProgram(0); for (int i = 0; i<h; i++) { glReadPixels(viewportOffsetX, viewportOffsetY+i, w, 1, GL_RGBA, GL_UNSIGNED_BYTE, image+xoffset*4+(yoffset+i)*4*tw); } yoffset += viewportHeight; } xoffset += viewportWidth; } setPixelCoords (false); png_structp png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { fatal ("Error saving image!"); return; } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr){ png_destroy_write_struct(&png_ptr, (png_infopp)NULL); fatal ("Error saving image!"); return; } png_init_io(png_ptr, writer); png_set_IHDR(png_ptr, info_ptr, w, h, 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); unsigned char * row_pointers[h]; for (int i = 0; i < h; i++) { row_pointers[i] = image + 4*i*tw; } png_set_rows(png_ptr, info_ptr, row_pointers); png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); delete [] image; image = NULL; }
// Paste a scaled sprite onto the backdrop void fixScaleSprite (int x, int y, sprite & single, const spritePalette & fontPal, onScreenPerson * thisPerson, int camX, int camY, bool mirror) { float scale = thisPerson-> scale; bool useZB = ! (thisPerson->extra & EXTRA_NOZB); bool light = ! (thisPerson->extra & EXTRA_NOLITE); if (scale <= 0.05) return; float tx1 = (float)(single.tex_x) / fontPal.tex_w[single.texNum]; float ty1 = (float) 1.0/fontPal.tex_h[single.texNum];//0.0; float tx2 = (float)(single.tex_x + single.width) / fontPal.tex_w[single.texNum]; float ty2 = (float)(single.height+1)/fontPal.tex_h[single.texNum]; int diffX = (int)(((float)single.width) * scale); int diffY = (int)(((float)single.height) * scale); int x1; if (single.xhot < 0) x1 = x - (int)((mirror ? (float) (single.width - single.xhot) : (float)(single.xhot+1) ) * scale); else x1 = x - (int)((mirror ? (float) (single.width - (single.xhot+1)) : (float)single.xhot ) * scale); int y1 = y - (int)((single.yhot - thisPerson->floaty) * scale); float spriteWidth = diffX; float spriteHeight = diffY; if (x1 < 0) diffX += x1; if (y1 < 0) diffY += y1; if (x1 + diffX > sceneWidth) diffX = sceneWidth - x1; if (y1 + diffY > sceneHeight) diffY = sceneHeight - y1; if (diffX < 0) return; if (diffY < 0) return; GLfloat z; if (useZB && zBuffer.numPanels) { int i; for (i = 1; i<zBuffer.numPanels; i++) { if (zBuffer.panel[i] >= y + cameraY) { i--; break; } } z = 0.999 - (double) i * (1.0 / 128.0); } else { z = -0.5; } float ltx1, btx1; float ltx2, btx2; float lty1, bty1; float lty2, bty2; if (! NPOT_textures) { ltx1 = lightMap.texW * x1 / sceneWidth; ltx2 = lightMap.texW * (x1+spriteWidth) / sceneWidth; lty1 = lightMap.texH * y1 / sceneHeight; lty2 = lightMap.texH * (y1+spriteHeight) / sceneHeight; btx1 = backdropTexW * x1 / sceneWidth; btx2 = backdropTexW * (x1+spriteWidth) / sceneWidth; bty1 = backdropTexH * y1 / sceneHeight; bty2 = backdropTexH * (y1+spriteHeight) / sceneHeight; } else { btx1 = ltx1 = (float) x1 / sceneWidth; btx2 = ltx2 = (float) (x1+spriteWidth) / sceneWidth; bty1 = lty1 = (float) y1 / sceneHeight; bty2 = lty2 = (float) (y1+spriteHeight) / sceneHeight; } const GLfloat ltexCoords[] = { ltx1, lty1, ltx2, lty1, ltx1, lty2, ltx2, lty2 }; const GLfloat btexCoords[] = { btx1, bty1, btx2, bty1, btx1, bty2, btx2, bty2 }; if (light && lightMap.data) { if (lightMapMode == LIGHTMAPMODE_HOTSPOT) { int lx=x+cameraX; int ly=y+cameraY; if (lx<0 || ly<0 || lx>=sceneWidth || ly>=sceneHeight) { curLight[0] = curLight[1] = curLight[2] = 255; } else { GLubyte *target = lightMap.data + (ly*sceneWidth + lx)*4; curLight[0] = target[0]; curLight[1] = target[1]; curLight[2] = target[2]; } } else if (lightMapMode == LIGHTMAPMODE_PIXEL) { curLight[0] = curLight[1] = curLight[2] = 255; glActiveTexture(GL_TEXTURE1); glBindTexture (GL_TEXTURE_2D, lightMap.name); } } else { curLight[0] = curLight[1] = curLight[2] = 255; } glActiveTexture(GL_TEXTURE2); glBindTexture (GL_TEXTURE_2D, backdropTextureName); glActiveTexture(GL_TEXTURE0); setPixelCoords (true); GLfloat xoffset = 0.0f; while (xoffset < diffX) { int w = (diffX-xoffset < viewportWidth) ? (int) (diffX-xoffset) : viewportWidth; GLfloat yoffset = 0.0f; while (yoffset < diffY) { int h = (diffY-yoffset< viewportHeight) ? (int) (diffY-yoffset) : viewportHeight; // Render the scene - first the old backdrop (so that it'll show through when the z-buffer is active //glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glBindTexture (GL_TEXTURE_2D, backdropTextureName); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); const GLfloat vertices[] = { -x1-xoffset, -y1-yoffset, 0.0f, sceneWidth-x1-xoffset, -y1-yoffset, 0.0f, -x1-xoffset, sceneHeight-y1-yoffset, 0.0f, sceneWidth-x1-xoffset, sceneHeight-y1-yoffset, 0.0f }; const GLfloat texCoords[] = { 0.0f, 0.0f, backdropTexW, 0.0f, 0.0f, backdropTexH, backdropTexW, backdropTexH }; glUseProgram(shader.texture); setPMVMatrix(shader.texture); drawQuad(shader.texture, vertices, 1, texCoords); // The z-buffer if (useZB) { glDepthMask (GL_TRUE); glClear(GL_DEPTH_BUFFER_BIT); drawZBuffer((int) (x1+xoffset+camX), (int) (y1+yoffset+camY), false); glDepthMask (GL_FALSE); glEnable(GL_DEPTH_TEST); } // Then the sprite glUseProgram(shader.paste); GLint uniform = glGetUniformLocation(shader.paste, "useLightTexture"); if (uniform >= 0) glUniform1i(uniform, light && lightMapMode == LIGHTMAPMODE_PIXEL && lightMap.data); setPMVMatrix(shader.paste); setDrawMode (thisPerson); glBindTexture (GL_TEXTURE_2D, fontPal.tex_names[single.texNum]); const GLfloat vertices2[] = { -xoffset, -yoffset, z, spriteWidth-xoffset, -yoffset, z, -xoffset, spriteHeight-yoffset, z, spriteWidth-xoffset, spriteHeight-yoffset, z }; if (! mirror) { GLfloat tx3 = tx1; tx1 = tx2; tx2 = tx3; } const GLfloat texCoords2[] = { tx2, ty1, tx1, ty1, tx2, ty2, tx1, ty2 }; drawQuad(shader.paste, vertices2, 3, texCoords2, ltexCoords, btexCoords); setSecondaryColor(0., 0., 0., 1.); //glDisable(GL_COLOR_SUM); FIXME: replace line? // Copy Our ViewPort To The Texture glUseProgram(0); copyTexSubImage2D(GL_TEXTURE_2D, 0, (int) ((x1<0) ? xoffset: x1+xoffset), (int) ((y1<0) ? yoffset: y1+yoffset), (int) ((x1<0) ?viewportOffsetX-x1:viewportOffsetX), (int) ((y1<0) ?viewportOffsetY-y1:viewportOffsetY), w, h, backdropTextureName); yoffset += viewportHeight; } xoffset += viewportWidth; } setPixelCoords (false); glUseProgram(0); }
bool scaleSprite (sprite & single, const spritePalette & fontPal, onScreenPerson * thisPerson, bool mirror) { float x = thisPerson->x; float y = thisPerson->y; float scale = thisPerson-> scale; bool light = ! (thisPerson->extra & EXTRA_NOLITE); if (scale <= 0.05) return false; float tx1 = (float)(single.tex_x) / fontPal.tex_w[single.texNum]; float ty1 = (float) 1.0/fontPal.tex_h[single.texNum]; float tx2 = (float)(single.tex_x + single.width) / fontPal.tex_w[single.texNum]; float ty2 = (float)(single.height+1)/fontPal.tex_h[single.texNum]; int diffX = (int)(((float)single.width) * scale); int diffY = (int)(((float)single.height) * scale); GLfloat x1, y1, x2, y2; if (thisPerson -> extra & EXTRA_FIXTOSCREEN) { x = x / cameraZoom; y = y / cameraZoom; if (single.xhot < 0) x1 = x - (int)((mirror ? (float) (single.width - single.xhot) : (float)(single.xhot+1) ) * scale/cameraZoom); else x1 = x - (int)((mirror ? (float) (single.width - (single.xhot+1)) : (float)single.xhot ) * scale / cameraZoom); y1 = y - (int)((single.yhot - thisPerson->floaty) * scale / cameraZoom); x2 = x1 + (int)(diffX / cameraZoom); y2 = y1 + (int)(diffY / cameraZoom); } else { x -= cameraX; y -= cameraY; if (single.xhot < 0) x1 = x - (int)((mirror ? (float) (single.width - single.xhot) : (float)(single.xhot+1) ) * scale); else x1 = x - (int)((mirror ? (float) (single.width - (single.xhot+1)) : (float)single.xhot ) * scale); y1 = y - (int)((single.yhot - thisPerson->floaty) * scale); x2 = x1 + diffX; y2 = y1 + diffY; } GLfloat z; if ((! (thisPerson->extra & EXTRA_NOZB)) && zBuffer.numPanels) { int i; for (i = 1; i<zBuffer.numPanels; i++) { if (zBuffer.panel[i] >= y + cameraY) { i--; break; } } z = 0.999 - (double) i * (1.0 / 128.0); } else { z = -0.5; } float ltx1, ltx2, lty1, lty2; if (! NPOT_textures) { ltx1 = lightMap.texW * (x1+cameraX) / sceneWidth; ltx2 = lightMap.texW * (x2+cameraX) / sceneWidth; lty1 = lightMap.texH * (y1+cameraY) / sceneHeight; lty2 = lightMap.texH * (y2+cameraY) / sceneHeight; } else { ltx1 = (float) (x1+cameraX) / sceneWidth; ltx2 = (float) (x2+cameraX) / sceneWidth; lty1 = (float) (y1+cameraY) / sceneHeight; lty2 = (float) (y2+cameraY) / sceneHeight; } const GLfloat ltexCoords[] = { ltx1, lty1, ltx2, lty1, ltx1, lty2, ltx2, lty2 }; if (light && lightMap.data) { if (lightMapMode == LIGHTMAPMODE_HOTSPOT) { int lx=(int)(x+cameraX); int ly=(int)(y+cameraY); if (lx<0) lx = 0; else if (lx>=sceneWidth) lx = sceneWidth-1; if (ly<0) ly = 0; else if (ly>=sceneHeight) ly = sceneHeight-1; GLubyte *target; if (! NPOT_textures) { target = lightMap.data + (ly*getNextPOT(sceneWidth) + lx)*4; } else { target = lightMap.data + (ly*sceneWidth + lx)*4; } curLight[0] = target[0]; curLight[1] = target[1]; curLight[2] = target[2]; } else if (lightMapMode == LIGHTMAPMODE_PIXEL) { curLight[0] = curLight[1] = curLight[2] = 255; glActiveTexture(GL_TEXTURE1); glBindTexture (GL_TEXTURE_2D, lightMap.name); glActiveTexture(GL_TEXTURE0); } } else { curLight[0] = curLight[1] = curLight[2] = 255; } if (! (thisPerson->extra & EXTRA_RECTANGULAR)) checkColourChange (true); setDrawMode (thisPerson); glBindTexture (GL_TEXTURE_2D, fontPal.tex_names[single.texNum]); glEnable(GL_BLEND); glUseProgram(shader.smartScaler); GLuint uniform = glGetUniformLocation(shader.smartScaler, "useLightTexture"); if (uniform >= 0) glUniform1i(uniform, light && lightMapMode == LIGHTMAPMODE_PIXEL && lightMap.data); setPMVMatrix(shader.smartScaler); if (gameSettings.antiAlias == 1) { glUniform1i(glGetUniformLocation(shader.smartScaler, "antialias"), 1); } else { glUniform1i(glGetUniformLocation(shader.smartScaler, "antialias"), 0); } const GLfloat vertices[] = { x1, y1, z, x2, y1, z, x1, y2, z, x2, y2, z }; if (! mirror) { GLfloat tx3 = tx1; tx1 = tx2; tx2 = tx3; } const GLfloat texCoords[] = { tx2, ty1, tx1, ty1, tx2, ty2, tx1, ty2 }; drawQuad(shader.smartScaler, vertices, 2, texCoords, ltexCoords); glDisable(GL_BLEND); glUseProgram(0); if (light && lightMapMode == LIGHTMAPMODE_PIXEL) { glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE0); } setSecondaryColor(0., 0., 0.,1.); //glDisable(GL_COLOR_SUM); FIXME: replace line? // Are we pointing at the sprite? if (input.mouseX >= x1 && input.mouseX <= x2 && input.mouseY >= y1 && input.mouseY <= y2) { if (thisPerson->extra & EXTRA_RECTANGULAR) return true; return checkColourChange (false); } return false; }
void burnSpriteToBackDrop (int x1, int y1, sprite & single, const spritePalette & fontPal) { float tx1 = (float)(single.tex_x - 0.5) / fontPal.tex_w[single.texNum]; float ty1 = 0.0; float tx2 = (float)(single.tex_x + single.width + 0.5) / fontPal.tex_w[single.texNum]; float ty2 = (float)(single.height+2)/fontPal.tex_h[single.texNum]; const GLfloat spriteTexCoords[] = { tx1, ty1, tx2, ty1, tx1, ty2, tx2, ty2 }; x1 -= single.xhot; y1 -= single.yhot-1; float bx1 = (float)x1*backdropTexW/sceneWidth; float by1 = (float)y1*backdropTexH/sceneHeight; float bx2 = (float)(x1+single.width-1)*backdropTexW/sceneWidth; float by2 = (float)(y1+single.height-1)*backdropTexH/sceneHeight; const GLfloat backdropTexCoords[] = { bx1, by1, bx2, by1, bx1, by2, bx2, by2 }; const GLfloat backdropTexCoords2[] = { 0.0f, 0.0f, backdropTexW, 0.0f, 0.0f, backdropTexH, backdropTexW, backdropTexH }; int diffX = single.width+1; int diffY = single.height+2; if (x1 < 0) diffX += x1; if (y1 < 0) diffY += y1; if (x1 + diffX > sceneWidth) diffX = sceneWidth - x1; if (y1 + diffY > sceneHeight) diffY = sceneHeight - y1; if (diffX < 0) return; if (diffY < 0) return; setPixelCoords (true); setPrimaryColor(currentBurnR/255.f, currentBurnG/255.f, currentBurnB/255.f, 1.0f); GLfloat xoffset = 0.0f; while (xoffset < diffX) { int w = (diffX-xoffset < viewportWidth) ? diffX-xoffset : viewportWidth; GLfloat yoffset = 0.0f; while (yoffset < diffY) { int h = (diffY-yoffset < viewportHeight) ? diffY-yoffset : viewportHeight; const GLfloat backdropVertices[] = { -x1-xoffset, -y1+yoffset, 0.0f, sceneWidth-1.0f-x1-xoffset, -y1+yoffset, 0.0f, -x1-xoffset, sceneHeight-1.0f-y1+yoffset, 0.0f, sceneWidth-1.0f-x1-xoffset, sceneHeight-1.0f-y1+yoffset, 0.0f }; const GLfloat spriteVertices[] = { -xoffset, -yoffset, 0.0f, single.width-1-xoffset, -yoffset, 0.0f, -xoffset, single.height-1-yoffset, 0.0f, single.width-1-xoffset, single.height-1-yoffset, 0.0f }; glBindTexture (GL_TEXTURE_2D, backdropTextureName); glUseProgram(shader.texture); setPMVMatrix(shader.texture); drawQuad(shader.texture, backdropVertices, 1, backdropTexCoords2); glActiveTexture(GL_TEXTURE2); glBindTexture (GL_TEXTURE_2D, backdropTextureName); glActiveTexture(GL_TEXTURE0); glUseProgram(shader.paste); GLint uniform = glGetUniformLocation(shader.paste, "useLightTexture"); if (uniform >= 0) glUniform1i(uniform, 0); // No lighting setPMVMatrix(shader.paste); glBindTexture (GL_TEXTURE_2D, fontPal.burnTex_names[single.texNum]); //FIXME: Test this some more. Also pasting the backdrop again is not strictly necessary but allows using the paste shader. drawQuad(shader.paste, spriteVertices, 3, spriteTexCoords, NULL, backdropTexCoords); glUseProgram(0); // Copy Our ViewPort To The Texture copyTexSubImage2D(GL_TEXTURE_2D, 0, (x1<0) ? xoffset : x1+xoffset, (y1<0) ? yoffset: y1+yoffset, viewportOffsetX, viewportOffsetY, w, h, backdropTextureName); yoffset += viewportHeight; } xoffset += viewportWidth; } setPixelCoords (false); }
void pasteSpriteToBackDrop (int x1, int y1, sprite & single, const spritePalette & fontPal) { float tx1 = (float)(single.tex_x) / fontPal.tex_w[single.texNum]; float ty1 = 0.0; float tx2 = (float)(single.tex_x + single.width) / fontPal.tex_w[single.texNum]; float ty2 = (float)(single.height)/fontPal.tex_h[single.texNum]; float btx1; float btx2; float bty1; float bty2; int diffX = single.width; int diffY = single.height; x1 -= single.xhot; y1 -= single.yhot; if (! NPOT_textures) { btx1 = backdropTexW * x1 / sceneWidth; btx2 = backdropTexW * (x1+single.width) / sceneWidth; bty1 = backdropTexH * y1 / sceneHeight; bty2 = backdropTexH * (y1+single.height) / sceneHeight; } else { btx1 = (float) x1 / sceneWidth; btx2 = (float) (x1+single.width) / sceneWidth; bty1 = (float) y1 / sceneHeight; bty2 = (float) (y1+single.height) / sceneHeight; } const GLfloat btexCoords[] = { btx1, bty1, btx2, bty1, btx1, bty2, btx2, bty2 }; if (x1 < 0) diffX += x1; if (y1 < 0) diffY += y1; if (x1 + diffX > sceneWidth) diffX = sceneWidth - x1; if (y1 + diffY > sceneHeight) diffY = sceneHeight - y1; if (diffX < 0) return; if (diffY < 0) return; setPixelCoords (true); int xoffset = 0; while (xoffset < diffX) { int w = (diffX-xoffset < viewportWidth) ? diffX-xoffset : viewportWidth; int yoffset = 0; while (yoffset < diffY) { int h = (diffY-yoffset < viewportHeight) ? diffY-yoffset : viewportHeight; // Render the sprite to the backdrop // (using mulitexturing, so the backdrop is seen where alpha < 1.0) glActiveTexture(GL_TEXTURE2); glBindTexture (GL_TEXTURE_2D, backdropTextureName); glActiveTexture(GL_TEXTURE0); glUseProgram(shader.paste); GLint uniform = glGetUniformLocation(shader.paste, "useLightTexture"); if (uniform >= 0) glUniform1i(uniform, 0); // No lighting setPMVMatrix(shader.paste); setPrimaryColor(fontPal.originalRed/255.f, fontPal.originalGreen/255.f, fontPal.originalBlue/255.f, 1.0f); glBindTexture (GL_TEXTURE_2D, fontPal.tex_names[single.texNum]); //glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); const GLfloat vertices[] = { (GLfloat)-xoffset, (GLfloat)-yoffset, 0., (GLfloat)single.width-xoffset, (GLfloat)-yoffset, 0., (GLfloat)-xoffset, (GLfloat)single.height-yoffset, 0., (GLfloat)single.width-xoffset, (GLfloat)single.height-yoffset, 0. }; const GLfloat texCoords[] = { tx1, ty1, tx2, ty1, tx1, ty2, tx2, ty2 }; drawQuad(shader.paste, vertices, 3, texCoords, NULL, btexCoords); // Copy Our ViewPort To The Texture glUseProgram(0); copyTexSubImage2D(GL_TEXTURE_2D, 0, (int) ((x1<0) ? xoffset: x1+xoffset), (int) ((y1<0) ? yoffset: y1+yoffset), (int) ((x1<0) ?viewportOffsetX-x1:viewportOffsetX), (int) ((y1<0) ?viewportOffsetY-y1:viewportOffsetY), w, h, backdropTextureName); yoffset += viewportHeight; } xoffset += viewportWidth; } setPixelCoords (false); }
void drawLine(int x1, int y1, int x2, int y2) { int x, y; bool backwards = false; if (x1 < 0) x1 = 0; if (y1 < 0) y1 = 0; if (x2 < 0) x2 = 0; if (y2 < 0) y2 = 0; if (x1 > sceneWidth) x1 = sceneWidth - 1; if (x2 > sceneWidth) x2 = sceneWidth - 1; if (y1 > sceneHeight) y1 = sceneHeight - 1; if (y2 > sceneHeight) y2 = sceneHeight - 1; if (x1 > x2) { x = x2; backwards = !backwards; } else x = x1; if (y1 > y2) { y = y2; backwards = !backwards; } else y = y1; int diffX = abs(x2-x1); int diffY = abs(y2-y1); if (! diffX) { diffX = 1; if (x == sceneWidth - 1) x = sceneWidth -2; } if (! diffY) { diffY = 1; if (y == sceneHeight - 1) y = sceneHeight -2; } setPixelCoords (true); glLineWidth (2.0); int xoffset = 0; while (xoffset < diffX) { int w = (diffX-xoffset < viewportWidth) ? diffX-xoffset : viewportWidth; int yoffset = 0; while (yoffset < diffY) { int h = (diffY-yoffset < viewportHeight) ? diffY-yoffset : viewportHeight; // Render the scene - first the old backdrop glBindTexture (GL_TEXTURE_2D, backdropTextureName); //glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); const GLfloat vertices[] = { (GLfloat)-x-xoffset, (GLfloat)1-y-yoffset, 0., (GLfloat)sceneWidth-x-xoffset, (GLfloat)1-y-yoffset, 0., (GLfloat)-x-xoffset, (GLfloat)sceneHeight-y-yoffset, 0., (GLfloat)sceneWidth-x-xoffset, (GLfloat)sceneHeight-y-yoffset, 0. }; const GLfloat texCoords[] = { 0.0f, 0.0f, backdropTexW, 0.0f, 0.0f, backdropTexH, backdropTexW, backdropTexH }; glUseProgram(shader.texture); setPMVMatrix(shader.texture); drawQuad(shader.texture, vertices, 1, texCoords); // Then the line //FIXME:Removing the lines doesn't work, but also didn't work properly before. GLint xo1=-xoffset, xo2=-xoffset; if (! backwards) { xo2 += diffX; } else { xo1 += diffX; } const GLint lineVertices[] = { xo1, -yoffset, 0, xo2, -yoffset+diffY, 0, }; glUseProgram(shader.color); setPMVMatrix(shader.color); glUniform4f(glGetUniformLocation(shader.color, "myColor"), 0.0f, 0.0f, 0.0f, 1.0f); int vertexLoc = glGetAttribLocation(shader.color, "myVertex"); glEnableVertexAttribArray(vertexLoc); glVertexAttribPointer(vertexLoc, 3, GL_INT, GL_FALSE, 0, lineVertices); glDrawArrays(GL_LINES, 0, 2); glDisableVertexAttribArray(vertexLoc); glUseProgram(0); // Copy Our ViewPort To The Texture copyTexSubImage2D(GL_TEXTURE_2D, 0, x+xoffset, y+yoffset, viewportOffsetX, viewportOffsetY, w, h, backdropTextureName); yoffset += viewportHeight; } xoffset += viewportWidth; } setPixelCoords (false); }