source: trunk/src/video.cpp @ 698

Last change on this file since 698 was 698, checked in by sam, 9 years ago

Enable GL_TEXTURE_2D in the Scene class instead of Video.

  • Property svn:keywords set to Id
File size: 5.7 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
26namespace lol
27{
28
29#if defined HAVE_GL_2X || defined HAVE_GLES_2X
30Shader *stdshader;
31#endif
32mat4 proj_matrix, view_matrix, model_matrix;
33
34#if defined HAVE_GL_2X || defined HAVE_GLES_2X
35static char const *vertexshader =
36#if !defined HAVE_GLES_2X
37    "#version 130\n"
38#endif
39    "\n"
40#if defined HAVE_GLES_2X
41    "attribute vec3 in_Position;\n"
42    "attribute vec2 in_TexCoord;\n"
43    "varying vec2 pass_TexCoord;\n"
44#else
45    "in vec3 in_Position;\n"
46    "in vec2 in_TexCoord;\n"
47#endif
48    //"in vec3 in_Color;\n"
49    //"out vec3 pass_Color;\n"
50    "uniform mat4 proj_matrix;\n"
51    "uniform mat4 view_matrix;\n"
52    "uniform mat4 model_matrix;\n"
53    "\n"
54    "void main()\n"
55    "{\n"
56    "    gl_Position = proj_matrix * view_matrix * model_matrix"
57    "                * vec4(in_Position, 1.0f);\n"
58    //"    pass_Color = in_Color;\n"
59#if defined HAVE_GLES_2X
60    "    pass_TexCoord = in_TexCoord;\n"
61#else
62    "    gl_TexCoord[0] = vec4(in_TexCoord, 0.0, 0.0);\n"
63#endif
64    "}\n";
65
66static char const *fragmentshader =
67#if !defined HAVE_GLES_2X
68    "#version 130\n"
69#endif
70    "\n"
71    "uniform sampler2D in_Texture;\n"
72    //"in vec3 pass_Color;\n"
73    //"out vec4 out_Color;\n"
74#if defined HAVE_GLES_2X
75    "varying vec2 pass_TexCoord;\n"
76#endif
77    "\n"
78    "void main()\n"
79    "{\n"
80#if defined HAVE_GLES_2X
81    "    gl_FragColor = texture2D(in_Texture, pass_TexCoord);\n"
82    //"    gl_FragColor = vec4(0.5, 1.0, 0.0, 0.5);\n"
83    //"    gl_FragColor = vec4(pass_TexCoord * 4.0, 0.0, 0.25);\n"
84#else
85    "    gl_FragColor = texture2D(in_Texture, vec2(gl_TexCoord[0]));\n"
86#endif
87    "}\n";
88#endif
89
90/*
91 * Public Video class
92 */
93
94void Video::Setup(int width, int height)
95{
96    /* Initialise OpenGL */
97    glViewport(0, 0, width, height);
98
99    glClearColor(0.1f, 0.2f, 0.3f, 0.0f);
100    glClearDepthf(1.0);
101
102#if defined HAVE_GL_2X || defined HAVE_GLES_1X
103    glShadeModel(GL_SMOOTH);
104#endif
105#if defined HAVE_GL_2X || defined HAVE_GLES_1X
106    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
107#endif
108
109#if defined HAVE_GL_2X || defined HAVE_GLES_2X
110    stdshader = Shader::Create(vertexshader, fragmentshader);
111#endif
112}
113
114void Video::SetFov(float theta)
115{
116#undef near /* Fuck Microsoft */
117#undef far /* Fuck Microsoft again */
118    mat4 proj;
119
120    float width = GetWidth();
121    float height = GetHeight();
122    float near = -width - height;
123    float far = width + height;
124
125    /* Set the projection matrix */
126    if (theta < 1e-4f)
127    {
128        /* The easy way: purely orthogonal projection. */
129        proj_matrix = mat4::ortho(0, width, 0, height, near, far);
130    }
131    else
132    {
133        /* Compute a view that approximates the glOrtho view when theta
134         * approaches zero. This view ensures that the z=0 plane fills
135         * the screen. */
136        float t1 = tanf(theta / 2);
137        float t2 = t1 * height / width;
138        float dist = (float)width / (2.0f * t1);
139
140        near += dist;
141        far += dist;
142
143        if (near <= 0.0f)
144        {
145            far -= (near - 1.0f);
146            near = 1.0f;
147        }
148
149        proj_matrix = mat4::frustum(-near * t1, near * t1,
150                                    -near * t2, near * t2, near, far)
151                    * mat4::translate(-0.5f * width, -0.5f * height, -dist);
152    }
153
154    view_matrix = mat4(1.0f);
155
156#if defined HAVE_GL_2X || defined HAVE_GLES_2X
157    stdshader->Bind(); /* Required on GLES 2.x? */
158    GLuint uni;
159    uni = stdshader->GetUniformLocation("proj_matrix");
160    glUniformMatrix4fv(uni, 1, GL_FALSE, &proj_matrix[0][0]);
161    uni = stdshader->GetUniformLocation("view_matrix");
162    glUniformMatrix4fv(uni, 1, GL_FALSE, &view_matrix[0][0]);
163#else
164    glMatrixMode(GL_PROJECTION);
165    glLoadIdentity();
166    glMultMatrixf(&proj_matrix[0][0]);
167
168    /* Reset the model view matrix, just in case */
169    glMatrixMode(GL_MODELVIEW);
170    glLoadIdentity();
171    glMultMatrixf(&view_matrix[0][0]);
172#endif
173}
174
175void Video::SetDepth(bool set)
176{
177    if (set)
178        glEnable(GL_DEPTH_TEST);
179    else
180        glDisable(GL_DEPTH_TEST);
181}
182
183void Video::Clear()
184{
185    glViewport(0, 0, GetWidth(), GetHeight());
186    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
187
188    SetFov(0.0f);
189}
190
191void Video::Destroy()
192{
193#if defined HAVE_GL_2X || defined HAVE_GLES_2X
194    Shader::Destroy(stdshader);
195#endif
196}
197
198void Video::Capture(uint32_t *buffer)
199{
200    GLint v[4];
201    glGetIntegerv(GL_VIEWPORT, v);
202    int width = v[2], height = v[3];
203
204#if defined HAVE_GL_1X || defined HAVE_GL_2X
205    glPixelStorei(GL_PACK_ROW_LENGTH, 0);
206#endif
207    glPixelStorei(GL_PACK_ALIGNMENT, 1);
208
209#if defined GL_BGRA
210    glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
211#else
212    glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
213#endif
214
215    for (int j = 0; j < height / 2; j++)
216        for (int i = 0; i < width; i++)
217        {
218            uint32_t tmp = buffer[j * width + i];
219            buffer[j * width + i] = buffer[(height - j - 1) * width + i];
220            buffer[(height - j - 1) * width + i] = tmp;
221        }
222}
223
224int Video::GetWidth()
225{
226    GLint v[4];
227    glGetIntegerv(GL_VIEWPORT, v);
228    return v[2];
229}
230
231int Video::GetHeight()
232{
233    GLint v[4];
234    glGetIntegerv(GL_VIEWPORT, v);
235    return v[3];
236}
237
238} /* namespace lol */
239
Note: See TracBrowser for help on using the repository browser.