Пример #1
0
void UIEnd() {
	ui_draw2d.End();
	ui_draw2d_front.End();

	ui_draw2d.Flush();
	ui_draw2d_front.Flush();
}
Пример #2
0
void UIInit(const Atlas *atlas, const UITheme &ui_theme) {
	ui_draw2d.SetAtlas(atlas);
	ui_draw2d_front.SetAtlas(atlas);
	themeAtlas = atlas;
	theme = ui_theme;
	memset(&uistate, 0, sizeof(uistate));
}
Пример #3
0
// TODO
int UIHSlider(int id, int x, int y, int w, int max, int *value) {
	// Calculate mouse cursor's relative y offset
	int xpos = ((256 - 16) * *value) / max;

	for (int i = 0; i < MAX_POINTERS; i++) {
		// Check for hotness
		if (UIRegionHit(i, x+8, y+8, 16, 255, 0)) {
			uistate.hotitem[i] = id;
			if (uistate.activeitem[i] == 0 && uistate.mousedown[i])
				uistate.activeitem[i] = id;
		}

		// Update widget value
		if (uistate.activeitem[i] == id) {
			int mousepos = uistate.mousey[i] - (y + 8);
			if (mousepos < 0) mousepos = 0;
			if (mousepos > 255) mousepos = 255;
			int v = (mousepos * max) / 255;
			if (v != *value) {
				*value = v;
				return 1;
			}
		}
	}
	// Render the scrollbar
	ui_draw2d.Rect(x, y, 32, 256+16, 0x777777);

	ui_draw2d.Rect(x+8+xpos, y+8, 16, 16, 0xffffff);

	return 0;
}
Пример #4
0
	//------------------------------------------------------
	void DrawSheet::_removeDrawOperation(DrawOperation* toRemove) {
		DrawBuffer* buf = getBufferForOperation(toRemove);

		if (buf)
			buf->removeDrawOperation(toRemove);

		mDrawOpMap.erase(toRemove->getID());
	}
Пример #5
0
void UIText(int font, const LayoutManager &layout, const char *text, uint32_t color, float scale, int align)
{
	ui_draw2d.SetFontScale(scale, scale);
	float w, h;
	ui_draw2d.MeasureText(font, text, &w, &h);
	float x, y;
	layout.GetPos(&w, &h, &x, &y);
	UIText(font, x, y, text, color, scale, 0);
	ui_draw2d.SetFontScale(1.0f, 1.0f);
}
Пример #6
0
int UIButton(int id, const LayoutManager &layout, float w, float h, const char *text, int button_align) {
	if (h == 0.0f)
		h = themeAtlas->images[theme.buttonImage].h;

	float x, y;
	layout.GetPos(&w, &h, &x, &y);

	if (button_align & ALIGN_HCENTER) x -= w / 2;
	if (button_align & ALIGN_VCENTER) y -= h / 2;
	if (button_align & ALIGN_RIGHT) x -= w;
	if (button_align & ALIGN_BOTTOM) y -= h;

	int txOffset = 0;

	int clicked = 0;
	for (int i = 0; i < MAX_POINTERS; i++) {
		// Check whether the button should be hot, use a generous margin for touch ease
		if (UIRegionHit(i, x, y, w, h, 8)) {
			uistate.hotitem[i] = id;
			if (uistate.activeitem[i] == 0 && uistate.mousedown[i]) {
				uistate.activeitem[i] = id;
			}
		}

		if (uistate.hotitem[i] == id) {
			if (uistate.activeitem[i] == id) {
				// Button is both 'hot' and 'active'
				txOffset = 2;
			} else {
				// Button is merely 'hot'
			}
		} else {
			// button is not hot, but it may be active
		}

		// If button is hot and active, but mouse button is not
		// down, the user must have clicked the button.
		if (uistate.mousedown[i] == 0 &&
				uistate.hotitem[i] == id &&
				uistate.activeitem[i] == id) {
			clicked = 1;
		}
	}

	// Render button

	if (h == themeAtlas->images[theme.buttonImage].h)
		ui_draw2d.DrawImage2GridH((txOffset && theme.buttonSelected) ? theme.buttonSelected : theme.buttonImage, x, y, x + w);
	else
		ui_draw2d.DrawImage4Grid((txOffset && theme.buttonSelected) ? theme.buttonSelected : theme.buttonImage, x, y, x + w, y + h);
	ui_draw2d.DrawTextShadow(theme.uiFont, text, x + w/2, y + h/2 + txOffset, 0xFFFFFFFF, ALIGN_HCENTER | ALIGN_VCENTER);

	uistate.lastwidget = id;
	return clicked;
}
Пример #7
0
	//------------------------------------------------------
	void DrawSheet::addDrawOperation(DrawOperation* drawOp) {
		DrawBuffer* buf = getBufferForOperation(drawOp, true);

		assert(buf);
		
		if (buf) {
			buf->addDrawOperation(drawOp);
			mDrawOpMap[drawOp->getID()] = drawOp;
			drawOp->onSheetRegister(this);
		}
	}
Пример #8
0
int UICheckBox(int id, int x, int y, const char *text, int align, bool *value) {
#ifdef _WIN32
	const int h = 32;
#else
	const int h = 48;
#endif
	float tw, th;
	ui_draw2d.MeasureText(theme.uiFont, text, &tw, &th);
	int w = themeAtlas->images[theme.checkOn].w + UI_SPACE + tw;
	if (align & ALIGN_HCENTER) x -= w / 2;
	if (align & ALIGN_VCENTER) y -= h / 2;
	if (align & ALIGN_RIGHT) x -= w;
	if (align & ALIGN_BOTTOMRIGHT) y -= h;

	int txOffset = 0;
	int clicked = 0;
	for (int i = 0; i < MAX_POINTERS; i++) {

		// Check whether the button should be hot
		if (UIRegionHit(i, x, y, w, h, 8)) {
			uistate.hotitem[i] = id;
			if (uistate.activeitem[i] == 0 && uistate.mousedown[i])
				uistate.activeitem[i] = id;
		}

		// Render button

		if (uistate.hotitem[i] == id) {
			if (uistate.activeitem[i] == id) {
				// Button is both 'hot' and 'active'
				txOffset = 2;
			} else {
				// Button is merely 'hot'
			}
		} else {
			// button is not hot, but it may be active
		}
		// If button is hot and active, but mouse button is not
		// down, the user must have clicked the button.
		if (uistate.mousedown[i] == 0 &&
			uistate.hotitem[i] == id &&
			uistate.activeitem[i] == id) {
				*value = !(*value);
				clicked = 1;
		}
	}

	ui_draw2d.DrawImage((*value) ? theme.checkOn : theme.checkOff, x, y+h/2, 1.0f, 0xFFFFFFFF, ALIGN_LEFT | ALIGN_VCENTER);
	ui_draw2d.DrawTextShadow(theme.uiFont, text, x + themeAtlas->images[theme.checkOn].w + UI_SPACE, y + txOffset + h/2, 0xFFFFFFFF, ALIGN_LEFT | ALIGN_VCENTER);


	uistate.lastwidget = id;
	return clicked;
}
Пример #9
0
	//------------------------------------------------------
	void DrawSheet::_markDirty(DrawOperation* drawOp) {
		// Marking dirty could mean the buffer changes.
		// We ignore that. Atlasing can only happen before creating the Draw Ops.

		// look up the DrawBuffer for this DrawOp.
		DrawBuffer* buf = getBufferForOperation(drawOp);

		assert(buf);

		// mark the buffer dirty, queue the change
		buf->queueUpdate(drawOp);
	}
Пример #10
0
void TouchButton::draw(DrawBuffer &db, uint32_t color, uint32_t colorOverlay)
{
	float scale = 1.0f;
	if (isDown_) {
		color |= 0xFF000000;
		colorOverlay |= 0xFF000000;
		scale = 2.0f;
	}
	scale *= scale_;
	// We only mirror background
	db.DrawImageRotated(imageIndex_, x_ + w_*scale_/2, y_ + h_*scale_/2, scale, rotationAngle_, color, mirror_h_);
	if (overlayImageIndex_ != -1)
		db.DrawImageRotated(overlayImageIndex_, x_ + w_*scale_/2, y_ + h_*scale_/2, scale, rotationAngle_, colorOverlay);
}
Пример #11
0
	//------------------------------------------------------
	void DrawSheet::_sourceChanged(DrawOperation* op, const DrawSourcePtr& oldsrc) {
		DrawSourceBase::ID oldID = oldsrc->getSourceID();
		DrawSourceBase::ID newID = op->getDrawSourceBase()->getSourceID();
		
		if (oldID != newID) {
			DrawBuffer* dbo = getBufferForSourceID(oldID);
			DrawBuffer* dbn = getBufferForSourceID(newID);
			
			// remove from the old buffer
			// add into the new one
			dbo->removeDrawOperation(op);
			dbn->addDrawOperation(op);
		}
	}
Пример #12
0
void TouchCrossPad::draw(DrawBuffer &db, uint32_t color, uint32_t colorOverlay)
{
	static const float xoff[4] = {1, 0, -1, 0};
	static const float yoff[4] = {0, 1, 0, -1};
	static const int dir[4] = {PAD_BUTTON_RIGHT, PAD_BUTTON_DOWN, PAD_BUTTON_LEFT, PAD_BUTTON_UP};
	for (int i = 0; i < 4; i++) {
		float x = x_ + xoff[i] * scale_ * radius_;
		float y = y_ + yoff[i] * scale_ * radius_;
		float angle = i * M_PI / 2;
		float imgScale = (down_ & dir[i]) ? scale_ * 2 : scale_;
		db.DrawImageRotated(arrowIndex_, x, y, imgScale, angle + PI, color, false);
		if (overlayIndex_ != -1)
			db.DrawImageRotated(overlayIndex_, x, y, imgScale, angle + PI, colorOverlay);
	}
}
Пример #13
0
int UIImageButton(int id, const LayoutManager &layout, float w, int image, int button_align) {
	float h = 64;
	float x, y;
	layout.GetPos(&w, &h, &x, &y);

	if (button_align & ALIGN_HCENTER) x -= w / 2;
	if (button_align & ALIGN_VCENTER) y -= h / 2;
	if (button_align & ALIGN_RIGHT) x -= w;
	if (button_align & ALIGN_BOTTOMRIGHT) y -= h;

	int txOffset = 0;
	int clicked = 0;
	for (int i = 0; i < MAX_POINTERS; i++) {
		// Check whether the button should be hot, use a generous margin for touch ease
		if (UIRegionHit(i, x, y, w, h, 8)) {
			uistate.hotitem[i] = id;
			if (uistate.activeitem[i] == 0 && uistate.mousedown[i])
				uistate.activeitem[i] = id;
		}

		if (uistate.hotitem[i] == id) {
			if (uistate.activeitem[i] == id) {
				// Button is both 'hot' and 'active'
				txOffset = 2;
			} else {
				// Button is merely 'hot'
			}
		} else {
			// button is not hot, but it may be active§
		}

		// If button is hot and active, but mouse button is not
		// down, the user must have clicked the button.
		if (uistate.mousedown[i] == 0 &&
			uistate.hotitem[i] == id &&
			uistate.activeitem[i] == id) {
				clicked = 1;
		}
	}

	// Render button

	ui_draw2d.DrawImage2GridH(theme.buttonImage, x, y, x + w);
	ui_draw2d.DrawImage(image, x + w/2, y + h/2 + txOffset, 1.0f, 0xFFFFFFFF, ALIGN_HCENTER | ALIGN_VCENTER);

	uistate.lastwidget = id;
	return clicked;
}
Пример #14
0
void GameRenderer::drawColour(const glm::vec4& colour, glm::vec4 extents)
{
	glUseProgram(ssRectProgram);

	// Move into NDC
	extents.x /= renderer->getViewport().x;
	extents.y /= renderer->getViewport().y;
	extents.z /= renderer->getViewport().x;
	extents.w /= renderer->getViewport().y;
	extents.x += extents.z / 2.f;
	extents.y += extents.w / 2.f;
	extents.x -= .5f;
	extents.y -= .5f;
	extents *= glm::vec4(2.f,-2.f, 1.f, 1.f);

	glEnable(GL_BLEND);
	glUniform2f(ssRectOffset, extents.x, extents.y);
	glUniform2f(ssRectSize, extents.z, extents.w);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, 0);
	glUniform1i(ssRectTexture, 0);
	glUniform4f(ssRectColour, colour.r, colour.g, colour.b, colour.a);

	glBindVertexArray( ssRectDraw.getVAOName() );
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

	// Ooops
	renderer->invalidate();
}
Пример #15
0
void UIEnd() {
	for (int i = 0; i < MAX_POINTERS; i++) {
		if (uistate.mousedown[i] == 0) {
			uistate.activeitem[i] = 0;
		} else {
			if (uistate.activeitem[i] == 0) {
				uistate.activeitem[i] = -1;
			}
		}
	}
	ui_draw2d.End();
	ui_draw2d_front.End();

	if (uistate.ui_tick > 0)
		uistate.ui_tick--;
}
Пример #16
0
void GameRenderer::renderLetterbox()
{
	glUseProgram(ssRectProgram);
	const float cinematicExperienceSize = 0.15f;
	glUniform2f(ssRectOffset, 0.f, -1.f * (1.f - cinematicExperienceSize));
	glUniform2f(ssRectSize, 1.f, cinematicExperienceSize);

	glBindTexture(GL_TEXTURE_2D, 0);
	glUniform1i(ssRectTexture, 0);
	glUniform4f(ssRectColour, 0.f, 0.f, 0.f, 1.f);

	glBindVertexArray( ssRectDraw.getVAOName() );
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

	glUniform2f(ssRectOffset, 0.f, 1.f * (1.f - cinematicExperienceSize));
	glUniform2f(ssRectSize, 1.f, cinematicExperienceSize);

	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
Пример #17
0
void TextDrawerWin32::DrawString(DrawBuffer &target, const char *str, float x, float y, uint32_t color, int align) {
	using namespace Draw;
	if (!strlen(str))
		return;

	uint32_t stringHash = hash::Adler32((const uint8_t *)str, strlen(str));
	uint32_t entryHash = stringHash ^ fontHash_ ^ (align << 24);

	target.Flush(true);

	TextStringEntry *entry;

	auto iter = cache_.find(entryHash);
	if (iter != cache_.end()) {
		entry = iter->second.get();
		entry->lastUsedFrame = frameCount_;
	} else {
		// Render the string to our bitmap and save to a GL texture.
		std::wstring wstr = ConvertUTF8ToWString(ReplaceAll(str, "\n", "\r\n"));
		SIZE size;

		auto iter = fontMap_.find(fontHash_);
		if (iter != fontMap_.end()) {
			SelectObject(ctx_->hDC, iter->second->hFont);
		}
		// Set text properties
		SetTextColor(ctx_->hDC, 0xFFFFFF);
		SetBkColor(ctx_->hDC, 0);
		SetTextAlign(ctx_->hDC, TA_TOP);

		// This matters for multi-line text - DT_CENTER is horizontal only.
		UINT dtAlign = (align & ALIGN_HCENTER) == 0 ? DT_LEFT : DT_CENTER;

		RECT textRect = { 0 };
		DrawTextExW(ctx_->hDC, (LPWSTR)wstr.c_str(), (int)wstr.size(), &textRect, DT_HIDEPREFIX | DT_TOP | dtAlign | DT_CALCRECT, 0);
		size.cx = textRect.right;
		size.cy = textRect.bottom;

		// GetTextExtentPoint32(ctx_->hDC, wstr.c_str(), (int)wstr.size(), &size);
		RECT rc = { 0 };
		rc.right = size.cx + 4;
		rc.bottom = size.cy + 4;
		FillRect(ctx_->hDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
		//ExtTextOut(ctx_->hDC, 0, 0, ETO_OPAQUE | ETO_CLIPPED, NULL, wstr.c_str(), (int)wstr.size(), NULL);
		DrawTextExW(ctx_->hDC, (LPWSTR)wstr.c_str(), (int)wstr.size(), &rc, DT_HIDEPREFIX | DT_TOP | dtAlign, 0);

		if (size.cx > MAX_TEXT_WIDTH)
			size.cx = MAX_TEXT_WIDTH;
		if (size.cy > MAX_TEXT_HEIGHT)
			size.cy = MAX_TEXT_HEIGHT;

		entry = new TextStringEntry();
		entry->width = size.cx;
		entry->height = size.cy;
		entry->bmWidth = (size.cx + 3) & ~3;
		entry->bmHeight = (size.cy + 3) & ~3;
		entry->lastUsedFrame = frameCount_;

		DataFormat texFormat;
		// For our purposes these are equivalent, so just choose the supported one. D3D can emulate them.
		if (draw_->GetDataFormatSupport(Draw::DataFormat::A4R4G4B4_UNORM_PACK16) & FMT_TEXTURE)
			texFormat = Draw::DataFormat::A4R4G4B4_UNORM_PACK16;
		else if (draw_->GetDataFormatSupport(Draw::DataFormat::B4G4R4A4_UNORM_PACK16) & FMT_TEXTURE)
			texFormat = Draw::DataFormat::B4G4R4A4_UNORM_PACK16;
		else
			texFormat = Draw::DataFormat::R8G8B8A8_UNORM;

		// Convert the bitmap to a Thin3D compatible array of 16-bit pixels. Can't use a single channel format
		// because we need white. Well, we could using swizzle, but not all our backends support that.
		TextureDesc desc{};
		uint32_t *bitmapData32 = nullptr;
		uint16_t *bitmapData16 = nullptr;
		if (texFormat == Draw::DataFormat::R8G8B8A8_UNORM || texFormat == Draw::DataFormat::B8G8R8A8_UNORM) {
			bitmapData32 = new uint32_t[entry->bmWidth * entry->bmHeight];
			for (int y = 0; y < entry->bmHeight; y++) {
				for (int x = 0; x < entry->bmWidth; x++) {
					uint8_t bAlpha = (uint8_t)(ctx_->pBitmapBits[MAX_TEXT_WIDTH * y + x] & 0xff);
					bitmapData32[entry->bmWidth * y + x] = (bAlpha << 24) | 0x00ffffff;
				}
			}
			desc.initData.push_back((uint8_t *)bitmapData32);
		} else if (texFormat == Draw::DataFormat::B4G4R4A4_UNORM_PACK16) {
			bitmapData16 = new uint16_t[entry->bmWidth * entry->bmHeight];
			for (int y = 0; y < entry->bmHeight; y++) {
				for (int x = 0; x < entry->bmWidth; x++) {
					uint8_t bAlpha = (uint8_t)((ctx_->pBitmapBits[MAX_TEXT_WIDTH * y + x] & 0xff) >> 4);
					bitmapData16[entry->bmWidth * y + x] = (bAlpha) | 0xfff0;
				}
			}
			desc.initData.push_back((uint8_t *)bitmapData16);
		} else if (texFormat == Draw::DataFormat::A4R4G4B4_UNORM_PACK16) {
Пример #18
0
void UIBegin() {
	for (int i = 0; i < MAX_POINTERS; i++)
		uistate.hotitem[i] = 0;
	ui_draw2d.Begin();
	ui_draw2d_front.Begin();
}
Пример #19
0
GameRenderer::GameRenderer(Logger* log, GameData* _data)
	: data(_data)
	, logger(log)
	, renderer(new OpenGLRenderer)
	, _renderAlpha(0.f)
	, _renderWorld(nullptr)
	, cullOverride(false)
	, map(renderer, _data)
	, water(this)
	, text(this)
{
	logger->info("Renderer", renderer->getIDString());

	worldProg = renderer->createShader(
				GameShaders::WorldObject::VertexShader,
				GameShaders::WorldObject::FragmentShader);

	renderer->setUniformTexture(worldProg, "texture", 0);
	renderer->setProgramBlockBinding(worldProg, "SceneData", 1);
	renderer->setProgramBlockBinding(worldProg, "ObjectData", 2);
	
	particleProg = renderer->createShader(
		GameShaders::WorldObject::VertexShader,
		GameShaders::Particle::FragmentShader);
	
	renderer->setUniformTexture(particleProg, "texture", 0);
	renderer->setProgramBlockBinding(particleProg, "SceneData", 1);
	renderer->setProgramBlockBinding(particleProg, "ObjectData", 2);

	skyProg = renderer->createShader(
		GameShaders::Sky::VertexShader,
		GameShaders::Sky::FragmentShader);

	renderer->setProgramBlockBinding(skyProg, "SceneData", 1);

	postProg = renderer->createShader(
		GameShaders::DefaultPostProcess::VertexShader,
		GameShaders::DefaultPostProcess::FragmentShader);

	glGenVertexArrays( 1, &vao );

	glGenTextures(1, &m_missingTexture);
	glBindTexture(GL_TEXTURE_2D, m_missingTexture);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, kMissingTextureBytes);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

	glGenFramebuffers(1, &framebufferName);
	glBindFramebuffer(GL_FRAMEBUFFER, framebufferName);
	glGenTextures(2, fbTextures);
	
	glBindTexture(GL_TEXTURE_2D, fbTextures[0]);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	
	glBindTexture(GL_TEXTURE_2D, fbTextures[1]);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, 128, 128, 0, GL_RED, GL_FLOAT, NULL);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbTextures[0], 0);
	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, fbTextures[1], 0);
	
	// Give water renderer the data texture
	water.setDataTexture(1, fbTextures[1]);
	
	glGenRenderbuffers(1, fbRenderBuffers);
	glBindRenderbuffer(GL_RENDERBUFFER, fbRenderBuffers[0]);
	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 128, 128);
	glFramebufferRenderbuffer(
		GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbRenderBuffers[0]
	);
	
	// Create the skydome

	size_t segments = skydomeSegments, rows = skydomeRows;

    float R = 1.f/(float)(rows-1);
    float S = 1.f/(float)(segments-1);
	std::vector<VertexP3> skydomeVerts;
	skydomeVerts.resize(rows * segments);
    for( size_t r = 0, i = 0; r < rows; ++r) {
        for( size_t s = 0; s < segments; ++s) {
			skydomeVerts[i++].position = glm::vec3(
                        cos(2.f * M_PI * s * S) * cos(M_PI_2 * r * R),
                        sin(2.f * M_PI * s * S) * cos(M_PI_2 * r * R),
                        sin(M_PI_2 * r * R)
                        );
		}
	}
	skyGbuff.uploadVertices(skydomeVerts);
	skyDbuff.addGeometry(&skyGbuff);
	skyDbuff.setFaceType(GL_TRIANGLES);

    glGenBuffers(1, &skydomeIBO);
	std::vector<GLuint> skydomeIndBuff;
	skydomeIndBuff.resize(rows*segments*6);
    for( size_t r = 0, i = 0; r < (rows-1); ++r ) {
        for( size_t s = 0; s < (segments-1); ++s ) {
            skydomeIndBuff[i++] = r * segments + s;
            skydomeIndBuff[i++] = r * segments + (s+1);
            skydomeIndBuff[i++] = (r+1) * segments + (s+1);
            skydomeIndBuff[i++] = r * segments + s;
            skydomeIndBuff[i++] = (r+1) * segments + (s+1);
            skydomeIndBuff[i++] = (r+1) * segments + s;
        }
    }
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, skydomeIBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * skydomeIndBuff.size(), skydomeIndBuff.data(), GL_STATIC_DRAW);

	glBindVertexArray(0);

    glGenBuffers(1, &debugVBO);
    glGenTextures(1, &debugTex);
    glGenVertexArrays(1, &debugVAO);

	particleGeom.uploadVertices<ParticleVert>(
	{
					{ 0.5f, 0.5f, 1.f, 1.f, 1.f, 1.f, 1.f},
					{-0.5f, 0.5f, 0.f, 1.f, 1.f, 1.f, 1.f},
					{ 0.5f,-0.5f, 1.f, 0.f, 1.f, 1.f, 1.f},
					{-0.5f,-0.5f, 0.f, 0.f, 1.f, 1.f, 1.f}
	});
	particleDraw.addGeometry(&particleGeom);
	particleDraw.setFaceType(GL_TRIANGLE_STRIP);

	ssRectGeom.uploadVertices(sspaceRect);
	ssRectDraw.addGeometry(&ssRectGeom);
	ssRectDraw.setFaceType(GL_TRIANGLE_STRIP);

	ssRectProgram = compileProgram(GameShaders::ScreenSpaceRect::VertexShader,
								  GameShaders::ScreenSpaceRect::FragmentShader);

	ssRectTexture = glGetUniformLocation(ssRectProgram, "texture");
	ssRectColour = glGetUniformLocation(ssRectProgram, "colour");
	ssRectSize = glGetUniformLocation(ssRectProgram, "size");
	ssRectOffset = glGetUniformLocation(ssRectProgram, "offset");
	
	const static int cylsegments = 16;
	std::vector<Model::GeometryVertex> cylverts;
	for(int s = 0; s < cylsegments; ++s)
	{
		float theta = (2.f*glm::pi<float>()/cylsegments) * (s+0);
		float gamma = (2.f*glm::pi<float>()/cylsegments) * (s+1);
		glm::vec2 p0( glm::sin(theta), glm::cos(theta) );
		glm::vec2 p1( glm::sin(gamma), glm::cos(gamma) );
		
		p0 *= 0.5f;
		p1 *= 0.5f;
		
		cylverts.push_back({glm::vec3(p0, 2.f), glm::vec3(), glm::vec2(0.45f,0.6f), glm::u8vec4(255, 255, 255, 50)});
		cylverts.push_back({glm::vec3(p0,-1.f), glm::vec3(), glm::vec2(0.45f,0.4f), glm::u8vec4(255, 255, 255, 150)});
		cylverts.push_back({glm::vec3(p1, 2.f), glm::vec3(), glm::vec2(0.55f,0.6f), glm::u8vec4(255, 255, 255, 50)});
		
		cylverts.push_back({glm::vec3(p0,-1.f), glm::vec3(), glm::vec2(0.45f,0.4f), glm::u8vec4(255, 255, 255, 150)});
		cylverts.push_back({glm::vec3(p1,-1.f), glm::vec3(), glm::vec2(0.55f,0.4f), glm::u8vec4(255, 255, 255, 150)});
		cylverts.push_back({glm::vec3(p1, 2.f), glm::vec3(), glm::vec2(0.55f,0.6f), glm::u8vec4(255, 255, 255, 50)});
	}
	cylinderGeometry.uploadVertices<Model::GeometryVertex>(cylverts);
	cylinderBuffer.addGeometry(&cylinderGeometry);
	cylinderBuffer.setFaceType(GL_TRIANGLES);
}
Пример #20
0
void StringVectorListAdapter::drawItem(int item, int x, int y, int w, int h, bool selected) const
{
	ui_draw2d.DrawImage2GridH(theme.buttonImage, x, y, x + w);
	ui_draw2d.DrawTextShadow(theme.uiFont, (*items_)[item].c_str(), x + UI_SPACE , y, 0xFFFFFFFF, ALIGN_LEFT | ALIGN_VCENTER);
}
Пример #21
0
void UIBegin(Thin3DShaderSet *shaderSet) {
	for (int i = 0; i < MAX_POINTERS; i++)
		uistate.hotitem[i] = 0;
	ui_draw2d.Begin(shaderSet);
	ui_draw2d_front.Begin(shaderSet);
}
Пример #22
0
void UIBegin(const GLSLProgram *shader) {
	for (int i = 0; i < MAX_POINTERS; i++)
		uistate.hotitem[i] = 0;
	ui_draw2d.Begin(shader);
	ui_draw2d_front.Begin(shader);
}
Пример #23
0
int UITextureButton(UIContext *ctx, int id, const LayoutManager &layout, float w, float h, Texture *texture, int button_align, uint32_t color, int drop_shadow)	// uses current UI atlas for fetching images.
{
	float x, y;
	layout.GetPos(&w, &h, &x, &y);

	if (button_align & ALIGN_HCENTER) x -= w / 2;
	if (button_align & ALIGN_VCENTER) y -= h / 2;
	if (button_align & ALIGN_RIGHT) x -= w;
	if (button_align & ALIGN_BOTTOMRIGHT) y -= h;

	int txOffset = 0;
	int clicked = 0;
	for (int i = 0; i < MAX_POINTERS; i++) {
		// Check whether the button should be hot, use a generous margin for touch ease
		if (UIRegionHit(i, x, y, w, h, 8)) {
			uistate.hotitem[i] = id;
			if (uistate.activeitem[i] == 0 && uistate.mousedown[i])
				uistate.activeitem[i] = id;
		}

		if (uistate.hotitem[i] == id) {
			if (uistate.activeitem[i] == id) {
				// Button is both 'hot' and 'active'
				txOffset = 2;
			} else {
				// Button is merely 'hot'
			}
		} else {
			// button is not hot, but it may be active
		}

		// If button is hot and active, but mouse button is not
		// down, the user must have clicked the button.
		if (uistate.mousedown[i] == 0 &&
			uistate.hotitem[i] == id &&
			uistate.activeitem[i] == id) {
				clicked = 1;
		}
	}
	if (texture) {
		float tw = texture->Width();
		float th = texture->Height();

		// Adjust position so we don't stretch the image vertically or horizontally.
		// TODO: Add a param to specify fit?  The below assumes it's never too wide.
		float nw = h * tw / th;
		x += (w - nw) / 2.0f;
		w = nw;
	}

	// Render button
	int dropsize = 10;
	if (drop_shadow && texture)
	{
		if (txOffset) {
			dropsize = 3;
			y += txOffset * 2;
		}
		ui_draw2d.DrawImage4Grid(drop_shadow, x - dropsize, y, x+w + dropsize, y+h+dropsize*1.5, 
			blackAlpha(0.5f), 1.0f);
		ui_draw2d.Flush(true);
	}

	if (texture) {
		texture->Bind(0);
	} else {
		ui_draw2d.DrawImage2GridH(theme.buttonImage, x, y, x + w, color);
		ui_draw2d.Flush();

		Texture::Unbind();
	}
	ui_draw2d.DrawTexRect(x, y, x+w, y+h, 0, 0, 1, 1, color);

	ui_draw2d.Flush();
	ctx->RebindTexture();

	uistate.lastwidget = id;
	return clicked;
}
Пример #24
0
void TouchStick::draw(DrawBuffer &db, uint32_t color)
{
	if (bgImageIndex_ != -1)
		db.DrawImage(bgImageIndex_, stick_x_, stick_y_, 1.0f * scale_, color, ALIGN_CENTER);
	db.DrawImage(stickImageIndex_, stick_x_ + stick_delta_x_ * stick_size_ * scale_, stick_y_ + stick_delta_y_ * stick_size_ * scale_, 1.0f * scale_, color, ALIGN_CENTER);
}
Пример #25
0
void UIBegin(Thin3DShaderSet *shaderSet) {
	ui_draw2d.Begin(shaderSet);
	ui_draw2d_front.Begin(shaderSet);
}
Пример #26
0
void UIText(int font, int x, int y, const char *text, uint32_t color, float scale, int align) {
	ui_draw2d.SetFontScale(scale, scale);
	ui_draw2d.DrawTextShadow(font, text, x, y, color, align);
	ui_draw2d.SetFontScale(1.0f, 1.0f);
}
Пример #27
0
void UIFlush() {
	ui_draw2d.Flush();
	ui_draw2d_front.Flush();
}
Пример #28
0
void GameRenderer::renderWorld(GameWorld* world, const ViewCamera &camera, float alpha)
{
	_renderAlpha = alpha;
	_renderWorld = world;

	// Store the input camera,
	_camera = camera;

	setupRender();

	glBindVertexArray( vao );

	float tod = world->getHour() + world->getMinute()/60.f;

	// Requires a float 0-24
	auto weatherID = static_cast<WeatherLoader::WeatherCondition>(world->state->basic.nextWeather * 24);
	auto weather = world->data->weatherLoader.getWeatherData(weatherID, tod);

	glm::vec3 skyTop = weather.skyTopColor;
	glm::vec3 skyBottom = weather.skyBottomColor;
	glm::vec3 ambient = weather.ambientColor;
	glm::vec3 dynamic = weather.directLightColor;

	float theta = (tod/(60.f * 24.f) - 0.5f) * 2 * 3.14159265;
	glm::vec3 sunDirection{
		sin(theta),
		0.0,
		cos(theta),
	};
	sunDirection = glm::normalize(sunDirection);

	_camera.frustum.near = world->state->cameraNear;
	_camera.frustum.far = weather.farClipping;

	auto view = _camera.getView();
	auto proj = _camera.frustum.projection();

	Renderer::SceneUniformData sceneParams {
		proj,
		view,
		glm::vec4{ambient, 0.0f},
		glm::vec4{dynamic, 0.0f},
		glm::vec4(skyBottom, 1.f),
		glm::vec4(camera.position, 0.f),
		weather.fogStart,
		camera.frustum.far
	};

	renderer->setSceneParameters(sceneParams);
	
	renderer->clear(glm::vec4(skyBottom, 1.f));

	_camera.frustum.update(proj * view);
	if (cullOverride)
	{
		cullingCamera.frustum.update(
					cullingCamera.frustum.projection() * cullingCamera.getView());
	}
	
	culled = 0;

	renderer->useProgram(worldProg);

	//===============================================================
	//	Render List Construction
	//---------------------------------------------------------------

	RW_PROFILE_BEGIN("RenderList");

	// This is sequential at the moment, it should be easy to make it
	// run in parallel with a good threading system.
	RenderList renderList;
	// Naive optimisation, assume 10% hitrate
	renderList.reserve(world->allObjects.size() * 0.5f);

	RW_PROFILE_BEGIN("Build");

	ObjectRenderer objectRenderer(_renderWorld,
					  (cullOverride ? cullingCamera : _camera),
					  _renderAlpha,
					  getMissingTexture());

	// World Objects
	for (auto object : world->allObjects) {
		objectRenderer.buildRenderList(object, renderList);
	}
	RW_PROFILE_END();

	renderer->pushDebugGroup("Objects");
	renderer->pushDebugGroup("RenderList");

	// Also parallelizable
	RW_PROFILE_BEGIN("Sort");
	std::sort(renderList.begin(), renderList.end(),
			  [](const Renderer::RenderInstruction& a,
				 const Renderer::RenderInstruction&b) {
					return a.sortKey < b.sortKey;
				});
	RW_PROFILE_END();

	RW_PROFILE_BEGIN("Draw");
	renderer->drawBatched(renderList);
	RW_PROFILE_END();

	renderer->popDebugGroup();
	profObjects = renderer->popDebugGroup();

	RW_PROFILE_END();

	// Render arrows above anything that isn't radar only (or hidden)
	ModelRef& arrowModel = world->data->models["arrow"];
	if( arrowModel && arrowModel->resource )
	{
		auto arrowTex = world->data->textures[{"copblue",""}];
		auto arrowFrame = arrowModel->resource->findFrame( "arrow" );
		for( auto& blip : world->state->radarBlips )
		{
			if( blip.second.display == BlipData::Show )
			{
				glm::mat4 model;

				if( blip.second.target > 0 )
				{
					// TODO restore arrows
					/*auto& pool = world->getTypeObjectPool(blip.second.target);
					auto object = pool.find(blip.second.target);
					if( object )
					{
						model = object->getTimeAdjustedTransform( _renderAlpha );
					}*/
				}
				else
				{
					model = glm::translate( model, blip.second.coord );
				}

				float a = world->getGameTime() * glm::pi<float>();
				model = glm::translate( model, glm::vec3(0.f, 0.f, 2.5f + glm::sin( a ) * 0.5f) );
				model = glm::rotate( model, a, glm::vec3(0.f, 0.f, 1.f) );
				model = glm::scale( model, glm::vec3(1.5f, 1.5f, 1.5f) );

				Renderer::DrawParameters dp;
				dp.textures = {arrowTex->getName()};
				dp.ambient = 1.f;
				dp.colour = glm::u8vec4(255, 255, 255, 255);

				auto geom = arrowModel->resource->geometries[arrowFrame->getGeometries()[0]];
				Model::SubGeometry& sg = geom->subgeom[0];

				dp.start = sg.start;
				dp.count = sg.numIndices;
				dp.diffuse = 1.f;

				renderer->draw( model, &geom->dbuff, dp );
			}
		}
	}

	// Draw goal indicators
	glDepthMask(GL_FALSE);
	renderer->useProgram( particleProg );
	for(auto& i : world->getAreaIndicators())
	{
		renderAreaIndicator( &i );
	}
	glDepthMask(GL_TRUE);

	renderer->pushDebugGroup("Water");

	water.render(this, world);

	profWater = renderer->popDebugGroup();

	renderer->pushDebugGroup("Sky");

	glBindVertexArray( vao );

	Renderer::DrawParameters dp;
	dp.start = 0;
	dp.count = skydomeSegments * skydomeRows * 6;

	renderer->useProgram(skyProg);
	renderer->setUniform(skyProg, "TopColor", glm::vec4(skyTop, 1.f));
	renderer->setUniform(skyProg, "BottomColor", glm::vec4(skyBottom, 1.f));

	renderer->draw(glm::mat4(), &skyDbuff, dp);

	profSky = renderer->popDebugGroup();

	renderer->pushDebugGroup("Effects");
	renderEffects(world);
	profEffects = renderer->popDebugGroup();

	glDisable(GL_DEPTH_TEST);

	GLuint splashTexName = 0;
	auto fc = world->state->fadeColour;
	if((fc.r + fc.g + fc.b) == 0 && world->state->currentSplash.size() > 0) {
		auto splash = world->data->findTexture(world->state->currentSplash);
		if ( splash )
		{
			splashTexName = splash->getName();
		}
	}

	if( (world->state->isCinematic || world->state->currentCutscene ) && splashTexName != 0 ) {
		renderLetterbox();
	}

	float fadeTimer = world->getGameTime() - world->state->fadeStart;
	if( fadeTimer < world->state->fadeTime || !world->state->fadeOut ) {
		glUseProgram(ssRectProgram);
		glUniform2f(ssRectOffset, 0.f, 0.f);
		glUniform2f(ssRectSize, 1.f, 1.f);

		glUniform1i(ssRectTexture, 0);

		if(splashTexName != 0) {
			glBindTexture(GL_TEXTURE_2D, splashTexName);
			fc = glm::u16vec3(0, 0, 0);
		}
		else {
			glBindTexture(GL_TEXTURE_2D, 0);
		}

		float fadeFrac = 0.f;
		if( world->state->fadeTime > 0.f ) {
			fadeFrac = std::min(fadeTimer / world->state->fadeTime, 1.f);
		}

		float a = world->state->fadeOut ? 1.f - fadeFrac : fadeFrac;

		glm::vec4 fadeNormed(fc.r / 255.f, fc.g/ 255.f, fc.b/ 255.f, a);

		glUniform4fv(ssRectColour, 1, glm::value_ptr(fadeNormed));

		glBindVertexArray( ssRectDraw.getVAOName() );
		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	}

	if( (world->state->isCinematic || world->state->currentCutscene ) && splashTexName == 0 ) {
		renderLetterbox();
	}

	renderPostProcess();

	glUseProgram(0);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	glBindVertexArray( 0 );
}