void Context::newTexture(unsigned int width, unsigned int height) { ods("OpenGL: newTex"); if (texture == ~0) { oglBindTexture(GL_TEXTURE_2D, 0); oglDeleteTextures(1, &texture); texture = ~0; } oglGenTextures(1, &texture); oglBindTexture(GL_TEXTURE_2D, texture); oglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); oglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); oglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); oglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); unsigned char *ptr = new unsigned char[width*height*4]; memset(ptr, 0, width*height*4); oglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, ptr); delete [] ptr; }
void GraphicsBase::draw() { if (indices.empty()) return; if (isWhite_ == false) { glPushColor(); glMultColor(r_, g_, b_, a_); } if (data) { oglEnable(GL_TEXTURE_2D); oglBindTexture(GL_TEXTURE_2D, data->id()); oglEnableClientState(GL_VERTEX_ARRAY); oglEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, &vertices[0]); glTexCoordPointer(2, GL_FLOAT, 0, &texcoords[0]); oglDrawElements(mode, indices.size(), GL_UNSIGNED_SHORT, &indices[0]); oglDisableClientState(GL_VERTEX_ARRAY); oglDisableClientState(GL_TEXTURE_COORD_ARRAY); } else { oglDisable(GL_TEXTURE_2D); oglEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, &vertices[0]); oglDrawElements(mode, indices.size(), GL_UNSIGNED_SHORT, &indices[0]); oglDisableClientState(GL_VERTEX_ARRAY); } if (isWhite_ == false) { glPopColor(); } }
void Context::blit(unsigned int x, unsigned int y, unsigned int w, unsigned int h) { ods("OpenGL: Blit %d %d %d %d -- %d %d : %d", x, y, w, h, uiWidth, uiHeight, texture); if (texture == ~0) return; oglBindTexture(GL_TEXTURE_2D, texture); if ((x == 0) && (y == 0) && (w == uiWidth) && (h == uiHeight)) { oglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, uiWidth, uiHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, a_ucTexture); } else { if (w != uiWidth) oglPixelStorei(GL_UNPACK_ROW_LENGTH, uiWidth); oglTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_BGRA, GL_UNSIGNED_BYTE, a_ucTexture + 4 * (y * uiWidth + x)); if (w != uiWidth) oglPixelStorei(GL_UNPACK_ROW_LENGTH, 0); } }
void Context::draw(HDC hdc) { // DEBUG // sm->bDebug = true; clock_t t = clock(); float elapsed = static_cast<float>(t - timeT) / CLOCKS_PER_SEC; ++frameCount; if (elapsed > OVERLAY_FPS_INTERVAL) { OverlayMsg om; om.omh.uiMagic = OVERLAY_MAGIC_NUMBER; om.omh.uiType = OVERLAY_MSGTYPE_FPS; om.omh.iLength = sizeof(OverlayMsgFps); om.omf.fps = frameCount / elapsed; sendMessage(om); frameCount = 0; timeT = t; } unsigned int width, height; width = oGetDeviceCaps(hdc, HORZRES); height = oGetDeviceCaps(hdc, VERTRES); HWND hwnd = WindowFromDC(hdc); if (hwnd) { RECT r; if (GetClientRect(hwnd, &r)) { width = r.right - r.left; height = r.bottom - r.top; } } ods("OpenGL: DrawStart: Screen is %d x %d", width, height); checkMessage(width, height); oglViewport(0, 0, width, height); oglMatrixMode(GL_PROJECTION); oglLoadIdentity(); oglOrtho(0, width, height, 0, -100.0, 100.0); oglMatrixMode(GL_MODELVIEW); oglBindTexture(GL_TEXTURE_2D, texture); oglPushMatrix(); oglLoadIdentity(); float w = static_cast<float>(uiWidth); float h = static_cast<float>(uiHeight); float left = static_cast<float>(uiLeft); float top = static_cast<float>(uiTop); float right = static_cast<float>(uiRight); float bottom = static_cast<float>(uiBottom); float xm = (left) / w; float ym = (top) / h; float xmx = (right) / w; float ymx = (bottom) / h; oglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); oglBegin(GL_QUADS); oglTexCoord2f(xm, ymx); oglVertex2f(left, bottom); oglTexCoord2f(xm, ym); oglVertex2f(left, top); oglTexCoord2f(xmx, ym); oglVertex2f(right, top); oglTexCoord2f(xmx, ymx); oglVertex2f(right, bottom); oglEnd(); oglPopMatrix(); }
void TileMap::doDraw(const CurrentTransform& transform, float hsx, float hsy, float hex, float hey) { int sx, sy, ex, ey; { // inverse transformed hardware start/end x/y float x1, y1, x2, y2, x3, y3, x4, y4; Matrix inverse = transform.inverse(); inverse.transformPoint(hsx, hsy, &x1, &y1); inverse.transformPoint(hex, hsy, &x2, &y2); inverse.transformPoint(hsx, hey, &x3, &y3); inverse.transformPoint(hex, hey, &x4, &y4); float thsx = std::min(std::min(x1, x2), std::min(x3, x4)); float thsy = std::min(std::min(y1, y2), std::min(y3, y4)); float thex = std::max(std::max(x1, x2), std::max(x3, x4)); float they = std::max(std::max(y1, y2), std::max(y3, y4)); // cell size width, cell size height float csw = std::max(std::max(tilewidth_, tileheight_), displaywidth_); float csh = std::max(std::max(tilewidth_, tileheight_), displayheight_); sx = floor((thsx - csw) / displaywidth_) + 1; sy = floor(thsy / displayheight_); ex = floor(thex / displaywidth_) + 1; ey = floor((they + csh) / displayheight_); // extra 1 block around sx--; sy--; ex++; ey++; sx = std::max(sx, 0); sy = std::max(sy, 0); ex = std::min(ex, width_); ey = std::min(ey, height_); } int tileCount = 0; for (int y = sy; y < ey; ++y) for (int x = sx; x < ex; ++x) { int index = x + y * width_; int tx = tileids_[index].x; int ty = tileids_[index].y; if (!isEmpty(tx, ty)) tileCount++; } if (tileCount == 0) return; vertices.resize(tileCount * 12); texcoords.resize(tileCount * 12); int pos = 0; for (int y = sy; y < ey; ++y) for (int x = sx; x < ex; ++x) { int index = x + y * width_; int tx = tileids_[index].x; int ty = tileids_[index].y; int flip = tileids_[index].flip; if (!isEmpty(tx, ty)) { bool flip_horizontal = (flip & FLIP_HORIZONTAL); bool flip_vertical = (flip & FLIP_VERTICAL); bool flip_diagonal = (flip & FLIP_DIAGONAL); float x0, y0, x1, y1; if (!flip_diagonal) { x0 = x * displaywidth_; y0 = y * displayheight_ - (tileheight_ - displayheight_); x1 = x0 + tilewidth_; y1 = y0 + tileheight_; } else { x0 = x * displaywidth_; y0 = y * displayheight_ - (tilewidth_ - displayheight_); x1 = x0 + tileheight_; y1 = y0 + tilewidth_; } vertices[pos + 0] = x0; vertices[pos + 1] = y0; vertices[pos + 2] = x1; vertices[pos + 3] = y0; vertices[pos + 4] = x0; vertices[pos + 5] = y1; vertices[pos + 6] = x1; vertices[pos + 7] = y0; vertices[pos + 8] = x1; vertices[pos + 9] = y1; vertices[pos + 10] = x0; vertices[pos + 11] = y1; int u0 = marginx_ + tx * (tilewidth_ + spacingx_); int v0 = marginy_ + ty * (tileheight_ + spacingy_); int u1 = marginx_ + tx * (tilewidth_ + spacingx_) + tilewidth_; int v1 = marginy_ + ty * (tileheight_ + spacingy_) + tileheight_; float fu0 = (float)u0 / (float)texture_->data->exwidth; float fv0 = (float)v0 / (float)texture_->data->exheight; float fu1 = (float)u1 / (float)texture_->data->exwidth; float fv1 = (float)v1 / (float)texture_->data->exheight; fu0 *= texture_->uvscalex; fv0 *= texture_->uvscaley; fu1 *= texture_->uvscalex; fv1 *= texture_->uvscaley; if (flip_horizontal) std::swap(fu0, fu1); if (flip_vertical) std::swap(fv0, fv1); if (flip_diagonal && (flip_vertical != flip_horizontal)) { std::swap(fu0, fu1); std::swap(fv0, fv1); } fu0 += 0.0001f; fv0 += 0.0001f; fu1 -= 0.0001f; fv1 -= 0.0001f; if (!flip_diagonal) { texcoords[pos + 0] = fu0; texcoords[pos + 1] = fv0; texcoords[pos + 2] = fu1; texcoords[pos + 3] = fv0; texcoords[pos + 4] = fu0; texcoords[pos + 5] = fv1; texcoords[pos + 6] = fu1; texcoords[pos + 7] = fv0; texcoords[pos + 8] = fu1; texcoords[pos + 9] = fv1; texcoords[pos + 10] = fu0; texcoords[pos + 11] = fv1; } else { texcoords[pos + 0] = fu0; texcoords[pos + 1] = fv0; texcoords[pos + 2] = fu0; texcoords[pos + 3] = fv1; texcoords[pos + 4] = fu1; texcoords[pos + 5] = fv0; texcoords[pos + 6] = fu0; texcoords[pos + 7] = fv1; texcoords[pos + 8] = fu1; texcoords[pos + 9] = fv1; texcoords[pos + 10] = fu1; texcoords[pos + 11] = fv0; } pos += 12; } } oglEnable(GL_TEXTURE_2D); oglBindTexture(GL_TEXTURE_2D, texture_->data->id()); oglArrayPointer(VertexArray,2, GL_FLOAT, &vertices[0]); oglEnableClientState(VertexArray); oglArrayPointer(TextureArray,2, GL_FLOAT, &texcoords[0]); oglEnableClientState(TextureArray); oglDrawArrays(GL_TRIANGLES, 0, tileCount * 6); oglDisableClientState(VertexArray); oglDisableClientState(TextureArray); }