all repos — mgba @ 908e61f4153702bce5a28616229f848168203b84

mGBA Game Boy Advance Emulator

src/platform/opengl/gl.c (view raw)

  1/* Copyright (c) 2013-2015 Jeffrey Pfau
  2 *
  3 * This Source Code Form is subject to the terms of the Mozilla Public
  4 * License, v. 2.0. If a copy of the MPL was not distributed with this
  5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6#include "gl.h"
  7
  8#include "gba/video.h"
  9
 10static const GLint _glVertices[] = {
 11	0, 0,
 12	256, 0,
 13	256, 256,
 14	0, 256
 15};
 16
 17static const GLint _glTexCoords[] = {
 18	0, 0,
 19	1, 0,
 20	1, 1,
 21	0, 1
 22};
 23
 24static void GBAGLContextInit(struct VideoBackend* v, WHandle handle) {
 25	UNUSED(handle);
 26	struct GBAGLContext* context = (struct GBAGLContext*) v;
 27	glGenTextures(1, &context->tex);
 28	glBindTexture(GL_TEXTURE_2D, context->tex);
 29	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 30#ifndef _WIN32
 31	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 32	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 33#endif
 34
 35#ifdef COLOR_16_BIT
 36#ifdef COLOR_5_6_5
 37	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0);
 38#else
 39	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0);
 40#endif
 41#else
 42	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
 43#endif
 44}
 45
 46static void GBAGLContextDeinit(struct VideoBackend* v) {
 47	struct GBAGLContext* context = (struct GBAGLContext*) v;
 48	glDeleteTextures(1, &context->tex);
 49}
 50
 51static void GBAGLContextResized(struct VideoBackend* v, int w, int h) {
 52	int drawW = w;
 53	int drawH = h;
 54	if (v->lockAspectRatio) {
 55		if (w * 2 > h * 3) {
 56			drawW = h * 3 / 2;
 57		} else if (w * 2 < h * 3) {
 58			drawH = w * 2 / 3;
 59		}
 60	}
 61	glMatrixMode(GL_MODELVIEW);
 62	glLoadIdentity();
 63	glClearColor(0, 0, 0, 0);
 64	glClear(GL_COLOR_BUFFER_BIT);
 65	glViewport((w - drawW) / 2, (h - drawH) / 2, drawW, drawH);
 66}
 67
 68static void GBAGLContextClear(struct VideoBackend* v) {
 69	UNUSED(v);
 70	glClearColor(0, 0, 0, 0);
 71	glClear(GL_COLOR_BUFFER_BIT);
 72}
 73
 74void GBAGLContextDrawFrame(struct VideoBackend* v) {
 75	struct GBAGLContext* context = (struct GBAGLContext*) v;
 76	glEnable(GL_TEXTURE_2D);
 77	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 78	glEnableClientState(GL_VERTEX_ARRAY);
 79	glVertexPointer(2, GL_INT, 0, _glVertices);
 80	glTexCoordPointer(2, GL_INT, 0, _glTexCoords);
 81	glMatrixMode(GL_PROJECTION);
 82	glLoadIdentity();
 83	glOrtho(0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, 0, 0, 1);
 84	glMatrixMode(GL_MODELVIEW);
 85	glLoadIdentity();
 86	glBindTexture(GL_TEXTURE_2D, context->tex);
 87	if (v->filter) {
 88		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 89		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 90	} else {
 91		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 92		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 93	}
 94	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 95}
 96
 97void GBAGLContextPostFrame(struct VideoBackend* v, const void* frame) {
 98	struct GBAGLContext* context = (struct GBAGLContext*) v;
 99	glBindTexture(GL_TEXTURE_2D, context->tex);
100#ifdef COLOR_16_BIT
101#ifdef COLOR_5_6_5
102	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, frame);
103#else
104	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, frame);
105#endif
106#else
107	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame);
108#endif
109}
110
111void GBAGLContextCreate(struct GBAGLContext* context) {
112	context->d.init = GBAGLContextInit;
113	context->d.deinit = GBAGLContextDeinit;
114	context->d.resized = GBAGLContextResized;
115	context->d.swap = 0;
116	context->d.clear = GBAGLContextClear;
117	context->d.postFrame = GBAGLContextPostFrame;
118	context->d.drawFrame = GBAGLContextDrawFrame;
119	context->d.setMessage = 0;
120	context->d.clearMessage = 0;
121}