source: trunk/src/shader.cpp @ 745

Last change on this file since 745 was 745, checked in by sam, 10 years ago

video: enforce shader-enabled GL implementations, getting rid of a lot
of code.

File size: 3.0 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
17#ifdef WIN32
18#   define WIN32_LEAN_AND_MEAN
19#   include <windows.h>
20#endif
21
22#include "core.h"
23#include "lolgl.h"
24
25namespace lol
26{
27
28/*
29 * Shader implementation class
30 */
31
32class ShaderData
33{
34    friend class Shader;
35
36private:
37    GLuint prog_id, vert_id, frag_id;
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    char buf[4096];
80    GLsizei len;
81
82    data->vert_crc = Hash::Crc32(vert);
83    data->vert_id = glCreateShader(GL_VERTEX_SHADER);
84    glShaderSource(data->vert_id, 1, &vert, NULL);
85    glCompileShader(data->vert_id);
86
87    glGetShaderInfoLog(data->vert_id, sizeof(buf), &len, buf);
88    if (len > 0)
89        Log::Error("failed to compile vertex shader: %s", buf);
90
91    data->frag_crc = Hash::Crc32(frag);
92    data->frag_id = glCreateShader(GL_FRAGMENT_SHADER);
93    glShaderSource(data->frag_id, 1, &frag, NULL);
94    glCompileShader(data->frag_id);
95
96    glGetShaderInfoLog(data->frag_id, sizeof(buf), &len, buf);
97    if (len > 0)
98        Log::Error("failed to compile fragment shader: %s", buf);
99
100    data->prog_id = glCreateProgram();
101    glAttachShader(data->prog_id, data->vert_id);
102    glAttachShader(data->prog_id, data->frag_id);
103
104    glLinkProgram(data->prog_id);
105    glValidateProgram(data->prog_id);
106}
107
108int Shader::GetAttribLocation(char const *attr) const
109{
110    return glGetAttribLocation(data->prog_id, attr);
111}
112
113int Shader::GetUniformLocation(char const *uni) const
114{
115    return glGetUniformLocation(data->prog_id, uni);
116}
117
118void Shader::Bind() const
119{
120    glUseProgram(data->prog_id);
121}
122
123Shader::~Shader()
124{
125    glDetachShader(data->prog_id, data->vert_id);
126    glDetachShader(data->prog_id, data->frag_id);
127    glDeleteShader(data->vert_id);
128    glDeleteShader(data->frag_id);
129    glDeleteProgram(data->prog_id);
130    delete data;
131}
132
133} /* namespace lol */
134
Note: See TracBrowser for help on using the repository browser.