2014-08-13 18:52:52 +02:00
|
|
|
/* ResidualVM - A 3D game interpreter
|
|
|
|
*
|
|
|
|
* ResidualVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the AUTHORS
|
|
|
|
* file distributed with this source distribution.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This file is based on, or a modified version of code from TinyGL (C) 1997-1998 Fabrice Bellard,
|
|
|
|
* which is licensed under the zlib-license (see LICENSE).
|
|
|
|
* It also has modifications by the ResidualVM-team, which are covered under the GPLv2 (or later).
|
|
|
|
*/
|
2006-05-16 14:52:36 +00:00
|
|
|
|
2009-05-08 07:32:33 +00:00
|
|
|
#include "graphics/tinygl/zgl.h"
|
2014-08-05 20:00:13 +02:00
|
|
|
#include "graphics/tinygl/zblit.h"
|
2016-07-25 01:18:11 +02:00
|
|
|
#include "graphics/tinygl/zdirtyrect.h"
|
2005-01-12 15:20:02 +00:00
|
|
|
|
2009-05-25 13:19:29 +00:00
|
|
|
namespace TinyGL {
|
|
|
|
|
2005-01-12 15:20:02 +00:00
|
|
|
GLContext *gl_ctx;
|
|
|
|
|
2021-12-07 00:58:14 +01:00
|
|
|
void GLContext::initSharedState() {
|
|
|
|
GLSharedState *s = &shared_state;
|
2006-05-16 14:52:36 +00:00
|
|
|
s->lists = (GLList **)gl_zalloc(sizeof(GLList *) * MAX_DISPLAY_LISTS);
|
|
|
|
s->texture_hash_table = (GLTexture **)gl_zalloc(sizeof(GLTexture *) * TEXTURE_HASH_TABLE_SIZE);
|
2005-01-12 15:20:02 +00:00
|
|
|
|
2021-12-07 00:58:14 +01:00
|
|
|
alloc_texture(0);
|
2005-01-12 15:20:02 +00:00
|
|
|
}
|
|
|
|
|
2021-12-07 00:58:14 +01:00
|
|
|
void GLContext::endSharedState() {
|
|
|
|
GLSharedState *s = &shared_state;
|
2005-01-12 15:20:02 +00:00
|
|
|
|
2021-12-04 14:27:35 +01:00
|
|
|
uint h = 0;
|
2021-12-07 00:58:14 +01:00
|
|
|
free_texture(h);
|
2014-02-20 18:46:49 +01:00
|
|
|
for (int i = 0; i < MAX_DISPLAY_LISTS; i++) {
|
2006-05-16 14:52:36 +00:00
|
|
|
// TODO
|
|
|
|
}
|
|
|
|
gl_free(s->lists);
|
2005-01-12 15:20:02 +00:00
|
|
|
|
2006-05-16 14:52:36 +00:00
|
|
|
gl_free(s->texture_hash_table);
|
2005-01-12 15:20:02 +00:00
|
|
|
}
|
|
|
|
|
2021-12-09 21:10:53 +01:00
|
|
|
void createContext(int screenW, int screenH, Graphics::PixelFormat pixelFormat, int textureSize, bool enableStencilBuffer, bool dirtyRectsEnable) {
|
2021-12-06 13:57:41 +01:00
|
|
|
assert(gl_ctx == nullptr);
|
2021-12-09 21:10:53 +01:00
|
|
|
gl_ctx = new GLContext();
|
|
|
|
gl_ctx->init(screenW, screenH, pixelFormat, textureSize, enableStencilBuffer, dirtyRectsEnable);
|
2021-12-06 13:57:41 +01:00
|
|
|
}
|
|
|
|
|
2021-12-09 21:10:53 +01:00
|
|
|
void GLContext::init(int screenW, int screenH, Graphics::PixelFormat pixelFormat, int textureSize, bool enableStencilBuffer, bool dirtyRectsEnable) {
|
2006-05-16 14:52:36 +00:00
|
|
|
GLViewport *v;
|
2005-01-12 15:20:02 +00:00
|
|
|
|
2021-12-07 20:40:32 +01:00
|
|
|
_enableDirtyRectangles = dirtyRectsEnable;
|
|
|
|
|
2021-12-09 21:10:53 +01:00
|
|
|
fb = new TinyGL::FrameBuffer(screenW, screenH, pixelFormat, enableStencilBuffer);
|
2021-12-07 20:40:32 +01:00
|
|
|
renderRect = Common::Rect(0, 0, screenW, screenH);
|
|
|
|
|
2014-07-05 13:08:34 +02:00
|
|
|
if ((textureSize & (textureSize - 1)))
|
|
|
|
error("glInit: texture size not power of two: %d", textureSize);
|
|
|
|
if (textureSize <= 1 || textureSize > 4096)
|
|
|
|
error("glInit: texture size not allowed: %d", textureSize);
|
2021-12-07 20:40:32 +01:00
|
|
|
_textureSize = textureSize;
|
|
|
|
fb->setTextureSizeAndMask(textureSize, (textureSize - 1) << ZB_POINT_ST_FRAC_BITS);
|
2014-07-05 13:08:34 +02:00
|
|
|
|
2006-05-16 14:52:36 +00:00
|
|
|
// allocate GLVertex array
|
2021-12-07 00:58:14 +01:00
|
|
|
vertex_max = POLYGON_MAX_VERTEX;
|
|
|
|
vertex = (GLVertex *)gl_malloc(POLYGON_MAX_VERTEX * sizeof(GLVertex));
|
2014-02-20 18:46:49 +01:00
|
|
|
|
2006-05-16 14:52:36 +00:00
|
|
|
// viewport
|
2021-12-07 00:58:14 +01:00
|
|
|
v = &viewport;
|
2006-05-16 14:52:36 +00:00
|
|
|
v->xmin = 0;
|
|
|
|
v->ymin = 0;
|
2021-12-07 20:40:32 +01:00
|
|
|
v->xsize = screenW;
|
|
|
|
v->ysize = screenH;
|
2006-05-16 14:52:36 +00:00
|
|
|
v->updated = 1;
|
|
|
|
|
|
|
|
// shared state
|
2021-12-07 00:58:14 +01:00
|
|
|
initSharedState();
|
2006-05-16 14:52:36 +00:00
|
|
|
|
|
|
|
// lists
|
2021-12-07 00:58:14 +01:00
|
|
|
exec_flag = 1;
|
|
|
|
compile_flag = 0;
|
|
|
|
print_flag = 0;
|
2006-05-16 14:52:36 +00:00
|
|
|
|
2021-12-07 00:58:14 +01:00
|
|
|
in_begin = 0;
|
2006-05-16 14:52:36 +00:00
|
|
|
|
|
|
|
// lights
|
2014-02-20 17:56:55 +01:00
|
|
|
for (int i = 0; i < T_MAX_LIGHTS; i++) {
|
2021-12-07 00:58:14 +01:00
|
|
|
GLLight *l = &lights[i];
|
2014-05-28 19:27:00 +01:00
|
|
|
l->ambient = Vector4(0, 0, 0, 1);
|
2015-03-15 22:14:39 +01:00
|
|
|
if (i == 0) {
|
|
|
|
l->diffuse = Vector4(1, 1, 1, 1);
|
|
|
|
l->specular = Vector4(1, 1, 1, 1);
|
2016-07-16 06:52:04 +00:00
|
|
|
l->has_specular = true;
|
2015-03-15 22:14:39 +01:00
|
|
|
} else {
|
2016-07-16 04:23:28 +00:00
|
|
|
l->diffuse = Vector4(0, 0, 0, 1);
|
|
|
|
l->specular = Vector4(0, 0, 0, 1);
|
2016-07-16 06:52:04 +00:00
|
|
|
l->has_specular = false;
|
2015-03-15 22:14:39 +01:00
|
|
|
}
|
2014-05-28 19:27:00 +01:00
|
|
|
l->position = Vector4(0, 0, 1, 0);
|
|
|
|
l->spot_direction = Vector3(0, 0, -1);
|
2006-05-16 14:52:36 +00:00
|
|
|
l->spot_exponent = 0;
|
|
|
|
l->spot_cutoff = 180;
|
|
|
|
l->attenuation[0] = 1;
|
|
|
|
l->attenuation[1] = 0;
|
|
|
|
l->attenuation[2] = 0;
|
2016-07-20 16:25:33 +02:00
|
|
|
l->cos_spot_cutoff = -1.0f;
|
|
|
|
l->norm_spot_direction = Vector3(0, 0, -1);
|
|
|
|
l->norm_position = Vector3(0, 0, 1);
|
2006-05-16 14:52:36 +00:00
|
|
|
l->enabled = 0;
|
2016-07-20 16:25:33 +02:00
|
|
|
l->next = NULL;
|
|
|
|
l->prev = NULL;
|
2006-05-16 14:52:36 +00:00
|
|
|
}
|
2021-12-07 00:58:14 +01:00
|
|
|
first_light = NULL;
|
|
|
|
ambient_light_model = Vector4(0.2f, 0.2f, 0.2f, 1);
|
|
|
|
local_light_model = 0;
|
|
|
|
lighting_enabled = 0;
|
|
|
|
light_model_two_side = 0;
|
2006-05-16 14:52:36 +00:00
|
|
|
|
|
|
|
// default materials */
|
2014-02-20 17:56:55 +01:00
|
|
|
for (int i = 0; i < 2; i++) {
|
2021-12-07 00:58:14 +01:00
|
|
|
GLMaterial *m = &materials[i];
|
2014-05-28 19:27:00 +01:00
|
|
|
m->emission = Vector4(0, 0, 0, 1);
|
|
|
|
m->ambient = Vector4(0.2f, 0.2f, 0.2f, 1);
|
|
|
|
m->diffuse = Vector4(0.8f, 0.8f, 0.8f, 1);
|
|
|
|
m->specular = Vector4(0, 0, 0, 1);
|
2016-07-16 06:52:04 +00:00
|
|
|
m->has_specular = false;
|
2006-05-16 14:52:36 +00:00
|
|
|
m->shininess = 0;
|
|
|
|
}
|
2021-12-07 00:58:14 +01:00
|
|
|
current_color_material_mode = TGL_FRONT_AND_BACK;
|
|
|
|
current_color_material_type = TGL_AMBIENT_AND_DIFFUSE;
|
|
|
|
color_material_enabled = 0;
|
2006-05-16 14:52:36 +00:00
|
|
|
|
|
|
|
// textures
|
2021-12-07 00:58:14 +01:00
|
|
|
glInitTextures();
|
2006-05-16 14:52:36 +00:00
|
|
|
|
|
|
|
// default state
|
2021-12-07 00:58:14 +01:00
|
|
|
current_color = Vector4(1.0f, 1.0f, 1.0f, 1.0f);
|
2006-05-16 14:52:36 +00:00
|
|
|
|
2021-12-07 00:58:14 +01:00
|
|
|
current_normal = Vector4(1.0f, 0.0f, 0.0f, 0.0f);
|
2006-05-16 14:52:36 +00:00
|
|
|
|
2021-12-07 00:58:14 +01:00
|
|
|
current_edge_flag = 1;
|
2006-05-16 14:52:36 +00:00
|
|
|
|
2021-12-07 00:58:14 +01:00
|
|
|
current_tex_coord = Vector4(0.0f, 0.0f, 0.0f, 1.0f);
|
2006-05-16 14:52:36 +00:00
|
|
|
|
2021-12-07 00:58:14 +01:00
|
|
|
polygon_mode_front = TGL_FILL;
|
|
|
|
polygon_mode_back = TGL_FILL;
|
2006-05-16 14:52:36 +00:00
|
|
|
|
2021-12-07 00:58:14 +01:00
|
|
|
current_front_face = 0; // 0 = GL_CCW 1 = GL_CW
|
|
|
|
current_cull_face = TGL_BACK;
|
|
|
|
current_shade_model = TGL_SMOOTH;
|
|
|
|
cull_face_enabled = 0;
|
2014-02-20 18:46:49 +01:00
|
|
|
|
2006-05-16 14:52:36 +00:00
|
|
|
// clear
|
2021-12-07 00:58:14 +01:00
|
|
|
clear_color = Vector4(0.0f, 0.0f, 0.0f, 0.0f);
|
|
|
|
clear_depth = 1.0f;
|
2021-12-09 21:10:53 +01:00
|
|
|
clear_stencil = 0;
|
2006-05-16 14:52:36 +00:00
|
|
|
|
|
|
|
// selection
|
2021-12-07 00:58:14 +01:00
|
|
|
render_mode = TGL_RENDER;
|
2021-12-09 21:10:53 +01:00
|
|
|
select_buffer = nullptr;
|
2021-12-07 00:58:14 +01:00
|
|
|
name_stack_size = 0;
|
2014-07-04 08:43:19 +02:00
|
|
|
|
|
|
|
// blending
|
2021-12-07 19:58:03 +01:00
|
|
|
blending_enabled = false;
|
2021-12-09 21:10:53 +01:00
|
|
|
source_blending_factor = TGL_ONE;
|
|
|
|
destination_blending_factor = TGL_ZERO;
|
2014-07-04 08:43:19 +02:00
|
|
|
|
|
|
|
// alpha test
|
2021-12-07 19:58:03 +01:00
|
|
|
alpha_test_enabled = false;
|
2021-12-09 21:10:53 +01:00
|
|
|
alpha_test_func = TGL_ALWAYS;
|
|
|
|
alpha_test_ref_val = 0;
|
2021-12-07 19:58:03 +01:00
|
|
|
|
|
|
|
// depth test
|
2021-12-09 21:10:53 +01:00
|
|
|
depth_test_enabled = false;
|
|
|
|
depth_func = TGL_LESS;
|
|
|
|
depth_write_mask = true;
|
|
|
|
|
|
|
|
// stencil
|
|
|
|
stencil_test_enabled = false;
|
|
|
|
stencil_test_func = TGL_ALWAYS;
|
|
|
|
stencil_ref_val = 0;
|
|
|
|
stencil_mask = 0xff;
|
|
|
|
stencil_write_mask = 0xff;
|
|
|
|
stencil_sfail = TGL_KEEP;
|
|
|
|
stencil_dpfail = TGL_KEEP;
|
|
|
|
stencil_dppass = TGL_KEEP;
|
2014-07-04 08:43:19 +02:00
|
|
|
|
2006-05-16 14:52:36 +00:00
|
|
|
// matrix
|
2021-12-07 00:58:14 +01:00
|
|
|
matrix_mode = 0;
|
2014-02-20 18:46:49 +01:00
|
|
|
|
2021-12-07 00:58:14 +01:00
|
|
|
matrix_stack_depth_max[0] = MAX_MODELVIEW_STACK_DEPTH;
|
|
|
|
matrix_stack_depth_max[1] = MAX_PROJECTION_STACK_DEPTH;
|
|
|
|
matrix_stack_depth_max[2] = MAX_TEXTURE_STACK_DEPTH;
|
2006-05-16 14:52:36 +00:00
|
|
|
|
2014-02-20 17:56:55 +01:00
|
|
|
for (int i = 0; i < 3; i++) {
|
2021-12-07 00:58:14 +01:00
|
|
|
matrix_stack[i] = (Matrix4 *)gl_zalloc(matrix_stack_depth_max[i] * sizeof(Matrix4));
|
|
|
|
matrix_stack_ptr[i] = matrix_stack[i];
|
2006-05-16 14:52:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
tglMatrixMode(TGL_PROJECTION);
|
|
|
|
tglLoadIdentity();
|
|
|
|
tglMatrixMode(TGL_TEXTURE);
|
|
|
|
tglLoadIdentity();
|
|
|
|
tglMatrixMode(TGL_MODELVIEW);
|
|
|
|
tglLoadIdentity();
|
2014-07-04 08:43:19 +02:00
|
|
|
|
2021-12-07 00:58:14 +01:00
|
|
|
matrix_model_projection_updated = 1;
|
2006-05-16 14:52:36 +00:00
|
|
|
|
|
|
|
// opengl 1.1 arrays
|
2021-12-07 00:58:14 +01:00
|
|
|
client_states = 0;
|
2006-05-16 14:52:36 +00:00
|
|
|
|
|
|
|
// opengl 1.1 polygon offset
|
2021-12-07 00:58:14 +01:00
|
|
|
offset_states = 0;
|
|
|
|
offset_factor = 0.0f;
|
|
|
|
offset_units = 0.0f;
|
2006-05-16 14:52:36 +00:00
|
|
|
|
|
|
|
// clear the resize callback function pointer
|
2021-12-09 21:10:53 +01:00
|
|
|
gl_resize_viewport = nullptr;
|
2006-05-16 14:52:36 +00:00
|
|
|
|
|
|
|
// specular buffer
|
2021-12-09 21:10:53 +01:00
|
|
|
specbuf_first = nullptr;
|
2021-12-07 00:58:14 +01:00
|
|
|
specbuf_used_counter = 0;
|
|
|
|
specbuf_num_buffers = 0;
|
2005-01-12 15:20:02 +00:00
|
|
|
|
2021-12-10 18:37:24 +01:00
|
|
|
// color mask
|
|
|
|
color_mask_red = color_mask_green = color_mask_blue = color_mask_alpha = true;
|
2014-08-05 20:00:13 +02:00
|
|
|
|
2014-08-07 21:47:54 +02:00
|
|
|
const int kDrawCallMemory = 5 * 1024 * 1024;
|
|
|
|
|
2021-12-07 00:58:14 +01:00
|
|
|
_currentAllocatorIndex = 0;
|
|
|
|
_drawCallAllocator[0].initialize(kDrawCallMemory);
|
|
|
|
_drawCallAllocator[1].initialize(kDrawCallMemory);
|
2021-12-09 12:38:41 +01:00
|
|
|
_debugRectsEnabled = false;
|
2014-08-06 21:50:49 +02:00
|
|
|
|
2021-12-06 13:57:41 +01:00
|
|
|
TinyGL::Internal::tglBlitResetScissorRect();
|
|
|
|
}
|
|
|
|
|
|
|
|
void destroyContext() {
|
|
|
|
GLContext *c = gl_get_context();
|
|
|
|
assert(c);
|
|
|
|
c->deinit();
|
|
|
|
delete c;
|
|
|
|
gl_ctx = nullptr;
|
2005-01-12 15:20:02 +00:00
|
|
|
}
|
|
|
|
|
2021-12-06 13:57:41 +01:00
|
|
|
void GLContext::deinit() {
|
2021-12-07 00:58:14 +01:00
|
|
|
disposeDrawCallLists();
|
|
|
|
disposeResources();
|
2016-07-17 14:28:06 +00:00
|
|
|
|
2021-12-07 00:58:14 +01:00
|
|
|
specbuf_cleanup();
|
2012-04-21 12:18:42 +02:00
|
|
|
for (int i = 0; i < 3; i++)
|
2021-12-07 00:58:14 +01:00
|
|
|
gl_free(matrix_stack[i]);
|
|
|
|
endSharedState();
|
|
|
|
gl_free(vertex);
|
2005-01-12 15:20:02 +00:00
|
|
|
}
|
2009-05-25 13:19:29 +00:00
|
|
|
|
|
|
|
} // end of namespace TinyGL
|