source: trunk/src/shader.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.

File size: 3.5 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/*
27 * Shader implementation class
28 */
29
30class ShaderData
31{
32    friend class Shader;
33
34private:
35#if defined HAVE_GL_2X || defined HAVE_GLES_2X
36    GLuint prog_id, vert_id, frag_id;
37#endif
38    uint32_t vert_crc, frag_crc;
39
40    /* Global shader cache */
41    static Shader *shaders[];
42    static int nshaders;
43};
44
45Shader *ShaderData::shaders[256];
46int ShaderData::nshaders = 0;
47
48/*
49 * Public Shader class
50 */
51
52Shader *Shader::Create(char const *vert, char const *frag)
53{
54    uint32_t new_vert_crc = Hash::Crc32(vert);
55    uint32_t new_frag_crc = Hash::Crc32(frag);
56
57    for (int n = 0; n < ShaderData::nshaders; n++)
58    {
59        if (ShaderData::shaders[n]->data->vert_crc == new_vert_crc
60             && ShaderData::shaders[n]->data->frag_crc == new_frag_crc)
61            return ShaderData::shaders[n];
62    }
63
64    Shader *ret = new Shader(vert, frag);
65    ShaderData::shaders[ShaderData::nshaders] = ret;
66    ShaderData::nshaders++;
67    return ret;
68}
69
70void Shader::Destroy(Shader *shader)
71{
72    /* XXX: do nothing! the shader should remain in cache */
73    (void)shader;
74}
75
76Shader::Shader(char const *vert, char const *frag)
77  : data(new ShaderData())
78{
79#if defined HAVE_GL_2X || defined HAVE_GLES_2X
80    char buf[4096];
81    GLsizei len;
82#endif
83
84    data->vert_crc = Hash::Crc32(vert);
85#if defined HAVE_GL_2X || defined HAVE_GLES_2X
86    data->vert_id = glCreateShader(GL_VERTEX_SHADER);
87    glShaderSource(data->vert_id, 1, &vert, NULL);
88    glCompileShader(data->vert_id);
89
90    glGetShaderInfoLog(data->vert_id, sizeof(buf), &len, buf);
91    if (len > 0)
92        fprintf(stderr, "ERROR: failed to compile vertex shader: %s", buf);
93#endif
94
95    data->frag_crc = Hash::Crc32(frag);
96#if defined HAVE_GL_2X || defined HAVE_GLES_2X
97    data->frag_id = glCreateShader(GL_FRAGMENT_SHADER);
98    glShaderSource(data->frag_id, 1, &frag, NULL);
99    glCompileShader(data->frag_id);
100
101    glGetShaderInfoLog(data->frag_id, sizeof(buf), &len, buf);
102    if (len > 0)
103        fprintf(stderr, "ERROR: failed to compile fragment shader: %s", buf);
104
105    data->prog_id = glCreateProgram();
106    glAttachShader(data->prog_id, data->vert_id);
107    glAttachShader(data->prog_id, data->frag_id);
108
109    glLinkProgram(data->prog_id);
110    glValidateProgram(data->prog_id);
111#endif
112}
113
114int Shader::GetAttribLocation(char const *attr) const
115{
116#if defined HAVE_GL_2X || defined HAVE_GLES_2X
117    return glGetAttribLocation(data->prog_id, attr);
118#else
119    (void)attr;
120    return -1;
121#endif
122}
123
124int Shader::GetUniformLocation(char const *uni) const
125{
126#if defined HAVE_GL_2X || defined HAVE_GLES_2X
127    return glGetUniformLocation(data->prog_id, uni);
128#else
129    (void)uni;
130    return -1;
131#endif
132}
133
134void Shader::Bind() const
135{
136#if defined HAVE_GL_2X || defined HAVE_GLES_2X
137    glUseProgram(data->prog_id);
138#endif
139}
140
141Shader::~Shader()
142{
143#if defined HAVE_GL_2X || defined HAVE_GLES_2X
144    glDetachShader(data->prog_id, data->vert_id);
145    glDetachShader(data->prog_id, data->frag_id);
146    glDeleteShader(data->vert_id);
147    glDeleteShader(data->frag_id);
148    glDeleteProgram(data->prog_id);
149#endif
150    delete data;
151}
152
Note: See TracBrowser for help on using the repository browser.