source: trunk/src/gpu/texture.cpp @ 1987

Last change on this file since 1987 was 1987, checked in by sam, 7 years ago

gpu: put the texture creation code in its own class; for now a lot of things are
hardcoded and only the fractal demo uses it, but everything will eventually switch.

  • Property svn:keywords set to Id
File size: 4.5 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2012 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 "core.h"
16#include "lolgl.h"
17
18#if defined _WIN32 && defined USE_D3D9
19#   define FAR
20#   define NEAR
21#   include <d3d9.h>
22#endif
23
24using namespace std;
25
26#if defined USE_D3D9
27extern IDirect3DDevice9 *g_d3ddevice;
28#elif defined _XBOX
29extern D3DDevice *g_d3ddevice;
30#endif
31
32namespace lol
33{
34
35//
36// The TextureData class
37// ---------------------
38//
39
40class TextureData
41{
42    friend class Texture;
43
44    ivec2 m_size;
45
46#if defined USE_D3D9
47    IDirect3DTexture9 *m_tex;
48#elif defined _XBOX
49    D3DTexture *m_tex;
50#else
51    GLuint m_texid;
52#endif
53};
54
55//
56// The Texture class
57// -----------------
58//
59
60/* FIXME: this is all hardcoded over the place */
61#if __CELLOS_LV2__
62static GLint const INTERNAL_FORMAT = GL_ARGB_SCE;
63static GLenum const TEXTURE_FORMAT = GL_BGRA;
64static GLenum const TEXTURE_TYPE = GL_UNSIGNED_INT_8_8_8_8_REV;
65#elif defined __native_client__ || defined HAVE_GLES_2X
66static GLint const INTERNAL_FORMAT = GL_RGBA;
67static GLenum const TEXTURE_FORMAT = GL_RGBA;
68static GLenum const TEXTURE_TYPE = GL_UNSIGNED_BYTE;
69#else
70/* Seems efficient for little endian textures */
71static GLint const INTERNAL_FORMAT = GL_RGBA;
72static GLenum const TEXTURE_FORMAT = GL_BGRA;
73static GLenum const TEXTURE_TYPE = GL_UNSIGNED_INT_8_8_8_8_REV;
74#endif
75
76Texture::Texture(ivec2 size)
77  : m_data(new TextureData)
78{
79    m_data->m_size = size;
80
81#if defined USE_D3D9
82    g_d3ddevice->CreateTexture(m_data->m_size.x, m_data->m_size.y, 1,
83                               D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8,
84                               D3DPOOL_SYSTEMMEM, &m_tex, NULL);
85#elif defined _XBOX
86    /* By default the X360 will swizzle the texture. Ask for linear. */
87    g_d3ddevice->CreateTexture(m_data->m_size.x, m_data->m_size.y, 1,
88                               D3DUSAGE_WRITEONLY, D3DFMT_LIN_A8R8G8B8,
89                               D3DPOOL_DEFAULT, &m_tex, NULL);
90#else
91    glGenTextures(1, &m_data->m_texid);
92    glBindTexture(GL_TEXTURE_2D, m_data->m_texid);
93
94#   if defined __CELLOS_LV2__
95    /* We need this hint because by default the storage type is
96     * GL_TEXTURE_SWIZZLED_GPU_SCE. */
97    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_ALLOCATION_HINT_SCE,
98                    GL_TEXTURE_TILED_GPU_SCE);
99#   endif
100    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
101    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
102#endif
103}
104
105void Texture::Bind()
106{
107#if defined _XBOX || defined USE_D3D9
108    g_d3ddevice->SetTexture(0, m_data->m_tex);
109#else
110#   if !defined HAVE_GLES_2X
111    glEnable(GL_TEXTURE_2D);
112#   endif
113    glBindTexture(GL_TEXTURE_2D, m_data->m_texid);
114#endif
115}
116
117void Texture::SetData(void *data)
118{
119#if defined _XBOX || defined USE_D3D9
120    D3DLOCKED_RECT rect;
121#   if defined _XBOX
122    m_data->m_tex->LockRect(0, &rect, NULL, D3DLOCK_NOOVERWRITE);
123#   else
124    m_data->m_tex->LockRect(0, &rect, NULL,
125                            D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE);
126#   endif
127    memcpy(rect.pBits, data, rect.Pitch * rect.Height);
128
129    m_data->m_tex->UnlockRect(0);
130
131#else
132    glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT,
133                 m_data->m_size.x, m_data->m_size.y, 0,
134                 TEXTURE_FORMAT, TEXTURE_TYPE, data);
135#endif
136}
137
138void Texture::SetSubData(ivec2 origin, ivec2 size, void *data)
139{
140#if defined _XBOX || defined USE_D3D9
141    D3DLOCKED_RECT rect;
142#   if defined _XBOX
143    m_data->m_tex->LockRect(0, &rect, NULL, D3DLOCK_NOOVERWRITE);
144#   else
145    m_data->m_tex->LockRect(0, &rect, NULL,
146                            D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE);
147#   endif
148    for (int j = 0; j < size.y; j++)
149    {
150        uint8_t *dst = (uint8_t *)rect.pBits + (origin.y + j) * rect.Pitch;
151        /* FIXME: the source or destination pitch isn't necessarily 4! */
152        uint8_t *src = (uint8_t *)data + j * size.y * 4;
153        memcpy(dst, src, size.y * 4);
154    }
155
156    m_data->m_tex->UnlockRect(0);
157
158#else
159    glTexSubImage2D(GL_TEXTURE_2D, 0, origin.x, origin.y, size.x, size.y,
160                    TEXTURE_FORMAT, TEXTURE_TYPE, data);
161#endif
162}
163
164Texture::~Texture()
165{
166#if defined USE_D3D9 || defined _XBOX
167    m_data->m_tex->Release();
168#else
169    glDeleteTextures(1, &m_data->m_texid);
170#endif
171
172    delete m_data;
173}
174
175} /* namespace lol */
176
Note: See TracBrowser for help on using the repository browser.