source: trunk/src/video.cpp @ 960

Last change on this file since 960 was 960, checked in by sam, 8 years ago

osx: link with the proper OpenGL libraries on OS X.

  • Property svn:keywords set to Id
File size: 4.5 KB
RevLine 
[105]1//
[221]2// Lol Engine
[105]3//
[221]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//
[105]10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
[216]15#include <cmath>
[209]16
[105]17#ifdef WIN32
18#   define WIN32_LEAN_AND_MEAN
19#   include <windows.h>
20#endif
21
[150]22#include "core.h"
[673]23#include "lolgl.h"
[105]24
[758]25using namespace std;
26
[686]27namespace lol
28{
29
[784]30class VideoData
31{
32    friend class Video;
33
34private:
35    static mat4 proj_matrix, view_matrix;
[960]36#if defined __ANDROID__ || defined __CELLOS_LV2__ || defined __APPLE__
[863]37    static ivec2 saved_viewport;
[707]38#endif
[784]39};
[707]40
[784]41mat4 VideoData::proj_matrix;
42mat4 VideoData::view_matrix;
[653]43
[960]44#if defined __ANDROID__ || defined __CELLOS_LV2__ || defined __APPLE__
[863]45ivec2 VideoData::saved_viewport = 0;
[682]46#endif
[653]47
[105]48/*
49 * Public Video class
50 */
51
[863]52void Video::Setup(ivec2 size)
[105]53{
[960]54#if defined USE_GLEW && !defined __APPLE__
[808]55    /* Initialise GLEW if necessary */
56    GLenum glerr = glewInit();
57    if (glerr != GLEW_OK)
58    {
59        Log::Error("cannot initialise GLEW: %s\n", glewGetErrorString(glerr));
60        exit(EXIT_FAILURE);
61    }
62#endif
63
[105]64    /* Initialise OpenGL */
[755]65    glViewport(0, 0, size.x, size.y);
[105]66
[960]67#if defined __ANDROID__ || defined __CELLOS_LV2__ || defined __APPLE__
[784]68    VideoData::saved_viewport = size;
[707]69#endif
70
[681]71    glClearColor(0.1f, 0.2f, 0.3f, 0.0f);
[796]72    glClearDepth(1.0);
[207]73
[960]74#if defined HAVE_GL_2X && !defined __APPLE__
[698]75    glShadeModel(GL_SMOOTH);
[207]76    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
[674]77#endif
[209]78}
[207]79
[209]80void Video::SetFov(float theta)
81{
[216]82#undef near /* Fuck Microsoft */
83#undef far /* Fuck Microsoft again */
[755]84    vec2 size = GetSize();
85    float near = -size.x - size.y;
86    float far = size.x + size.y;
[209]87
[939]88#if defined __ANDROID__
[780]89    size = vec2(640.0f, 480.0f);
[727]90#endif
91
[209]92    /* Set the projection matrix */
93    if (theta < 1e-4f)
94    {
95        /* The easy way: purely orthogonal projection. */
[784]96        VideoData::proj_matrix = mat4::ortho(0, size.x, 0, size.y, near, far);
[209]97    }
98    else
99    {
100        /* Compute a view that approximates the glOrtho view when theta
101         * approaches zero. This view ensures that the z=0 plane fills
102         * the screen. */
103        float t1 = tanf(theta / 2);
[755]104        float t2 = t1 * size.y / size.y;
105        float dist = size.x / (2.0f * t1);
[209]106
107        near += dist;
108        far += dist;
109
110        if (near <= 0.0f)
111        {
112            far -= (near - 1.0f);
113            near = 1.0f;
114        }
115
[784]116        mat4 proj = mat4::frustum(-near * t1, near * t1,
117                                  -near * t2, near * t2, near, far);
118        mat4 trans = mat4::translate(-0.5f * size.x, -0.5f * size.y, -dist);
119        VideoData::proj_matrix = proj * trans;
[209]120    }
121
[784]122    VideoData::view_matrix = mat4(1.0f);
[105]123}
124
[211]125void Video::SetDepth(bool set)
126{
127    if (set)
128        glEnable(GL_DEPTH_TEST);
129    else
130        glDisable(GL_DEPTH_TEST);
131}
132
[105]133void Video::Clear()
134{
[863]135    ivec2 size = GetSize();
[755]136    glViewport(0, 0, size.x, size.y);
[653]137    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
138
[662]139    SetFov(0.0f);
[105]140}
[139]141
[653]142void Video::Destroy()
143{
[784]144    ;
[653]145}
146
[140]147void Video::Capture(uint32_t *buffer)
148{
149    GLint v[4];
[758]150#if defined __CELLOS_LV2__
151    // FIXME: use psglCreateDeviceAuto && psglGetDeviceDimensions
152    v[2] = 1920;
153    v[3] = 1080;
154#else
[140]155    glGetIntegerv(GL_VIEWPORT, v);
[758]156#endif
[140]157    int width = v[2], height = v[3];
158
[745]159#if defined HAVE_GL_2X
[140]160    glPixelStorei(GL_PACK_ROW_LENGTH, 0);
[674]161#endif
[140]162    glPixelStorei(GL_PACK_ALIGNMENT, 1);
163
[615]164#if defined GL_BGRA
165    glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
166#else
[216]167    glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
[615]168#endif
[140]169
170    for (int j = 0; j < height / 2; j++)
171        for (int i = 0; i < width; i++)
172        {
173            uint32_t tmp = buffer[j * width + i];
174            buffer[j * width + i] = buffer[(height - j - 1) * width + i];
175            buffer[(height - j - 1) * width + i] = tmp;
176        }
177}
178
[863]179ivec2 Video::GetSize()
[139]180{
[939]181#if defined __ANDROID__
[784]182    return VideoData::saved_viewport;
[758]183#elif defined __CELLOS_LV2__
184    // FIXME: use psglCreateDeviceAuto && psglGetDeviceDimensions
[820]185    return VideoData::saved_viewport;
[960]186#elif defined __APPLE__
187    return VideoData::saved_viewport;
[707]188#else
[139]189    GLint v[4];
190    glGetIntegerv(GL_VIEWPORT, v);
[863]191    return ivec2(v[2], v[3]);
[707]192#endif
[139]193}
194
[784]195mat4 const & Video::GetProjMatrix()
196{
197    return VideoData::proj_matrix;
198}
199
200mat4 const & Video::GetViewMatrix()
201{
202    return VideoData::view_matrix;
203}
204
[686]205} /* namespace lol */
206
Note: See TracBrowser for help on using the repository browser.