1 /*
2 * Copyright (c) 2007-2013 Scott Lembcke and Howling Moon Software
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */22 moduledemo.ChipmunkDemoShaderSupport;
23 24 importcore.stdc.stdlib;
25 26 importstd.conv;
27 importstd.stdio;
28 importstd.string;
29 30 importdemo.dchip;
31 32 importglad.gl.all;
33 importglad.gl.loader;
34 35 stringSET_ATTRIBUTE(stringprogram, stringtype, stringname, stringgltype)
36 {
37 returnq{38 SetAttribute(program, "%1$s", %2$s.%1$s.sizeof / GLfloat.sizeof, %3$s, %2$s.sizeof, cast(GLvoid *)%2$s.%1$s.offsetof);
39 }.format(name, type, gltype);
40 }
41 42 /// Converts an OpenGL errorenum to a string43 stringtoString(GLenumerror)
44 {
45 switch (error)
46 {
47 caseGL_INVALID_ENUM:
48 return"An unacceptable value is specified for an enumerated argument.";
49 50 caseGL_INVALID_VALUE:
51 return"A numeric argument is out of range.";
52 53 caseGL_INVALID_OPERATION:
54 return"The specified operation is not allowed in the current state.";
55 56 caseGL_INVALID_FRAMEBUFFER_OPERATION:
57 return"The framebuffer object is not complete.";
58 59 caseGL_OUT_OF_MEMORY:
60 return"There is not enough memory left to execute the command. WARNING: GL operation is undefined.";
61 62 caseGL_STACK_UNDERFLOW:
63 return"An attempt has been made to perform an operation that would cause an internal stack to underflow.";
64 65 caseGL_STACK_OVERFLOW:
66 return"An attempt has been made to perform an operation that would cause an internal stack to overflow.";
67 68 default:
69 assert(0, format("Unhandled GLenum error state: '%s'", error));
70 }
71 }
72 73 voidCheckGLErrors()
74 {
75 for (GLenumerr = glGetError(); err; err = glGetError())
76 {
77 if (err)
78 {
79 stderr.writefln("Error: - %s", err.toString());
80 stderr.writefln("GLError(%s:%d) 0x%04X\n", __FILE__, __LINE__, err);
81 assert(0);
82 }
83 }
84 }
85 86 aliasPFNGLGETSHADERIVPROC = fp_glGetShaderiv;
87 aliasPFNGLGETSHADERINFOLOGPROC = fp_glGetProgramInfoLog;
88 89 //typedef GLAPIENTRY void (*GETIV)(GLuint shader, GLenum pname, GLint *params);90 //typedef GLAPIENTRY void (*GETINFOLOG)(GLuint shader, GLsizei maxLength, GLsizei *length, GLchar *infoLog);91 92 staticcpBoolCheckError(GLintobj, GLenumstatus, PFNGLGETSHADERIVPROCgetiv, PFNGLGETSHADERINFOLOGPROCgetInfoLog)
93 {
94 GLintsuccess;
95 getiv(obj, status, &success);
96 97 if (!success)
98 {
99 GLintlength;
100 getiv(obj, GL_INFO_LOG_LENGTH, &length);
101 102 char* log = cast(char*)alloca(length);
103 getInfoLog(obj, length, null, log);
104 105 stderr.writefln("Shader compile error for 0x%04X: %s\n", status, log.to!string);
106 returncpFalse;
107 }
108 else109 {
110 returncpTrue;
111 }
112 }
113 114 GLintCompileShader(GLenumtype, stringsource)
115 {
116 GLintshader = glCreateShader(type);
117 118 autossp = source.ptr;
119 intssl = cast(int)(source.length);
120 glShaderSource(shader, 1, &ssp, &ssl);
121 glCompileShader(shader);
122 123 // TODO return placeholder shader instead?124 cpAssertHard(CheckError(shader, GL_COMPILE_STATUS, glGetShaderiv, glGetShaderInfoLog), "Error compiling shader");
125 126 returnshader;
127 }
128 129 GLintLinkProgram(GLintvshader, GLintfshader)
130 {
131 GLintprogram = glCreateProgram();
132 133 glAttachShader(program, vshader);
134 glAttachShader(program, fshader);
135 glLinkProgram(program);
136 137 // todo return placeholder program instead?138 cpAssertHard(CheckError(program, GL_LINK_STATUS, glGetProgramiv, glGetProgramInfoLog), "Error linking shader program");
139 140 returnprogram;
141 }
142 143 cpBoolValidateProgram(GLintprogram)
144 {
145 // TODO146 returncpTrue;
147 }
148 149 voidSetAttribute(GLuintprogram, stringname, GLintsize, GLenumgltype, GLsizeistride, GLvoid* offset)
150 {
151 GLintindex = glGetAttribLocation(program, name.toStringz);
152 glEnableVertexAttribArray(index);
153 glVertexAttribPointer(index, size, gltype, GL_FALSE, stride, offset);
154 }