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 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, frame);
103#else
104 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, frame);
105#endif
106#else
107 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, 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}