source: trunk/src/video.cpp @ 674

Last change on this file since 674 was 674, checked in by sam, 11 years ago

The engine now builds for GL and GL ES 1.x and 2.x, and runs for each
one except GL ES 2.x for now.

  • Property svn:keywords set to Id
File size: 5.3 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include <cmath>
16#include <cstdio>
17
18#ifdef WIN32
19#   define WIN32_LEAN_AND_MEAN
20#   include <windows.h>
21#endif
22
23#include "core.h"
24#include "lolgl.h"
25
26#if defined HAVE_GL_2X || defined HAVE_GLES_2X
27Shader *stdshader;
28#endif
29mat4 proj_matrix, view_matrix, model_matrix;
30
31#if defined HAVE_GL_2X || defined HAVE_GLES_2X
32static char const *vertexshader =
33    "#version 130\n"
34    "\n"
35    "in vec3 in_Position;\n"
36    //"in vec3 in_Color;\n"
37    "in vec2 in_TexCoord;\n"
38    //"out vec3 pass_Color;\n"
39    "uniform mat4 proj_matrix;\n"
40    "uniform mat4 view_matrix;\n"
41    "uniform mat4 model_matrix;\n"
42    "\n"
43    "void main()\n"
44    "{\n"
45    "    gl_Position = proj_matrix * view_matrix * model_matrix"
46    "                * vec4(in_Position, 1.0f);\n"
47    "    gl_TexCoord[0] = vec4(in_TexCoord, 0.0, 0.0);\n"
48    //"    pass_Color = in_Color;\n"
49    "}\n";
50
51static char const *fragmentshader =
52    "#version 130\n"
53    "\n"
54    "uniform sampler2D in_Texture;\n"
55    //"in vec3 pass_Color;\n"
56    "out vec4 out_Color;\n"
57    "\n"
58    "void main()\n"
59    "{\n"
60    //"    gl_FragColor = 0.5 * (texture2D(in_Texture, vec2(gl_TexCoord[0]))\n"
61    //"                           + vec4(pass_Color, 1.0));\n"
62    "    gl_FragColor = texture2D(in_Texture, vec2(gl_TexCoord[0]));\n"
63    //"    gl_FragColor = vec4(0.5, 1.0, 0.0, 0.5);\n"
64    "}\n";
65#endif
66
67/*
68 * Public Video class
69 */
70
71void Video::Setup(int width, int height)
72{
73    /* Initialise OpenGL */
74    glViewport(0, 0, width, height);
75
76    glEnable(GL_TEXTURE_2D);
77#if defined HAVE_GL_2X || defined HAVE_GLES_1X
78    glShadeModel(GL_SMOOTH);
79#endif
80    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
81    glClearDepthf(1.0);
82
83#if defined HAVE_GL_2X || defined HAVE_GLES_1X
84    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
85#endif
86
87#if defined HAVE_GL_2X || defined HAVE_GLES_2X
88    stdshader = Shader::Create(vertexshader, fragmentshader);
89#endif
90}
91
92void Video::SetFov(float theta)
93{
94#undef near /* Fuck Microsoft */
95#undef far /* Fuck Microsoft again */
96    mat4 proj;
97
98    float width = GetWidth();
99    float height = GetHeight();
100    float near = -width - height;
101    float far = width + height;
102
103    /* Set the projection matrix */
104    if (theta < 1e-4f)
105    {
106        /* The easy way: purely orthogonal projection. */
107        proj_matrix = mat4::ortho(0, width, 0, height, near, far);
108    }
109    else
110    {
111        /* Compute a view that approximates the glOrtho view when theta
112         * approaches zero. This view ensures that the z=0 plane fills
113         * the screen. */
114        float t1 = tanf(theta / 2);
115        float t2 = t1 * height / width;
116        float dist = (float)width / (2.0f * t1);
117
118        near += dist;
119        far += dist;
120
121        if (near <= 0.0f)
122        {
123            far -= (near - 1.0f);
124            near = 1.0f;
125        }
126
127        proj_matrix = mat4::frustum(-near * t1, near * t1,
128                                    -near * t2, near * t2, near, far)
129                    * mat4::translate(-0.5f * width, -0.5f * height, -dist);
130    }
131
132    view_matrix = mat4(1.0f);
133
134#if defined HAVE_GL_2X || defined HAVE_GLES_2X
135    stdshader->Bind(); /* Required on GLES 2.x? */
136    GLuint uni;
137    uni = stdshader->GetUniformLocation("proj_matrix");
138    glUniformMatrix4fv(uni, 1, GL_FALSE, &proj_matrix[0][0]);
139    uni = stdshader->GetUniformLocation("view_matrix");
140    glUniformMatrix4fv(uni, 1, GL_FALSE, &view_matrix[0][0]);
141#else
142    glMatrixMode(GL_PROJECTION);
143    glLoadIdentity();
144    glMultMatrixf(&proj_matrix[0][0]);
145
146    /* Reset the model view matrix, just in case */
147    glMatrixMode(GL_MODELVIEW);
148    glLoadIdentity();
149    glMultMatrixf(&view_matrix[0][0]);
150#endif
151}
152
153void Video::SetDepth(bool set)
154{
155    if (set)
156        glEnable(GL_DEPTH_TEST);
157    else
158        glDisable(GL_DEPTH_TEST);
159}
160
161void Video::Clear()
162{
163    glViewport(0, 0, GetWidth(), GetHeight());
164    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
165
166    SetFov(0.0f);
167}
168
169void Video::Destroy()
170{
171#if defined HAVE_GL_2X || defined HAVE_GLES_2X
172    Shader::Destroy(stdshader);
173#endif
174}
175
176void Video::Capture(uint32_t *buffer)
177{
178    GLint v[4];
179    glGetIntegerv(GL_VIEWPORT, v);
180    int width = v[2], height = v[3];
181
182#if defined HAVE_GL_1X || defined HAVE_GL_2X
183    glPixelStorei(GL_PACK_ROW_LENGTH, 0);
184#endif
185    glPixelStorei(GL_PACK_ALIGNMENT, 1);
186
187#if defined GL_BGRA
188    glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
189#else
190    glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
191#endif
192
193    for (int j = 0; j < height / 2; j++)
194        for (int i = 0; i < width; i++)
195        {
196            uint32_t tmp = buffer[j * width + i];
197            buffer[j * width + i] = buffer[(height - j - 1) * width + i];
198            buffer[(height - j - 1) * width + i] = tmp;
199        }
200}
201
202int Video::GetWidth()
203{
204    GLint v[4];
205    glGetIntegerv(GL_VIEWPORT, v);
206    return v[2];
207}
208
209int Video::GetHeight()
210{
211    GLint v[4];
212    glGetIntegerv(GL_VIEWPORT, v);
213    return v[3];
214}
215
Note: See TracBrowser for help on using the repository browser.