예제 #1
0
	bool OpenGLRenderVertexBuffer::initialize( ServiceProviderInterface * _serviceProvider, uint32_t _vertexNum, bool _dynamic )
	{ 
		m_serviceProvider = _serviceProvider;

		m_memory = Helper::allocateMemory<RenderVertex2D>( _vertexNum );
		m_vertexNum = _vertexNum;

		m_usage = GL_STATIC_DRAW;

		if( _dynamic == true )
		{
			m_usage = GL_DYNAMIC_DRAW;
		}

		GLuint bufId = 0;
		GLCALL( m_serviceProvider, glGenBuffers, (1, &bufId) );

		GLCALL( m_serviceProvider, glBindBuffer, (GL_ARRAY_BUFFER, bufId) );
		GLCALL( m_serviceProvider, glBufferData, (GL_ARRAY_BUFFER, m_vertexNum * sizeof( RenderVertex2D ), nullptr, m_usage) );
		GLCALL( m_serviceProvider, glBindBuffer, (GL_ARRAY_BUFFER, 0) );

		m_id = bufId;

		return true;
	}
예제 #2
0
void OSystem_Android::clearScreen(FixupType type, byte count) {
	assert(count > 0);

	bool sm = _show_mouse;
	_show_mouse = false;

	GLCALL(glDisable(GL_SCISSOR_TEST));

	for (byte i = 0; i < count; ++i) {
		// clear screen
		GLCALL(glClearColorx(0, 0, 0, 1 << 16));
		GLCALL(glClear(GL_COLOR_BUFFER_BIT));

		switch (type) {
		case kClear:
			break;

		case kClearSwap:
			JNI::swapBuffers();
			break;

		case kClearUpdate:
			_force_redraw = true;
			updateScreen();
			break;
		}
	}

	if (!_show_overlay)
		GLCALL(glEnable(GL_SCISSOR_TEST));

	_show_mouse = sm;
	_force_redraw = true;
}
예제 #3
0
void RenderScene::RenderScene(RenderLists* renderLists, Camera* camera) {

#ifdef PLATFORM_IOS
	GLCALL(glGetIntegerv, GL_FRAMEBUFFER_BINDING, &g_default_fbo);
#endif

	GLCALL(glBindFramebuffer, GL_FRAMEBUFFER, SCREEN_FRAME_BUFFER /* default window framebuffer */);
	renderLists->Draw(camera, false, DISTANCE_FROM_CAMERA_COMPARE_TYPE_ortho_z);
}
예제 #4
0
void Texture::MakeActive(unsigned int slot){
	if(slot < GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS){
		boundTo = GL_TEXTURE0 + slot;
		GLCALL(glActiveTexture(boundTo));
		GLCALL(glBindTexture(type, buffer));
	}
	
	
}
예제 #5
0
void OpenGLGraphicsManager::updateScreen() {
	if (!_gameScreen) {
		return;
	}

	// Clear the screen buffer
	GLCALL(glClear(GL_COLOR_BUFFER_BIT));

	const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_displayHeight / _gameScreen->getHeight();

	// First step: Draw the (virtual) game screen.
	_gameScreen->draw(_displayX, _displayY + shakeOffset, _displayWidth, _displayHeight);

	// Second step: Draw the overlay if visible.
	if (_overlayVisible) {
		_overlay->draw(0, 0, _outputScreenWidth, _outputScreenHeight);
	}

	// Third step: Draw the cursor if visible.
	if (_cursorVisible && _cursor) {
		// Adjust game screen shake position, but only when the overlay is not
		// visible.
		const GLfloat cursorOffset = _overlayVisible ? 0 : shakeOffset;

		_cursor->draw(_cursorX - _cursorHotspotXScaled, _cursorY - _cursorHotspotYScaled + cursorOffset,
		              _cursorWidthScaled, _cursorHeightScaled);
	}

#ifdef USE_OSD
	// Fourth step: Draw the OSD.
	if (_osdAlpha > 0) {
		Common::StackLock lock(_osdMutex);

		// Update alpha value.
		const int diff = g_system->getMillis(false) - _osdFadeStartTime;
		if (diff > 0) {
			if (diff >= kOSDFadeOutDuration) {
				// Back to full transparency.
				_osdAlpha = 0;
			} else {
				// Do a fade out.
				_osdAlpha = kOSDInitialAlpha - diff * kOSDInitialAlpha / kOSDFadeOutDuration;
			}
		}

		// Set the OSD transparency.
		GLCALL(glColor4f(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f));

		// Draw the OSD texture.
		_osd->draw(0, 0, _outputScreenWidth, _outputScreenHeight);

		// Reset color.
		GLCALL(glColor4f(1.0f, 1.0f, 1.0f, 1.0f));
	}
#endif
}
void GraphicsComponent::Render(int){
	EntitySpecificShaderSetup();
	GLCALL(glBindVertexArray(vao_ID));
	if(!usesElements){
		GLCALL(glDrawArrays(primMode, 0, numElements));
	}
	else{
		GLCALL(glDrawElements(primMode, numElements, GL_UNSIGNED_INT, (void*)0));
	}
	GLCALL(glBindVertexArray(0));
}
예제 #7
0
	bool OpenGLRenderVertexBuffer::unlock()
	{
		GLCALL( m_serviceProvider, glBindBuffer, (GL_ARRAY_BUFFER, m_id) );
		GLCALL( m_serviceProvider, glBufferSubData, (GL_ARRAY_BUFFER, m_lockOffset * sizeof( RenderVertex2D ), m_lockCount * sizeof( RenderVertex2D ), m_lockMemory) );
		GLCALL( m_serviceProvider, glBindBuffer, (GL_ARRAY_BUFFER, 0) );

		m_lockOffset = 0;
		m_lockCount = 0;
		m_lockMemory = nullptr;
		m_lockFlags = BLF_LOCK_NONE;

		return true;
	}
예제 #8
0
파일: drv_api.c 프로젝트: dborca/sage
int
sage_bind (sageContext *ctx, void *win, int width, int height)
{
    if (hardware < 0) {
	return -1;
    }

    if (ctx == NULL || win == NULL) {
	if (current != NULL) {
	    /* unbind */
	    current = NULL;
	}
	return 0;
    }
    if (ctx == current) {
	if (win == current->drawable) {
	    /* nop */
	    return 0;
	}
	/* rebind */
    }

    ctx->drawable = win;
    current = ctx;

    GLCALL(Viewport)(0, 0, width, height);

    return 0;
}
예제 #9
0
파일: gfx.cpp 프로젝트: Akz-/residual
void OSystem_Android::initViewport() {
	LOGD("initializing viewport");

	assert(JNI::haveSurface());

	GLCALL(glDisable(GL_CULL_FACE));
	GLCALL(glDisable(GL_DEPTH_TEST));

	GLCALL(glEnable(GL_BLEND));
	GLCALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));

	GLCALL(glViewport(0, 0, _egl_surface_width, _egl_surface_height));
	LOGD("viewport size: %dx%d", _egl_surface_width, _egl_surface_height);

	clearFocusRectangle();
}
예제 #10
0
	MarmaladeRenderProgram::~MarmaladeRenderProgram()
	{
		if( m_program != 0 )
		{
			GLCALL( m_serviceProvider, glDeleteProgram, (m_program) );
			m_program = 0;
		}
	}
예제 #11
0
	OpenGLRenderVertexBuffer::~OpenGLRenderVertexBuffer()
	{
		if( m_id != 0 )
		{
			GLCALL( m_serviceProvider, glDeleteBuffers, (1, &m_id) );
		}

		Helper::freeMemory( m_memory );
	}
예제 #12
0
void OpenGLGraphicsManager::saveScreenshot(const Common::String &filename) const {
	const uint width  = _outputScreenWidth;
	const uint height = _outputScreenHeight;

	// A line of a BMP image must have a size divisible by 4.
	// We calculate the padding bytes needed here.
	// Since we use a 3 byte per pixel mode, we can use width % 4 here, since
	// it is equal to 4 - (width * 3) % 4. (4 - (width * Bpp) % 4, is the
	// usual way of computing the padding bytes required).
	const uint linePaddingSize = width % 4;
	const uint lineSize        = width * 3 + linePaddingSize;

	// Allocate memory for screenshot
	uint8 *pixels = new uint8[lineSize * height];

	// Get pixel data from OpenGL buffer
	GLCALL(glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels));

	// BMP stores as BGR. Since we can't assume that GL_BGR is supported we
	// will swap the components from the RGB we read to BGR on our own.
	for (uint y = height; y-- > 0;) {
		uint8 *line = pixels + y * lineSize;

		for (uint x = width; x > 0; --x, line += 3) {
			SWAP(line[0], line[2]);
		}
	}

	// Open file
	Common::DumpFile out;
	out.open(filename);

	// Write BMP header
	out.writeByte('B');
	out.writeByte('M');
	out.writeUint32LE(height * lineSize + 54);
	out.writeUint32LE(0);
	out.writeUint32LE(54);
	out.writeUint32LE(40);
	out.writeUint32LE(width);
	out.writeUint32LE(height);
	out.writeUint16LE(1);
	out.writeUint16LE(24);
	out.writeUint32LE(0);
	out.writeUint32LE(0);
	out.writeUint32LE(0);
	out.writeUint32LE(0);
	out.writeUint32LE(0);
	out.writeUint32LE(0);

	// Write pixel data to BMP
	out.write(pixels, lineSize * height);

	// Free allocated memory
	delete[] pixels;
}
예제 #13
0
void Texture::SetStorage(int width, int height, int depth, int levels){
	switch(type){
		case TT_GL_TEXTURE_1D:
			GLCALL(glTexStorage1D(type, levels, format, width));
			break;
		case TT_GL_TEXTURE_2D:
		case TT_GL_TEXTURE_1D_ARRAY:
		case TT_GL_TEXTURE_RECTANGLE:
		case TT_GL_TEXTURE_CUBE_MAP:
			GLCALL(glTexStorage2D(type, levels, format, width, height));
			break;

		case TT_GL_TEXTURE_3D:
		case TT_GL_TEXTURE_2D_ARRAY:
		case TT_GL_TEXTURE_CUBE_MAP_ARRAY:
			GLCALL(glTexStorage3D(type, levels, format, width, height, depth));
			break;
	}
}
void GraphicsContext::RenderPass(int pass, ShaderProgram* defaultShader, Camera* cam){

	GLCALL(glViewport(0,0, windowWidth, windowHeight));
	//Set RenderTarget
	GLCALL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
	//Need a constant buffer for Camera shtuff
	if(cam != NULL)
		cam->SetCurrent();
	if(defaultShader != NULL){
		defaultShader->Bind();
		defaultShaderForPass = defaultShader;
	}
	
	for( auto it = entitiesPerPass[pass].begin(); it != entitiesPerPass[pass].end(); it++){
		(*it)->Render(pass);
	}
	
	if(pass == numPasses-1)
		SwapBuffers(hdc);
}
예제 #15
0
파일: gfx.cpp 프로젝트: Akz-/residual
void OSystem_Android::showOverlay() {
	ENTER();

	_show_overlay = true;
	_force_redraw = true;

	updateEventScale();

	warpMouse(_overlay_texture->width() / 2, _overlay_texture->height() / 2);

	GLCALL(glDisable(GL_SCISSOR_TEST));
}
예제 #16
0
void WaterRenderer::Draw() {
	ShaderSet* currentShaderSet = FRAMEWORK->GetOpenGLWrapper()->GetCurrentShaderSet();
	if (currentShaderSet->HasHandle(SHADER_VARIABLE_VARIABLENAME_scrolling_uv_offset)) {
		GLint scrolling_uv_offset_handle = currentShaderSet->GetHandle(SHADER_VARIABLE_VARIABLENAME_scrolling_uv_offset);
		GLCALL(glUniform1f, scrolling_uv_offset_handle, this->scrollingUVsOffset);
	}

	if (this->secondaryTexture) {
		this->secondaryTexture->Draw(2);
	}

	MeshRenderer::Draw();

}
예제 #17
0
파일: gfx.cpp 프로젝트: Akz-/residual
void OSystem_Android::hideOverlay() {
	ENTER();

	_show_overlay = false;

	updateEventScale();

	warpMouse(_game_texture->width() / 2, _game_texture->height() / 2);

	// double buffered, flip twice
	clearScreen(kClearUpdate, 2);

	GLCALL(glEnable(GL_SCISSOR_TEST));
}
예제 #18
0
	void MarmaladeRenderProgram::bindTexture( uint32_t _index ) const
	{	
		if( _index >= m_samplerCount )
		{
			LOGGER_ERROR( m_serviceProvider )("MarmaladeProgram::bindTexture %s invalid support sampler count %d max %d"
				, m_name.c_str()
				, _index
				, m_samplerCount
				);

			return;
		}

		int location = m_samplerLocation[_index];

		GLCALL( m_serviceProvider, glUniform1i, (location, _index) );
	}
예제 #19
0
void Texture::GiveData(TexData &toGive){
	GLCALL(glBindTexture(type, buffer));
	switch(type){
	case TT_GL_TEXTURE_1D:
		GLCALL(glTexImage1D(type, toGive.level, format, toGive.width, 0, toGive.format, toGive.type, toGive.data));
		break;
	case TT_GL_TEXTURE_2D:
	case TT_GL_TEXTURE_1D_ARRAY:
	case TT_GL_TEXTURE_RECTANGLE:
		GLCALL(glTexImage2D(type, toGive.level, format, toGive.width, toGive.height, 0, toGive.format, toGive.type, toGive.data));
		break;
	case TT_GL_TEXTURE_CUBE_MAP:
		GLCALL(glTexImage2D(toGive.target, toGive.level, format, toGive.width, toGive.height, 0, toGive.format, toGive.type, toGive.data));
		break;
	case TT_GL_TEXTURE_3D:
	case TT_GL_TEXTURE_2D_ARRAY:
	case TT_GL_TEXTURE_CUBE_MAP_ARRAY:
		GLCALL(glTexImage3D(type, toGive.level, format, toGive.width, toGive.height, toGive.depth, 0, toGive.format, toGive.type, toGive.data));
		break;
	}
	GLCALL(glBindTexture(type, 0));
}
예제 #20
0
void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &defaultFormat, const Graphics::PixelFormat &defaultFormatAlpha) {
	// Initialize all extensions.
	initializeGLExtensions();

	// Disable 3D properties.
	GLCALL(glDisable(GL_CULL_FACE));
	GLCALL(glDisable(GL_DEPTH_TEST));
	GLCALL(glDisable(GL_LIGHTING));
	GLCALL(glDisable(GL_FOG));
	GLCALL(glDisable(GL_DITHER));
	GLCALL(glShadeModel(GL_FLAT));
	GLCALL(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST));

	// Default to black as clear color.
	GLCALL(glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
	GLCALL(glColor4f(1.0f, 1.0f, 1.0f, 1.0f));

	// Setup alpha blend (for overlay and cursor).
	GLCALL(glEnable(GL_BLEND));
	GLCALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));

	// Enable rendering with vertex and coord arrays.
	GLCALL(glEnableClientState(GL_VERTEX_ARRAY));
	GLCALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));

	GLCALL(glEnable(GL_TEXTURE_2D));

	// We use a "pack" alignment (when reading from textures) to 4 here,
	// since the only place where we really use it is the BMP screenshot
	// code and that requires the same alignment too.
	GLCALL(glPixelStorei(GL_PACK_ALIGNMENT, 4));

	// Query information needed by textures.
	Texture::queryTextureInformation();

	// Refresh the output screen dimensions if some are set up.
	if (_outputScreenWidth != 0 && _outputScreenHeight != 0) {
		setActualScreenSize(_outputScreenWidth, _outputScreenHeight);
	}

	// TODO: Should we try to convert textures into one of those formats if
	// possible? For example, when _gameScreen is CLUT8 we might want to use
	// defaultFormat now.
	_defaultFormat = defaultFormat;
	_defaultFormatAlpha = defaultFormatAlpha;

	if (_gameScreen) {
		_gameScreen->recreateInternalTexture();
	}

	if (_overlay) {
		_overlay->recreateInternalTexture();
	}

	if (_cursor) {
		_cursor->recreateInternalTexture();
	}

#ifdef USE_OSD
	if (_osd) {
		_osd->recreateInternalTexture();
	}
#endif
}
예제 #21
0
파일: gfx.cpp 프로젝트: Akz-/residual
void OSystem_Android::updateScreen() {
	//ENTER();

	GLTHREADCHECK;

	if (!JNI::haveSurface())
		return;

		if (_game_pbuf) {
			int pitch = _game_texture->width() * _game_texture->getPixelFormat().bytesPerPixel;
			_game_texture->updateBuffer(0, 0, _game_texture->width(), _game_texture->height(),
					_game_pbuf.getRawBuffer(), pitch);
		}

		if (!_force_redraw &&
				!_game_texture->dirty() &&
				!_overlay_texture->dirty() &&
				!_mouse_texture->dirty())
			return;

		_force_redraw = false;

		if (_frame_buffer) {
			_frame_buffer->detach();
			glViewport(0,0, _egl_surface_width, _egl_surface_height);
		}

		// clear pointer leftovers in dead areas
		clearScreen(kClear);

	// TODO this doesnt work on those sucky drivers, do it differently
	//	if (_show_overlay)
	//		GLCALL(glColor4ub(0x9f, 0x9f, 0x9f, 0x9f));

		if (true || _focus_rect.isEmpty()) {
			_game_texture->drawTextureRect();
			drawVirtControls();
		} else {
// TODO what is this and do we have engines using it?
#if 0
			GLCALL(glPushMatrix());

			GLCALL(glScalex(xdiv(_egl_surface_width, _focus_rect.width()),
							xdiv(_egl_surface_height, _focus_rect.height()),
							1 << 16));
			GLCALL(glTranslatex(-_focus_rect.left << 16,
								-_focus_rect.top << 16, 0));
			GLCALL(glScalex(xdiv(_game_texture->width(), _egl_surface_width),
							xdiv(_game_texture->height(), _egl_surface_height),
							1 << 16));

			_game_texture->drawTextureRect();

			GLCALL(glPopMatrix());
#endif
		}

		int cs = _mouse_targetscale;

		if (_show_overlay) {
	// TODO see above
	//		GLCALL(glColor4ub(0xff, 0xff, 0xff, 0xff));

			// ugly, but the modern theme sets a wacko factor, only god knows why
			cs = 1;

			GLCALL(_overlay_texture->drawTextureRect());
		}

		if (_show_mouse && !_mouse_texture->isEmpty()) {
			const Common::Point &mouse = getEventManager()->getMousePos();
			if (_show_overlay) {
				_mouse_texture->drawTexture(mouse.x * cs, mouse.y * cs, _mouse_texture->width(), _mouse_texture->height());
			}
// TODO: Port the non-overlay code as well?
#if 0
			if (_show_overlay) {
			} else {
				const Common::Rect &r = _game_texture->getDrawRect();

				GLCALL(glTranslatex(r.left << 16,
									r.top << 16,
									0));
				GLCALL(glScalex(xdiv(r.width(), _game_texture->width()),
								xdiv(r.height(), _game_texture->height()),
								1 << 16));
			}

			GLCALL(glTranslatex((-_mouse_hotspot.x * cs) << 16,
								(-_mouse_hotspot.y * cs) << 16,
								0));

#endif
	}

	if (!JNI::swapBuffers())
		LOGW("swapBuffers failed: 0x%x", glGetError());

	if (_frame_buffer)
		_frame_buffer->attach();
}
예제 #22
0
void RenderScene::SetupStuff() {

    GLCALL(glEnable, GL_DEPTH_TEST);
	
#ifdef PLATFORM_IOS
	GLCALL(glGetIntegerv, GL_FRAMEBUFFER_BINDING, &g_default_fbo);
#endif

	// Create a frame buffer object:
	GLCALL(glGenFramebuffers, 1, &g_depth_fbo_id);
	GLCALL(glBindFramebuffer, GL_FRAMEBUFFER, g_depth_fbo_id);
	
	// Create a render buffer
    GLCALL(glGenRenderbuffers, 1, &renderBuffer);
    GLCALL(glBindRenderbuffer, GL_RENDERBUFFER, renderBuffer);

    unsigned int depthMap_width, depthMap_height;
    ENGINE->GetShadowMap()->GetDepthMapResolution(depthMap_width, depthMap_height);

	// Create a depth texture:
    GLCALL(glGenTextures, 1, &ENGINE->GetShadowMap()->depthTexture);
	GLCALL(glActiveTexture, GL_TEXTURE2);
    GLCALL(glBindTexture, GL_TEXTURE_2D, ENGINE->GetShadowMap()->depthTexture);
    GLCALL(glTexImage2D, GL_TEXTURE_2D, 0, GL_RGBA, depthMap_width, depthMap_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    //
    GLCALL(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    GLCALL(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    GLCALL(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     GL_CLAMP_TO_EDGE);
    GLCALL(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     GL_CLAMP_TO_EDGE);

	GLCALL(glFramebufferTexture2D, GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ENGINE->GetShadowMap()->depthTexture, 0);
	
	// Allocate 16-bit depth buffer
	GLCALL(glRenderbufferStorage, GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, depthMap_width, depthMap_height);
	
	// Attach the render buffer as depth buffer - will be ignored
	GLCALL(glFramebufferRenderbuffer, GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffer);

	if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {	// GLCALL
		ASSERT(0, "Framebuffer OK");
	}
	
	
#if MULTISAMPLING_ENABLED
	//Generate our MSAA Frame and Render buffers
	glGenFramebuffers(1, &msaaFramebuffer);
	glGenRenderbuffers(1, &msaaRenderBuffer);
	
	//Bind our MSAA buffers
	glBindFramebuffer(GL_FRAMEBUFFER, msaaFramebuffer);
	glBindRenderbuffer(GL_RENDERBUFFER, msaaRenderBuffer);
	
	unsigned int numSamples = 4;
	
	// Generate the msaaDepthBuffer.
	// numSamples will be the number of pixels that the MSAA buffer will use in order to make one pixel on the render buffer.
	glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER, numSamples, GL_RGB5_A1, FRAMEWORK->GetDeviceProperties()->GetWidthPixels(), FRAMEWORK->GetDeviceProperties()->GetHeightPixels());
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, msaaRenderBuffer);
	glGenRenderbuffers(1, &msaaDepthBuffer);
	
	//Bind the msaa depth buffer.
	glBindRenderbuffer(GL_RENDERBUFFER, msaaDepthBuffer);
	glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER, numSamples, GL_DEPTH_COMPONENT16, FRAMEWORK->GetDeviceProperties()->GetWidthPixels() , FRAMEWORK->GetDeviceProperties()->GetHeightPixels());
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, msaaDepthBuffer);
#endif
}
예제 #23
0
void OSystem_Android::updateScreen() {
	//ENTER();

	GLTHREADCHECK;

	if (!JNI::haveSurface())
		return;

	if (!_force_redraw &&
			!_game_texture->dirty() &&
			!_overlay_texture->dirty() &&
			!_mouse_texture->dirty())
		return;

	_force_redraw = false;

	// clear pointer leftovers in dead areas
	// also, HTC's GLES drivers are made of fail and don't preserve the buffer
	// ( http://www.khronos.org/registry/egl/specs/EGLTechNote0001.html )
	if ((_show_overlay || _htc_fail) && !_fullscreen)
		clearScreen(kClear);

	GLCALL(glPushMatrix());

	if (_shake_offset != 0 ||
			(!_focus_rect.isEmpty() &&
			!Common::Rect(_game_texture->width(),
							_game_texture->height()).contains(_focus_rect))) {
		// These are the only cases where _game_texture doesn't
		// cover the entire screen.
		clearScreen(kClear);

		// Move everything up by _shake_offset (game) pixels
		GLCALL(glTranslatex(0, -_shake_offset << 16, 0));
	}

// TODO this doesn't work on those sucky drivers, do it differently
//	if (_show_overlay)
//		GLCALL(glColor4ub(0x9f, 0x9f, 0x9f, 0x9f));

	if (_focus_rect.isEmpty()) {
		_game_texture->drawTextureRect();
	} else {
		GLCALL(glPushMatrix());

		GLCALL(glScalex(xdiv(_egl_surface_width, _focus_rect.width()),
						xdiv(_egl_surface_height, _focus_rect.height()),
						1 << 16));
		GLCALL(glTranslatex(-_focus_rect.left << 16,
							-_focus_rect.top << 16, 0));
		GLCALL(glScalex(xdiv(_game_texture->width(), _egl_surface_width),
						xdiv(_game_texture->height(), _egl_surface_height),
						1 << 16));

		_game_texture->drawTextureRect();

		GLCALL(glPopMatrix());
	}

	int cs = _mouse_targetscale;

	if (_show_overlay) {
// TODO see above
//		GLCALL(glColor4ub(0xff, 0xff, 0xff, 0xff));

		// ugly, but the modern theme sets a wacko factor, only god knows why
		cs = 1;

		GLCALL(_overlay_texture->drawTextureRect());
	}

	if (_show_mouse && !_mouse_texture->isEmpty()) {
		GLCALL(glPushMatrix());

		const Common::Point &mouse = getEventManager()->getMousePos();

		// Scale up ScummVM -> OpenGL (pixel) coordinates
		if (_show_overlay) {
			GLCALL(glScalex(xdiv(_egl_surface_width,
									_overlay_texture->width()),
							xdiv(_egl_surface_height,
									_overlay_texture->height()),
							1 << 16));
		} else {
			const Common::Rect &r = _game_texture->getDrawRect();

			GLCALL(glTranslatex(r.left << 16,
								r.top << 16,
								0));
			GLCALL(glScalex(xdiv(r.width(), _game_texture->width()),
							xdiv(r.height(), _game_texture->height()),
							1 << 16));
		}

		GLCALL(glTranslatex((-_mouse_hotspot.x * cs) << 16,
							(-_mouse_hotspot.y * cs) << 16,
							0));

		// Note the extra half texel to position the mouse in
		// the middle of the x,y square:
		GLCALL(glTranslatex((mouse.x << 16) | 1 << 15,
							(mouse.y << 16) | 1 << 15, 0));

		GLCALL(glScalex(cs << 16, cs << 16, 1 << 16));

		_mouse_texture->drawTextureOrigin();

		GLCALL(glPopMatrix());
	}

	GLCALL(glPopMatrix());

	if (!JNI::swapBuffers())
		LOGW("swapBuffers failed: 0x%x", glGetError());
}
예제 #24
0
void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
	_outputScreenWidth = width;
	_outputScreenHeight = height;

	// Setup coordinates system.
	GLCALL(glViewport(0, 0, _outputScreenWidth, _outputScreenHeight));

	GLCALL(glMatrixMode(GL_PROJECTION));
	GLCALL(glLoadIdentity());
#ifdef USE_GLES
	GLCALL(glOrthof(0, _outputScreenWidth, _outputScreenHeight, 0, -1, 1));
#else
	GLCALL(glOrtho(0, _outputScreenWidth, _outputScreenHeight, 0, -1, 1));
#endif
	GLCALL(glMatrixMode(GL_MODELVIEW));
	GLCALL(glLoadIdentity());

	uint overlayWidth = width;
	uint overlayHeight = height;

	// WORKAROUND: We can only support surfaces up to the maximum supported
	// texture size. Thus, in case we encounter a physical size bigger than
	// this maximum texture size we will simply use an overlay as big as
	// possible and then scale it to the physical display size. This sounds
	// bad but actually all recent chips should support full HD resolution
	// anyway. Thus, it should not be a real issue for modern hardware.
	if (   overlayWidth  > (uint)Texture::getMaximumTextureSize()
	    || overlayHeight > (uint)Texture::getMaximumTextureSize()) {
		const frac_t outputAspect = intToFrac(_outputScreenWidth) / _outputScreenHeight;

		if (outputAspect > (frac_t)FRAC_ONE) {
			overlayWidth  = Texture::getMaximumTextureSize();
			overlayHeight = intToFrac(overlayWidth) / outputAspect;
		} else {
			overlayHeight = Texture::getMaximumTextureSize();
			overlayWidth  = fracToInt(overlayHeight * outputAspect);
		}
	}

	// HACK: We limit the minimal overlay size to 256x200, which is the
	// minimum of the dimensions of the two resolutions 256x240 (NES) and
	// 320x200 (many DOS games use this). This hopefully assure that our
	// GUI has working layouts.
	overlayWidth = MAX<uint>(overlayWidth, 256);
	overlayHeight = MAX<uint>(overlayHeight, 200);

	if (!_overlay || _overlay->getFormat() != _defaultFormatAlpha) {
		delete _overlay;
		_overlay = nullptr;

		_overlay = createTexture(_defaultFormatAlpha);
		assert(_overlay);
		// We always filter the overlay with GL_LINEAR. This assures it's
		// readable in case it needs to be scaled and does not affect it
		// otherwise.
		_overlay->enableLinearFiltering(true);
	}
	_overlay->allocate(overlayWidth, overlayHeight);
	_overlay->fill(0);

#ifdef USE_OSD
	if (!_osd || _osd->getFormat() != _defaultFormatAlpha) {
		delete _osd;
		_osd = nullptr;

		_osd = createTexture(_defaultFormatAlpha);
		assert(_osd);
		// We always filter the osd with GL_LINEAR. This assures it's
		// readable in case it needs to be scaled and does not affect it
		// otherwise.
		_osd->enableLinearFiltering(true);
	}
	_osd->allocate(_overlay->getWidth(), _overlay->getHeight());
	_osd->fill(0);
#endif

	// Re-setup the scaling for the screen and cursor
	recalculateDisplayArea();
	recalculateCursorScaling();

	// Something changed, so update the screen change ID.
	++_screenChangeID;
}
예제 #25
0
void OSystem_Android::initViewport() {
	LOGD("initializing viewport");

	assert(JNI::haveSurface());

	// Turn off anything that looks like 3D ;)
	GLCALL(glDisable(GL_CULL_FACE));
	GLCALL(glDisable(GL_DEPTH_TEST));
	GLCALL(glDisable(GL_LIGHTING));
	GLCALL(glDisable(GL_FOG));
	GLCALL(glDisable(GL_DITHER));

	GLCALL(glShadeModel(GL_FLAT));
	GLCALL(glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST));

	GLCALL(glEnable(GL_BLEND));
	GLCALL(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));

	GLCALL(glEnableClientState(GL_VERTEX_ARRAY));
	GLCALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));

	GLCALL(glEnable(GL_TEXTURE_2D));

	GLCALL(glViewport(0, 0, _egl_surface_width, _egl_surface_height));

	GLCALL(glMatrixMode(GL_PROJECTION));
	GLCALL(glLoadIdentity());
	GLCALL(glOrthof(0, _egl_surface_width, _egl_surface_height, 0, -1, 1));
	GLCALL(glMatrixMode(GL_MODELVIEW));
	GLCALL(glLoadIdentity());

	clearFocusRectangle();
}
예제 #26
0
	bool MarmaladeRenderProgram::initialize( const ConstString & _name, const MarmaladeRenderVertexShaderPtr & _vertexShader, const MarmaladeRenderFragmentShaderPtr & _fragmentShader, uint32_t _samplerCount )
	{
		m_name = _name;
		m_samplerCount = _samplerCount;

		if( m_samplerCount > MENGE_MAX_TEXTURE_STAGES )
		{
			LOGGER_ERROR( m_serviceProvider )("MarmaladeProgram::initialize %s don't support sampler count %d max %d"
				, _name.c_str()
				, m_samplerCount
				, MENGE_MAX_TEXTURE_STAGES
				);

			return false;
		}

		GLuint program;
		GLCALLR( m_serviceProvider, program, glCreateProgram, () );

		if( program == 0 )
		{
			LOGGER_ERROR( m_serviceProvider )("MarmaladeProgram::initialize %s invalid create program"
				, _name.c_str()
				);

			return false;
		}

		if( _vertexShader != nullptr )
		{
			m_vertexShader = _vertexShader;

			m_vertexShader->attach( program );
		}

		if( _fragmentShader != nullptr )
		{
			m_fragmentShader = _fragmentShader;

			m_fragmentShader->attach( program );
		}
		
		GLCALL( m_serviceProvider, glBindAttribLocation, ( program, VERTEX_POSITION_ARRAY, "inVert" ) );
		GLCALL( m_serviceProvider, glBindAttribLocation, ( program, VERTEX_COLOR_ARRAY, "inCol" ) );

		for( uint32_t i = 0; i != MENGINE_RENDER_VERTEX_UV_COUNT; ++i )
		{
			char attrib[16];
			sprintf( attrib, "inUV%d", i );
		
			GLCALL( m_serviceProvider, glBindAttribLocation, (program, VERTEX_UV0_ARRAY + i, attrib) );
		}

		GLCALL( m_serviceProvider, glLinkProgram, ( program ) );

		GLint linked;
		GLCALL( m_serviceProvider, glGetProgramiv, ( program, GL_LINK_STATUS, &linked ) );

		if( linked == GL_FALSE )
		{
			GLchar errorLog[1024] = {0};
			GLCALL( m_serviceProvider, glGetProgramInfoLog, ( program, 1023, NULL, errorLog ) );

			LOGGER_ERROR( m_serviceProvider )("MarmaladeProgram::shaderProgram - shader linking error '%s'"
				, errorLog
				);

			return false;
		}
				
		int transformLocation;
		GLCALLR( m_serviceProvider, transformLocation, glGetUniformLocation, (program, "mvpMat") );

		m_transformLocation = transformLocation;

		for( uint32_t index = 0; index != m_samplerCount; ++index )
		{
			char samplerVar[16];
			sprintf( samplerVar, "inSampler%d", index );

			int location;
			GLCALLR( m_serviceProvider, location, glGetUniformLocation, (program, samplerVar) );

			m_samplerLocation[index] = location;
		}

		m_program = program;

		return true;
    }
예제 #27
0
bool OpenGLGraphicsManager::getGLPixelFormat(const Graphics::PixelFormat &pixelFormat, GLenum &glIntFormat, GLenum &glFormat, GLenum &glType) const {
#ifdef SCUMM_LITTLE_ENDIAN
	if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)) { // ABGR8888
#else
	if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)) { // RGBA8888
#endif
		glIntFormat = GL_RGBA;
		glFormat = GL_RGBA;
		glType = GL_UNSIGNED_BYTE;
		return true;
	} else if (pixelFormat == Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)) { // RGB565
		glIntFormat = GL_RGB;
		glFormat = GL_RGB;
		glType = GL_UNSIGNED_SHORT_5_6_5;
		return true;
	} else if (pixelFormat == Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0)) { // RGBA5551
		glIntFormat = GL_RGBA;
		glFormat = GL_RGBA;
		glType = GL_UNSIGNED_SHORT_5_5_5_1;
		return true;
	} else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0)) { // RGBA4444
		glIntFormat = GL_RGBA;
		glFormat = GL_RGBA;
		glType = GL_UNSIGNED_SHORT_4_4_4_4;
		return true;
#ifndef USE_GLES
#ifdef SCUMM_LITTLE_ENDIAN
	} else if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)) { // RGBA8888
		glIntFormat = GL_RGBA;
		glFormat = GL_RGBA;
		glType = GL_UNSIGNED_INT_8_8_8_8;
		return true;
#endif
	} else if (pixelFormat == Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)) { // RGB555
		// GL_BGRA does not exist in every GLES implementation so should not be configured if
		// USE_GLES is set.
		glIntFormat = GL_RGB;
		glFormat = GL_BGRA;
		glType = GL_UNSIGNED_SHORT_1_5_5_5_REV;
		return true;
	} else if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24)) { // ARGB8888
		glIntFormat = GL_RGBA;
		glFormat = GL_BGRA;
		glType = GL_UNSIGNED_INT_8_8_8_8_REV;
		return true;
	} else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 8, 4, 0, 12)) { // ARGB4444
		glIntFormat = GL_RGBA;
		glFormat = GL_BGRA;
		glType = GL_UNSIGNED_SHORT_4_4_4_4_REV;
		return true;
#ifdef SCUMM_BIG_ENDIAN
	} else if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)) { // ABGR8888
		glIntFormat = GL_RGBA;
		glFormat = GL_RGBA;
		glType = GL_UNSIGNED_INT_8_8_8_8_REV;
		return true;
#endif
	} else if (pixelFormat == Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0)) { // BGRA8888
		glIntFormat = GL_RGBA;
		glFormat = GL_BGRA;
		glType = GL_UNSIGNED_INT_8_8_8_8;
		return true;
	} else if (pixelFormat == Graphics::PixelFormat(2, 5, 6, 5, 0, 0, 5, 11, 0)) { // BGR565
		glIntFormat = GL_RGB;
		glFormat = GL_BGR;
		glType = GL_UNSIGNED_SHORT_5_6_5;
		return true;
	} else if (pixelFormat == Graphics::PixelFormat(2, 5, 5, 5, 1, 1, 6, 11, 0)) { // BGRA5551
		glIntFormat = GL_RGBA;
		glFormat = GL_BGRA;
		glType = GL_UNSIGNED_SHORT_5_5_5_1;
		return true;
	} else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 0, 4, 8, 12)) { // ABGR4444
		glIntFormat = GL_RGBA;
		glFormat = GL_RGBA;
		glType = GL_UNSIGNED_SHORT_4_4_4_4_REV;
		return true;
	} else if (pixelFormat == Graphics::PixelFormat(2, 4, 4, 4, 4, 4, 8, 12, 0)) { // BGRA4444
		glIntFormat = GL_RGBA;
		glFormat = GL_BGRA;
		glType = GL_UNSIGNED_SHORT_4_4_4_4;
		return true;
#endif
	} else {
		return false;
	}
}

frac_t OpenGLGraphicsManager::getDesiredGameScreenAspect() const {
	const uint width  = _currentState.gameWidth;
	const uint height = _currentState.gameHeight;

	if (_currentState.aspectRatioCorrection) {
		// In case we enable aspect ratio correction we force a 4/3 ratio.
		// But just for 320x200 and 640x400 games, since other games do not need
		// this.
		if ((width == 320 && height == 200) || (width == 640 && height == 400)) {
			return intToFrac(4) / 3;
		}
	}

	return intToFrac(width) / height;
}

void OpenGLGraphicsManager::recalculateDisplayArea() {
	if (!_gameScreen || _outputScreenHeight == 0) {
		return;
	}

	const frac_t outputAspect = intToFrac(_outputScreenWidth) / _outputScreenHeight;
	const frac_t desiredAspect = getDesiredGameScreenAspect();

	_displayWidth = _outputScreenWidth;
	_displayHeight = _outputScreenHeight;

	// Adjust one dimension for mantaining the aspect ratio.
	if (outputAspect < desiredAspect) {
		_displayHeight = intToFrac(_displayWidth) / desiredAspect;
	} else if (outputAspect > desiredAspect) {
		_displayWidth = fracToInt(_displayHeight * desiredAspect);
	}

	// We center the screen in the middle for now.
	_displayX = (_outputScreenWidth  - _displayWidth ) / 2; 
	_displayY = (_outputScreenHeight - _displayHeight) / 2; 
}

void OpenGLGraphicsManager::updateCursorPalette() {
	if (!_cursor || !_cursor->hasPalette()) {
		return;
	}

	if (_cursorPaletteEnabled) {
		_cursor->setPalette(0, 256, _cursorPalette);
	} else {
		_cursor->setPalette(0, 256, _gamePalette);
	}

	// We remove all alpha bits from the palette entry of the color key.
	// This makes sure its properly handled as color key.
	const Graphics::PixelFormat &hardwareFormat = _cursor->getHardwareFormat();
	const uint32 aMask = (0xFF >> hardwareFormat.aLoss) << hardwareFormat.aShift;

	if (hardwareFormat.bytesPerPixel == 2) {
		uint16 *palette = (uint16 *)_cursor->getPalette() + _cursorKeyColor;
		*palette &= ~aMask;
	} else if (hardwareFormat.bytesPerPixel == 4) {
		uint32 *palette = (uint32 *)_cursor->getPalette() + _cursorKeyColor;
		*palette &= ~aMask;
	} else {
		warning("OpenGLGraphicsManager::updateCursorPalette: Unsupported pixel depth %d", hardwareFormat.bytesPerPixel);
	}
}

void OpenGLGraphicsManager::recalculateCursorScaling() {
	if (!_cursor || !_gameScreen) {
		return;
	}

	// By default we use the unscaled versions.
	_cursorHotspotXScaled = _cursorHotspotX;
	_cursorHotspotYScaled = _cursorHotspotY;
	_cursorWidthScaled = _cursor->getWidth();
	_cursorHeightScaled = _cursor->getHeight();

	// In case scaling is actually enabled we will scale the cursor according
	// to the game screen.
	if (!_cursorDontScale) {
		const frac_t screenScaleFactorX = intToFrac(_displayWidth)  / _gameScreen->getWidth();
		const frac_t screenScaleFactorY = intToFrac(_displayHeight) / _gameScreen->getHeight();

		_cursorHotspotXScaled = fracToInt(_cursorHotspotXScaled * screenScaleFactorX);
		_cursorWidthScaled    = fracToInt(_cursorWidthScaled    * screenScaleFactorX);

		_cursorHotspotYScaled = fracToInt(_cursorHotspotYScaled * screenScaleFactorY);
		_cursorHeightScaled   = fracToInt(_cursorHeightScaled   * screenScaleFactorY);
	}
}

#ifdef USE_OSD
const Graphics::Font *OpenGLGraphicsManager::getFontOSD() {
	return FontMan.getFontByUsage(Graphics::FontManager::kLocalizedFont);
}
#endif

void OpenGLGraphicsManager::saveScreenshot(const Common::String &filename) const {
	const uint width  = _outputScreenWidth;
	const uint height = _outputScreenHeight;

	// A line of a BMP image must have a size divisible by 4.
	// We calculate the padding bytes needed here.
	// Since we use a 3 byte per pixel mode, we can use width % 4 here, since
	// it is equal to 4 - (width * 3) % 4. (4 - (width * Bpp) % 4, is the
	// usual way of computing the padding bytes required).
	const uint linePaddingSize = width % 4;
	const uint lineSize        = width * 3 + linePaddingSize;

	// Allocate memory for screenshot
	uint8 *pixels = new uint8[lineSize * height];

	// Get pixel data from OpenGL buffer
	GLCALL(glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels));

	// BMP stores as BGR. Since we can't assume that GL_BGR is supported we
	// will swap the components from the RGB we read to BGR on our own.
	for (uint y = height; y-- > 0;) {
		uint8 *line = pixels + y * lineSize;

		for (uint x = width; x > 0; --x, line += 3) {
			SWAP(line[0], line[2]);
		}
	}

	// Open file
	Common::DumpFile out;
	out.open(filename);

	// Write BMP header
	out.writeByte('B');
	out.writeByte('M');
	out.writeUint32LE(height * lineSize + 54);
	out.writeUint32LE(0);
	out.writeUint32LE(54);
	out.writeUint32LE(40);
	out.writeUint32LE(width);
	out.writeUint32LE(height);
	out.writeUint16LE(1);
	out.writeUint16LE(24);
	out.writeUint32LE(0);
	out.writeUint32LE(0);
	out.writeUint32LE(0);
	out.writeUint32LE(0);
	out.writeUint32LE(0);
	out.writeUint32LE(0);

	// Write pixel data to BMP
	out.write(pixels, lineSize * height);

	// Free allocated memory
	delete[] pixels;
}

} // End of namespace OpenGL
예제 #28
0
	void MarmaladeRenderProgram::bindMatrix( const mt::mat4f & _worldMatrix, const mt::mat4f & _viewMatrix, const mt::mat4f & _projectionMatrix ) const
	{
		m_mvpMat = _worldMatrix * _viewMatrix * _projectionMatrix;

		GLCALL( m_serviceProvider, glUniformMatrix4fv, (m_transformLocation, 1, GL_FALSE, m_mvpMat.buff()) );
	}
예제 #29
0
	void MarmaladeRenderProgram::disable() const
	{
		GLCALL( m_serviceProvider, glUseProgram, (0) );
	}
예제 #30
0
	void MarmaladeRenderProgram::enable() const
	{
		GLCALL( m_serviceProvider, glUseProgram, (m_program) );
	}