summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Fonseca <jose.r.fonseca@gmail.com>2011-05-19 10:45:04 +0100
committerJosé Fonseca <jose.r.fonseca@gmail.com>2011-05-19 10:45:04 +0100
commit2e3fff6025fac330cbf00c8b81766dcbcf6298b5 (patch)
treed36d056a1143eb24b01cd45319ae59a394422525
parenta4d77a9074af5290b0dbbb7fddd99b981f59bc8a (diff)
Reorganize glstate code.
-rw-r--r--.gitignore2
-rwxr-xr-xCMakeLists.txt5
-rw-r--r--glretrace_main.cpp2
-rw-r--r--glstate.cpp643
-rw-r--r--glstate.hpp15
-rw-r--r--glstate.py629
6 files changed, 673 insertions, 623 deletions
diff --git a/.gitignore b/.gitignore
index 56809775..5b141147 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,7 +35,7 @@ dxsdk
glproc.hpp
glretrace
glretrace_gl.cpp
-glstate.cpp
+glstate_params.cpp
glxtrace.cpp
install_manifest.txt
qapitrace
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 41bbd6d9..44b4c84a 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -306,8 +306,8 @@ add_custom_command (
)
add_custom_command (
- OUTPUT glstate.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glstate.py > ${CMAKE_CURRENT_BINARY_DIR}/glstate.cpp
+ OUTPUT glstate_params.cpp
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glstate.py > ${CMAKE_CURRENT_BINARY_DIR}/glstate_params.cpp
DEPENDS glstate.py glparams.py gltypes.py stdapi.py
)
@@ -323,6 +323,7 @@ add_executable (glretrace
glretrace_wgl.cpp
glretrace_main.cpp
glstate.cpp
+ glstate_params.cpp
retrace.cpp
${glws}
image.cpp
diff --git a/glretrace_main.cpp b/glretrace_main.cpp
index bfab151f..56113efc 100644
--- a/glretrace_main.cpp
+++ b/glretrace_main.cpp
@@ -203,7 +203,7 @@ static void display(void) {
if (!insideGlBeginEnd &&
drawable && context &&
call->no >= dump_state) {
- glstate::state_dump(std::cout);
+ glstate::dumpCurrentContext(std::cout);
exit(0);
}
diff --git a/glstate.cpp b/glstate.cpp
new file mode 100644
index 00000000..a60c6876
--- /dev/null
+++ b/glstate.cpp
@@ -0,0 +1,643 @@
+/**************************************************************************
+ *
+ * Copyright 2011 Jose Fonseca
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include <string.h>
+#include <iostream>
+#include <algorithm>
+
+#include "image.hpp"
+#include "json.hpp"
+#include "glproc.hpp"
+#include "glsize.hpp"
+#include "glstate.hpp"
+
+
+namespace glstate {
+
+
+static void
+dumpShader(JSONWriter &json, GLuint shader)
+{
+ if (!shader) {
+ return;
+ }
+
+ GLint shader_type = 0;
+ glGetShaderiv(shader, GL_SHADER_TYPE, &shader_type);
+ if (!shader_type) {
+ return;
+ }
+
+ GLint source_length = 0;
+ glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &source_length);
+ if (!source_length) {
+ return;
+ }
+
+ GLchar *source = new GLchar[source_length];
+ GLsizei length = 0;
+ source[0] = 0;
+ glGetShaderSource(shader, source_length, &length, source);
+
+ json.beginMember(enumToString(shader_type));
+ json.writeString(source);
+ json.endMember();
+
+ delete [] source;
+}
+
+
+static void
+dumpShaderObj(JSONWriter &json, GLhandleARB shaderObj)
+{
+ if (!shaderObj) {
+ return;
+ }
+
+ GLint shader_type = 0;
+ glGetObjectParameterivARB(shaderObj, GL_OBJECT_TYPE_ARB, &shader_type);
+ if (!shader_type) {
+ return;
+ }
+
+ GLint source_length = 0;
+ glGetObjectParameterivARB(shaderObj, GL_OBJECT_SHADER_SOURCE_LENGTH_ARB, &source_length);
+ if (!source_length) {
+ return;
+ }
+
+ GLcharARB *source = new GLcharARB[source_length];
+ GLsizei length = 0;
+ source[0] = 0;
+ glGetShaderSource(shaderObj, source_length, &length, source);
+
+ json.beginMember(enumToString(shader_type));
+ json.writeString(source);
+ json.endMember();
+
+ delete [] source;
+}
+
+
+static inline void
+dumpCurrentProgram(JSONWriter &json)
+{
+ GLint program = 0;
+ glGetIntegerv(GL_CURRENT_PROGRAM, &program);
+ if (!program) {
+ return;
+ }
+
+ GLint attached_shaders = 0;
+ glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
+ if (!attached_shaders) {
+ return;
+ }
+
+ GLuint *shaders = new GLuint[attached_shaders];
+ GLsizei count = 0;
+ glGetAttachedShaders(program, attached_shaders, &count, shaders);
+ for (GLsizei i = 0; i < count; ++ i) {
+ dumpShader(json, shaders[i]);
+ }
+ delete [] shaders;
+}
+
+
+static inline void
+dumpCurrentProgramObj(JSONWriter &json)
+{
+ GLhandleARB programObj = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
+ if (!programObj) {
+ return;
+ }
+
+ GLint attached_shaders = 0;
+ glGetProgramivARB(programObj, GL_OBJECT_ATTACHED_OBJECTS_ARB, &attached_shaders);
+ if (!attached_shaders) {
+ return;
+ }
+
+ GLhandleARB *shaderObjs = new GLhandleARB[attached_shaders];
+ GLsizei count = 0;
+ glGetAttachedObjectsARB(programObj, attached_shaders, &count, shaderObjs);
+ for (GLsizei i = 0; i < count; ++ i) {
+ dumpShaderObj(json, shaderObjs[i]);
+ }
+ delete [] shaderObjs;
+}
+
+
+static inline void
+dumpArbProgram(JSONWriter &json, GLenum target)
+{
+ if (!glIsEnabled(target)) {
+ return;
+ }
+
+ GLint program_length = 0;
+ glGetProgramivARB(target, GL_PROGRAM_LENGTH_ARB, &program_length);
+ if (!program_length) {
+ return;
+ }
+
+ GLchar *source = new GLchar[program_length + 1];
+ source[0] = 0;
+ glGetProgramStringARB(target, GL_PROGRAM_STRING_ARB, source);
+ source[program_length] = 0;
+
+ json.beginMember(enumToString(target));
+ json.writeString(source);
+ json.endMember();
+
+ delete [] source;
+}
+
+
+static inline void
+dumpShaders(JSONWriter &json)
+{
+ json.beginMember("shaders");
+ json.beginObject();
+ dumpCurrentProgram(json);
+ dumpArbProgram(json, GL_FRAGMENT_PROGRAM_ARB);
+ dumpArbProgram(json, GL_VERTEX_PROGRAM_ARB);
+ json.endObject();
+ json.endMember(); //shaders
+}
+
+
+static inline void
+dumpTextureImage(JSONWriter &json, GLenum target, GLint level)
+{
+ GLint width, height = 1, depth = 1;
+
+ width = 0;
+ glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
+
+ if (target != GL_TEXTURE_1D) {
+ height = 0;
+ glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
+ if (target == GL_TEXTURE_3D) {
+ depth = 0;
+ glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth);
+ }
+ }
+
+ if (width <= 0 || height <= 0 || depth <= 0) {
+ return;
+ } else {
+ char label[512];
+
+ GLint active_texture = GL_TEXTURE0;
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
+ snprintf(label, sizeof label, "%s, %s, level = %i", enumToString(active_texture), enumToString(target), level);
+
+ json.beginMember(label);
+
+ json.beginObject();
+
+ // Tell the GUI this is no ordinary object, but an image
+ json.writeStringMember("__class__", "image");
+
+ json.writeNumberMember("__width__", width);
+ json.writeNumberMember("__height__", height);
+ json.writeNumberMember("__depth__", depth);
+
+ // Hardcoded for now, but we could chose types more adequate to the
+ // texture internal format
+ json.writeStringMember("__type__", "uint8");
+ json.writeBoolMember("__normalized__", true);
+ json.writeNumberMember("__channels__", 4);
+
+ GLubyte *pixels = new GLubyte[depth*width*height*4];
+
+ glGetTexImage(target, level, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ json.beginMember("__data__");
+ char *pngBuffer;
+ int pngBufferSize;
+ Image::writePixelsToBuffer(pixels, width, height, 4, false, &pngBuffer, &pngBufferSize);
+ json.writeBase64(pngBuffer, pngBufferSize);
+ free(pngBuffer);
+ json.endMember(); // __data__
+
+ delete [] pixels;
+ json.endObject();
+ }
+}
+
+
+static inline void
+dumpTexture(JSONWriter &json, GLenum target, GLenum binding)
+{
+ GLint texture_binding = 0;
+ glGetIntegerv(binding, &texture_binding);
+ if (!glIsEnabled(target) && !texture_binding) {
+ return;
+ }
+
+ GLint level = 0;
+ do {
+ GLint width = 0, height = 0;
+ glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
+ glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
+ if (!width || !height) {
+ break;
+ }
+
+ if (target == GL_TEXTURE_CUBE_MAP) {
+ for (int face = 0; face < 6; ++face) {
+ dumpTextureImage(json, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level);
+ }
+ } else {
+ dumpTextureImage(json, target, level);
+ }
+
+ ++level;
+ } while(true);
+}
+
+
+static inline void
+dumpTextures(JSONWriter &json)
+{
+ json.beginMember("textures");
+ json.beginObject();
+ GLint active_texture = GL_TEXTURE0;
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
+ GLint max_texture_coords = 0;
+ glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);
+ GLint max_combined_texture_image_units = 0;
+ glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_combined_texture_image_units);
+ GLint max_units = std::max(max_combined_texture_image_units, max_texture_coords);
+ for (GLint unit = 0; unit < max_units; ++unit) {
+ GLenum texture = GL_TEXTURE0 + unit;
+ glActiveTexture(texture);
+ dumpTexture(json, GL_TEXTURE_1D, GL_TEXTURE_BINDING_1D);
+ dumpTexture(json, GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D);
+ dumpTexture(json, GL_TEXTURE_3D, GL_TEXTURE_BINDING_3D);
+ dumpTexture(json, GL_TEXTURE_RECTANGLE, GL_TEXTURE_BINDING_RECTANGLE);
+ dumpTexture(json, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BINDING_CUBE_MAP);
+ }
+ glActiveTexture(active_texture);
+ json.endObject();
+ json.endMember(); // textures
+}
+
+
+static bool
+getDrawableBounds(GLint *width, GLint *height) {
+#if defined(_WIN32)
+
+ HDC hDC = wglGetCurrentDC();
+ if (!hDC) {
+ return false;
+ }
+
+ HWND hWnd = WindowFromDC(hDC);
+ RECT rect;
+
+ if (!GetClientRect(hWnd, &rect)) {
+ return false;
+ }
+
+ *width = rect.right - rect.left;
+ *height = rect.bottom - rect.top;
+
+#elif 0 /* __APPLE__ */
+
+ CGLError CGLGetSurface(CGLContextObj, CGSConnectionID*, CGSWindowID*, CGSSurfaceID*);
+ CGError CGSGetWindowBounds(CGSConnectionID, CGWindowID, CGRect *ret);
+
+#else
+
+ Display *display;
+ Drawable drawable;
+ Window root;
+ int x, y;
+ unsigned int w, h, bw, depth;
+
+ display = glXGetCurrentDisplay();
+ if (!display) {
+ return false;
+ }
+
+ drawable = glXGetCurrentDrawable();
+ if (drawable == None) {
+ return false;
+ }
+
+ if (!XGetGeometry(display, drawable, &root, &x, &y, &w, &h, &bw, &depth)) {
+ return false;
+ }
+
+ *width = w;
+ *height = h;
+
+#endif
+
+ return true;
+}
+
+
+static inline void
+dumpDrawBufferImage(JSONWriter &json, GLenum format)
+{
+ GLint channels = __gl_format_channels(format);
+
+ GLint width, height;
+
+ if (!getDrawableBounds(&width, &height)) {
+ json.writeNull();
+ } else {
+ json.beginObject();
+
+ // Tell the GUI this is no ordinary object, but an image
+ json.writeStringMember("__class__", "image");
+
+ json.writeNumberMember("__width__", width);
+ json.writeNumberMember("__height__", height);
+ json.writeNumberMember("__depth__", 1);
+
+ // Hardcoded for now, but we could chose types more adequate to the
+ // texture internal format
+ json.writeStringMember("__type__", "uint8");
+ json.writeBoolMember("__normalized__", true);
+ json.writeNumberMember("__channels__", channels);
+
+ GLubyte *pixels = new GLubyte[width*height*channels];
+
+ GLint drawbuffer = GL_NONE;
+ GLint readbuffer = GL_NONE;
+ glGetIntegerv(GL_DRAW_BUFFER, &drawbuffer);
+ glGetIntegerv(GL_READ_BUFFER, &readbuffer);
+ glReadBuffer(drawbuffer);
+
+ glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
+ glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+ glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, pixels);
+
+ glPopClientAttrib();
+ glReadBuffer(readbuffer);
+
+ json.beginMember("__data__");
+ char *pngBuffer;
+ int pngBufferSize;
+ Image::writePixelsToBuffer(pixels, width, height, channels, false, &pngBuffer, &pngBufferSize);
+ //std::cerr <<" Before = "<<(width * height * channels * sizeof *pixels)
+ // <<", after = "<<pngBufferSize << ", ratio = " << double(width * height * channels * sizeof *pixels)/pngBufferSize;
+ json.writeBase64(pngBuffer, pngBufferSize);
+ free(pngBuffer);
+ json.endMember(); // __data__
+
+ delete [] pixels;
+ json.endObject();
+ }
+}
+
+
+static inline GLuint
+downsampledFramebuffer(GLuint oldFbo, GLint drawbuffer,
+ GLint colorRb, GLint depthRb, GLint stencilRb,
+ GLuint *rbs, GLint *numRbs)
+{
+ GLuint fbo;
+ GLint format;
+ GLint w, h;
+
+ *numRbs = 0;
+
+ glGenFramebuffers(1, &fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, colorRb);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_WIDTH, &w);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_HEIGHT, &h);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
+
+ glGenRenderbuffers(1, &rbs[*numRbs]);
+ glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
+ glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, drawbuffer,
+ GL_RENDERBUFFER, rbs[*numRbs]);
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
+ glDrawBuffer(drawbuffer);
+ glReadBuffer(drawbuffer);
+ glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ ++*numRbs;
+
+ if (stencilRb == depthRb && stencilRb) {
+ //combined depth and stencil buffer
+ glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_WIDTH, &w);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_HEIGHT, &h);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
+
+ glGenRenderbuffers(1, &rbs[*numRbs]);
+ glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
+ glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, rbs[*numRbs]);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
+ glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
+ GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ ++*numRbs;
+ } else {
+ if (depthRb) {
+ glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_WIDTH, &w);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_HEIGHT, &h);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
+
+ glGenRenderbuffers(1, &rbs[*numRbs]);
+ glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
+ glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, rbs[*numRbs]);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
+ glDrawBuffer(GL_DEPTH_ATTACHMENT);
+ glReadBuffer(GL_DEPTH_ATTACHMENT);
+ glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
+ GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ ++*numRbs;
+ }
+ if (stencilRb) {
+ glBindRenderbuffer(GL_RENDERBUFFER, stencilRb);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_WIDTH, &w);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_HEIGHT, &h);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
+
+ glGenRenderbuffers(1, &rbs[*numRbs]);
+ glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
+ glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+ GL_STENCIL_ATTACHMENT,
+ GL_RENDERBUFFER, rbs[*numRbs]);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
+ glDrawBuffer(GL_STENCIL_ATTACHMENT);
+ glReadBuffer(GL_STENCIL_ATTACHMENT);
+ glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
+ GL_STENCIL_BUFFER_BIT, GL_NEAREST);
+ ++*numRbs;
+ }
+ }
+
+ return fbo;
+}
+
+
+static void
+dumpDrawBuffers(JSONWriter &json, GLboolean dumpDepth, GLboolean dumpStencil)
+{
+ json.beginMember("GL_RGBA");
+ dumpDrawBufferImage(json, GL_RGBA);
+ json.endMember();
+
+ if (dumpDepth) {
+ json.beginMember("GL_DEPTH_COMPONENT");
+ dumpDrawBufferImage(json, GL_DEPTH_COMPONENT);
+ json.endMember();
+ }
+
+ if (dumpStencil) {
+ json.beginMember("GL_STENCIL_INDEX");
+ dumpDrawBufferImage(json, GL_STENCIL_INDEX);
+ json.endMember();
+ }
+}
+
+
+static void
+dumpFramebuffer(JSONWriter &json)
+{
+ json.beginMember("framebuffer");
+ json.beginObject();
+
+ GLint boundDrawFbo = 0, boundReadFbo = 0;
+ glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundDrawFbo);
+ glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundReadFbo);
+ if (!boundDrawFbo) {
+ GLint depth_bits = 0;
+ glGetIntegerv(GL_DEPTH_BITS, &depth_bits);
+ GLint stencil_bits = 0;
+ glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
+ dumpDrawBuffers(json, depth_bits, stencil_bits);
+ } else {
+ GLint colorRb, stencilRb, depthRb;
+ GLint boundRb;
+ glGetIntegerv(GL_RENDERBUFFER_BINDING, &boundRb);
+ GLint drawbuffer = GL_NONE;
+ glGetIntegerv(GL_DRAW_BUFFER, &drawbuffer);
+
+ glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
+ drawbuffer,
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
+ &colorRb);
+ glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
+ &depthRb);
+ glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
+ GL_STENCIL_ATTACHMENT,
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
+ &stencilRb);
+
+ GLint colorSamples, depthSamples, stencilSamples;
+ GLuint rbs[3];
+ GLint numRbs = 0;
+ GLuint fboCopy = 0;
+ glBindRenderbuffer(GL_RENDERBUFFER, colorRb);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_SAMPLES, &colorSamples);
+ glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_SAMPLES, &depthSamples);
+ glBindRenderbuffer(GL_RENDERBUFFER, stencilRb);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER,
+ GL_RENDERBUFFER_SAMPLES, &stencilSamples);
+ glBindRenderbuffer(GL_RENDERBUFFER, boundRb);
+
+ if (colorSamples || depthSamples || stencilSamples) {
+ //glReadPixels doesnt support multisampled buffers so we need
+ // to blit the fbo to a temporary one
+ fboCopy = downsampledFramebuffer(boundDrawFbo, drawbuffer,
+ colorRb, depthRb, stencilRb,
+ rbs, &numRbs);
+ }
+ glDrawBuffer(drawbuffer);
+ glReadBuffer(drawbuffer);
+
+ dumpDrawBuffers(json, depthRb, stencilRb);
+
+ if (fboCopy) {
+ glBindFramebuffer(GL_FRAMEBUFFER, boundDrawFbo);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, boundReadFbo);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, boundDrawFbo);
+ glBindRenderbuffer(GL_RENDERBUFFER_BINDING, boundRb);
+ glDeleteRenderbuffers(numRbs, rbs);
+ glDeleteFramebuffers(1, &fboCopy);
+ }
+ }
+
+ json.endObject();
+ json.endMember(); // framebuffer
+}
+
+
+void dumpCurrentContext(std::ostream &os)
+{
+ JSONWriter json(os);
+ dumpParameters(json);
+ dumpShaders(json);
+ dumpTextures(json);
+ dumpFramebuffer(json);
+}
+
+
+} /* namespace glstate */
diff --git a/glstate.hpp b/glstate.hpp
index 13426290..abbfad00 100644
--- a/glstate.hpp
+++ b/glstate.hpp
@@ -29,14 +29,25 @@
#include <ostream>
+#include "glimports.hpp"
+
+
+class JSONWriter;
+
namespace glstate {
-void state_dump(std::ostream &os);
+const char *enumToString(GLenum pname);
+
+void dumpEnum(JSONWriter &json, GLenum pname);
+
+void dumpParameters(JSONWriter &json);
+
+void dumpCurrentContext(std::ostream &os);
-} /* namespace glretrace */
+} /* namespace glstate */
#endif /* _GLSTATE_HPP_ */
diff --git a/glstate.py b/glstate.py
index 859b3df1..38084151 100644
--- a/glstate.py
+++ b/glstate.py
@@ -197,7 +197,7 @@ class JsonWriter(Visitor):
def visit_enum(self, enum, instance):
if enum.expr == 'GLenum':
- print ' writeEnum(json, %s);' % instance
+ print ' dumpEnum(json, %s);' % instance
else:
print ' json.writeNumber(%s);' % instance
@@ -232,19 +232,17 @@ class StateDumper:
def dump(self):
print '#include <string.h>'
- print '#include <iostream>'
- print '#include <algorithm>'
print
- print '#include "image.hpp"'
print '#include "json.hpp"'
- print '#include "glimports.hpp"'
print '#include "glproc.hpp"'
print '#include "glsize.hpp"'
print '#include "glstate.hpp"'
print
+ print 'namespace glstate {'
+ print
- print 'static const char *'
- print '_enum_string(GLenum pname)'
+ print 'const char *'
+ print 'enumToString(GLenum pname)'
print '{'
print ' switch(pname) {'
for name in GLenum.values:
@@ -256,24 +254,10 @@ class StateDumper:
print '}'
print
- print 'static const char *'
- print 'enum_string(GLenum pname)'
+ print 'void'
+ print 'dumpEnum(JSONWriter &json, GLenum pname)'
print '{'
- print ' const char *s = _enum_string(pname);'
- print ' if (s) {'
- print ' return s;'
- print ' } else {'
- print ' static char buf[16];'
- print ' snprintf(buf, sizeof buf, "0x%04x", pname);'
- print ' return buf;'
- print ' }'
- print '}'
- print
-
- print 'static inline void'
- print 'writeEnum(JSONWriter &json, GLenum pname)'
- print '{'
- print ' const char *s = _enum_string(pname);'
+ print ' const char *s = enumToString(pname);'
print ' if (s) {'
print ' json.writeString(s);'
print ' } else {'
@@ -282,492 +266,8 @@ class StateDumper:
print '}'
print
- # shaders
- print '''
-static void
-writeShader(JSONWriter &json, GLuint shader)
-{
- if (!shader) {
- return;
- }
-
- GLint shader_type = 0;
- glGetShaderiv(shader, GL_SHADER_TYPE, &shader_type);
- if (!shader_type) {
- return;
- }
-
- GLint source_length = 0;
- glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &source_length);
- if (!source_length) {
- return;
- }
-
- GLchar *source = new GLchar[source_length];
- GLsizei length = 0;
- source[0] = 0;
- glGetShaderSource(shader, source_length, &length, source);
-
- json.beginMember(enum_string(shader_type));
- json.writeString(source);
- json.endMember();
-
- delete [] source;
-}
-
-static void
-writeShaderObj(JSONWriter &json, GLhandleARB shaderObj)
-{
- if (!shaderObj) {
- return;
- }
-
- GLint shader_type = 0;
- glGetObjectParameterivARB(shaderObj, GL_OBJECT_TYPE_ARB, &shader_type);
- if (!shader_type) {
- return;
- }
-
- GLint source_length = 0;
- glGetObjectParameterivARB(shaderObj, GL_OBJECT_SHADER_SOURCE_LENGTH_ARB, &source_length);
- if (!source_length) {
- return;
- }
-
- GLcharARB *source = new GLcharARB[source_length];
- GLsizei length = 0;
- source[0] = 0;
- glGetShaderSource(shaderObj, source_length, &length, source);
-
- json.beginMember(enum_string(shader_type));
- json.writeString(source);
- json.endMember();
-
- delete [] source;
-}
-
-static inline void
-writeCurrentProgram(JSONWriter &json)
-{
- GLint program = 0;
- glGetIntegerv(GL_CURRENT_PROGRAM, &program);
- if (!program) {
- return;
- }
-
- GLint attached_shaders = 0;
- glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
- if (!attached_shaders) {
- return;
- }
-
- GLuint *shaders = new GLuint[attached_shaders];
- GLsizei count = 0;
- glGetAttachedShaders(program, attached_shaders, &count, shaders);
- for (GLsizei i = 0; i < count; ++ i) {
- writeShader(json, shaders[i]);
- }
- delete [] shaders;
-}
-
-static inline void
-writeCurrentProgramObj(JSONWriter &json)
-{
- GLhandleARB programObj = glGetHandleARB(GL_PROGRAM_OBJECT_ARB);
- if (!programObj) {
- return;
- }
-
- GLint attached_shaders = 0;
- glGetProgramivARB(programObj, GL_OBJECT_ATTACHED_OBJECTS_ARB, &attached_shaders);
- if (!attached_shaders) {
- return;
- }
-
- GLhandleARB *shaderObjs = new GLhandleARB[attached_shaders];
- GLsizei count = 0;
- glGetAttachedObjectsARB(programObj, attached_shaders, &count, shaderObjs);
- for (GLsizei i = 0; i < count; ++ i) {
- writeShaderObj(json, shaderObjs[i]);
- }
- delete [] shaderObjs;
-}
-
-static inline void
-writeArbProgram(JSONWriter &json, GLenum target)
-{
- if (!glIsEnabled(target)) {
- return;
- }
-
- GLint program_length = 0;
- glGetProgramivARB(target, GL_PROGRAM_LENGTH_ARB, &program_length);
- if (!program_length) {
- return;
- }
-
- GLchar *source = new GLchar[program_length + 1];
- source[0] = 0;
- glGetProgramStringARB(target, GL_PROGRAM_STRING_ARB, source);
- source[program_length] = 0;
-
- json.beginMember(enum_string(target));
- json.writeString(source);
- json.endMember();
-
- delete [] source;
-}
-'''
-
- # texture image
- print '''
-static inline void
-writeTextureImage(JSONWriter &json, GLenum target, GLint level)
-{
- GLint width, height = 1, depth = 1;
-
- width = 0;
- glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);
-
- if (target != GL_TEXTURE_1D) {
- height = 0;
- glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);
- if (target == GL_TEXTURE_3D) {
- depth = 0;
- glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth);
- }
- }
-
- if (width <= 0 || height <= 0 || depth <= 0) {
- return;
- } else {
- char label[512];
-
- GLint active_texture = GL_TEXTURE0;
- glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);
- snprintf(label, sizeof label, "%s, %s, level = %i", _enum_string(active_texture), _enum_string(target), level);
-
- json.beginMember(label);
-
- json.beginObject();
-
- // Tell the GUI this is no ordinary object, but an image
- json.writeStringMember("__class__", "image");
-
- json.writeNumberMember("__width__", width);
- json.writeNumberMember("__height__", height);
- json.writeNumberMember("__depth__", depth);
-
- // Hardcoded for now, but we could chose types more adequate to the
- // texture internal format
- json.writeStringMember("__type__", "uint8");
- json.writeBoolMember("__normalized__", true);
- json.writeNumberMember("__channels__", 4);
-
- GLubyte *pixels = new GLubyte[depth*width*height*4];
-
- glGetTexImage(target, level, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
-
- json.beginMember("__data__");
- char *pngBuffer;
- int pngBufferSize;
- Image::writePixelsToBuffer(pixels, width, height, 4, false, &pngBuffer, &pngBufferSize);
- json.writeBase64(pngBuffer, pngBufferSize);
- free(pngBuffer);
- json.endMember(); // __data__
-
- delete [] pixels;
- json.endObject();
- }
-}
-
-
-static bool
-getDrawableBounds(GLint *width, GLint *height) {
-#if defined(_WIN32)
-
- HDC hDC = wglGetCurrentDC();
- if (!hDC) {
- return false;
- }
-
- HWND hWnd = WindowFromDC(hDC);
- RECT rect;
-
- if (!GetClientRect(hWnd, &rect)) {
- return false;
- }
-
- *width = rect.right - rect.left;
- *height = rect.bottom - rect.top;
-
-#elif 0 /* __APPLE__ */
-
- CGLError CGLGetSurface(CGLContextObj, CGSConnectionID*, CGSWindowID*, CGSSurfaceID*);
- CGError CGSGetWindowBounds(CGSConnectionID, CGWindowID, CGRect *ret);
-
-#else
-
- Display *display;
- Drawable drawable;
- Window root;
- int x, y;
- unsigned int w, h, bw, depth;
-
- display = glXGetCurrentDisplay();
- if (!display) {
- return false;
- }
-
- drawable = glXGetCurrentDrawable();
- if (drawable == None) {
- return false;
- }
-
- if (!XGetGeometry(display, drawable, &root, &x, &y, &w, &h, &bw, &depth)) {
- return false;
- }
-
- *width = w;
- *height = h;
-
-#endif
-
- return true;
-}
-
-
-static inline void
-writeDrawBufferImage(JSONWriter &json, GLenum format)
-{
- GLint channels = __gl_format_channels(format);
-
- GLint width, height;
-
- if (!getDrawableBounds(&width, &height)) {
- json.writeNull();
- } else {
- json.beginObject();
-
- // Tell the GUI this is no ordinary object, but an image
- json.writeStringMember("__class__", "image");
-
- json.writeNumberMember("__width__", width);
- json.writeNumberMember("__height__", height);
- json.writeNumberMember("__depth__", 1);
-
- // Hardcoded for now, but we could chose types more adequate to the
- // texture internal format
- json.writeStringMember("__type__", "uint8");
- json.writeBoolMember("__normalized__", true);
- json.writeNumberMember("__channels__", channels);
-
- GLubyte *pixels = new GLubyte[width*height*channels];
-
- GLint drawbuffer = GL_NONE;
- GLint readbuffer = GL_NONE;
- glGetIntegerv(GL_DRAW_BUFFER, &drawbuffer);
- glGetIntegerv(GL_READ_BUFFER, &readbuffer);
- glReadBuffer(drawbuffer);
-
- glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
-
- glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, pixels);
-
- glPopClientAttrib();
- glReadBuffer(readbuffer);
-
- json.beginMember("__data__");
- char *pngBuffer;
- int pngBufferSize;
- Image::writePixelsToBuffer(pixels, width, height, channels, false, &pngBuffer, &pngBufferSize);
- //std::cerr <<" Before = "<<(width * height * channels * sizeof *pixels)
- // <<", after = "<<pngBufferSize << ", ratio = " << double(width * height * channels * sizeof *pixels)/pngBufferSize;
- json.writeBase64(pngBuffer, pngBufferSize);
- free(pngBuffer);
- json.endMember(); // __data__
-
- delete [] pixels;
- json.endObject();
- }
-}
-
-static inline GLuint
-downsampledFramebuffer(GLuint oldFbo, GLint drawbuffer,
- GLint colorRb, GLint depthRb, GLint stencilRb,
- GLuint *rbs, GLint *numRbs)
-{
- GLuint fbo;
- GLint format;
- GLint w, h;
-
- *numRbs = 0;
-
- glGenFramebuffers(1, &fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
-
- glBindRenderbuffer(GL_RENDERBUFFER, colorRb);
- glGetRenderbufferParameteriv(GL_RENDERBUFFER,
- GL_RENDERBUFFER_WIDTH, &w);
- glGetRenderbufferParameteriv(GL_RENDERBUFFER,
- GL_RENDERBUFFER_HEIGHT, &h);
- glGetRenderbufferParameteriv(GL_RENDERBUFFER,
- GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
-
- glGenRenderbuffers(1, &rbs[*numRbs]);
- glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
- glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, drawbuffer,
- GL_RENDERBUFFER, rbs[*numRbs]);
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
- glDrawBuffer(drawbuffer);
- glReadBuffer(drawbuffer);
- glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
- GL_COLOR_BUFFER_BIT, GL_NEAREST);
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- ++*numRbs;
-
- if (stencilRb == depthRb && stencilRb) {
- //combined depth and stencil buffer
- glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
- glGetRenderbufferParameteriv(GL_RENDERBUFFER,
- GL_RENDERBUFFER_WIDTH, &w);
- glGetRenderbufferParameteriv(GL_RENDERBUFFER,
- GL_RENDERBUFFER_HEIGHT, &h);
- glGetRenderbufferParameteriv(GL_RENDERBUFFER,
- GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
-
- glGenRenderbuffers(1, &rbs[*numRbs]);
- glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
- glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
- GL_RENDERBUFFER, rbs[*numRbs]);
- glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
- glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
- GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- ++*numRbs;
- } else {
- if (depthRb) {
- glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
- glGetRenderbufferParameteriv(GL_RENDERBUFFER,
- GL_RENDERBUFFER_WIDTH, &w);
- glGetRenderbufferParameteriv(GL_RENDERBUFFER,
- GL_RENDERBUFFER_HEIGHT, &h);
- glGetRenderbufferParameteriv(GL_RENDERBUFFER,
- GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
-
- glGenRenderbuffers(1, &rbs[*numRbs]);
- glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
- glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER,
- GL_DEPTH_ATTACHMENT,
- GL_RENDERBUFFER, rbs[*numRbs]);
- glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
- glDrawBuffer(GL_DEPTH_ATTACHMENT);
- glReadBuffer(GL_DEPTH_ATTACHMENT);
- glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
- GL_DEPTH_BUFFER_BIT, GL_NEAREST);
- ++*numRbs;
- }
- if (stencilRb) {
- glBindRenderbuffer(GL_RENDERBUFFER, stencilRb);
- glGetRenderbufferParameteriv(GL_RENDERBUFFER,
- GL_RENDERBUFFER_WIDTH, &w);
- glGetRenderbufferParameteriv(GL_RENDERBUFFER,
- GL_RENDERBUFFER_HEIGHT, &h);
- glGetRenderbufferParameteriv(GL_RENDERBUFFER,
- GL_RENDERBUFFER_INTERNAL_FORMAT, &format);
-
- glGenRenderbuffers(1, &rbs[*numRbs]);
- glBindRenderbuffer(GL_RENDERBUFFER, rbs[*numRbs]);
- glRenderbufferStorage(GL_RENDERBUFFER, format, w, h);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER,
- GL_STENCIL_ATTACHMENT,
- GL_RENDERBUFFER, rbs[*numRbs]);
- glBindFramebuffer(GL_READ_FRAMEBUFFER, oldFbo);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
- glDrawBuffer(GL_STENCIL_ATTACHMENT);
- glReadBuffer(GL_STENCIL_ATTACHMENT);
- glBlitFramebuffer(0, 0, w, h, 0, 0, w, h,
- GL_STENCIL_BUFFER_BIT, GL_NEAREST);
- ++*numRbs;
- }
- }
-
- return fbo;
-}
-
-static void
-writeDrawBuffers(JSONWriter &json, GLboolean writeDepth, GLboolean writeStencil)
-{
- json.beginMember("GL_RGBA");
- writeDrawBufferImage(json, GL_RGBA);
- json.endMember();
-
- if (writeDepth) {
- json.beginMember("GL_DEPTH_COMPONENT");
- writeDrawBufferImage(json, GL_DEPTH_COMPONENT);
- json.endMember();
- }
-
- if (writeStencil) {
- json.beginMember("GL_STENCIL_INDEX");
- writeDrawBufferImage(json, GL_STENCIL_INDEX);
- json.endMember();
- }
-}
-
-'''
-
- # textures
- print 'static inline void'
- print 'writeTexture(JSONWriter &json, GLenum target, GLenum binding)'
- print '{'
- print ' GLint texture_binding = 0;'
- print ' glGetIntegerv(binding, &texture_binding);'
- print ' if (!glIsEnabled(target) && !texture_binding) {'
- print ' return;'
- print ' }'
- print
- print ' GLint level = 0;'
- print ' do {'
- print ' GLint width = 0, height = 0;'
- print ' glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width);'
- print ' glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height);'
- print ' if (!width || !height) {'
- print ' break;'
- print ' }'
- print
- print ' if (target == GL_TEXTURE_CUBE_MAP) {'
- print ' for (int face = 0; face < 6; ++face) {'
- print ' writeTextureImage(json, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level);'
- print ' }'
- print ' } else {'
- print ' writeTextureImage(json, target, level);'
- print ' }'
- print
- print ' ++level;'
- print ' } while(true);'
- print '}'
- print
-
- print 'void glstate::state_dump(std::ostream &os)'
+ print 'void dumpParameters(JSONWriter &json)'
print '{'
- print ' JSONWriter json(os);'
- self.dump_parameters()
- self.dump_current_program()
- self.dump_textures()
- self.dump_framebuffer()
- print '}'
- print
-
- def dump_parameters(self):
print ' json.beginMember("parameters");'
print ' json.beginObject();'
@@ -782,7 +282,10 @@ writeDrawBuffers(JSONWriter &json, GLboolean writeDepth, GLboolean writeStencil)
print ' json.endObject();'
print ' json.endMember(); // parameters'
+ print '}'
print
+
+ print '} /*namespace glstate */'
def dump_material_params(self):
for face in ['GL_FRONT', 'GL_BACK']:
@@ -887,114 +390,6 @@ writeDrawBuffers(JSONWriter &json, GLboolean writeDepth, GLboolean writeStencil)
print ' }'
print
- def dump_current_program(self):
- print ' json.beginMember("shaders");'
- print ' json.beginObject();'
- print ' writeCurrentProgram(json);'
- for target in self.program_targets:
- print ' writeArbProgram(json, %s);' % target
- print ' json.endObject();'
- print ' json.endMember(); //shaders'
- print
-
- def dump_textures(self):
- print ' {'
- print ' json.beginMember("textures");'
- print ' json.beginObject();'
- print ' GLint active_texture = GL_TEXTURE0;'
- print ' glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture);'
- print ' GLint max_texture_coords = 0;'
- print ' glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);'
- print ' GLint max_combined_texture_image_units = 0;'
- print ' glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_combined_texture_image_units);'
- print ' GLint max_units = std::max(max_combined_texture_image_units, max_texture_coords);'
- print ' for (GLint unit = 0; unit < max_units; ++unit) {'
- print ' GLenum texture = GL_TEXTURE0 + unit;'
- print ' glActiveTexture(texture);'
- for target, binding in texture_targets:
- print ' writeTexture(json, %s, %s);' % (target, binding)
- print ' }'
- print ' glActiveTexture(active_texture);'
- print ' json.endObject();'
- print ' json.endMember(); // textures'
- print ' }'
- print
-
- def dump_framebuffer(self):
- print ' json.beginMember("framebuffer");'
- print ' json.beginObject();'
- # TODO: Handle real FBOs
- print
- print ' GLint boundDrawFbo = 0, boundReadFbo = 0;'
- print ' glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundDrawFbo);'
- print ' glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundReadFbo);'
- print ' if (!boundDrawFbo) {'
- print ' GLint depth_bits = 0;'
- print ' glGetIntegerv(GL_DEPTH_BITS, &depth_bits);'
- print ' GLint stencil_bits = 0;'
- print ' glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);'
- print ' writeDrawBuffers(json, depth_bits, stencil_bits);'
- print ' } else {'
- print ' GLint colorRb, stencilRb, depthRb;'
- print ' GLint boundRb;'
- print ' glGetIntegerv(GL_RENDERBUFFER_BINDING, &boundRb);'
- print ' GLint drawbuffer = GL_NONE;'
- print ' glGetIntegerv(GL_DRAW_BUFFER, &drawbuffer);'
- print
- print ' glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,'
- print ' drawbuffer,'
- print ' GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,'
- print ' &colorRb);'
- print ' glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,'
- print ' GL_DEPTH_ATTACHMENT,'
- print ' GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,'
- print ' &depthRb);'
- print ' glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,'
- print ' GL_STENCIL_ATTACHMENT,'
- print ' GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,'
- print ' &stencilRb);'
- print
- print ' GLint colorSamples, depthSamples, stencilSamples;'
- print ' GLuint rbs[3];'
- print ' GLint numRbs = 0;'
- print ' GLuint fboCopy = 0;'
- print ' glBindRenderbuffer(GL_RENDERBUFFER, colorRb);'
- print ' glGetRenderbufferParameteriv(GL_RENDERBUFFER,'
- print ' GL_RENDERBUFFER_SAMPLES, &colorSamples);'
- print ' glBindRenderbuffer(GL_RENDERBUFFER, depthRb);'
- print ' glGetRenderbufferParameteriv(GL_RENDERBUFFER,'
- print ' GL_RENDERBUFFER_SAMPLES, &depthSamples);'
- print ' glBindRenderbuffer(GL_RENDERBUFFER, stencilRb);'
- print ' glGetRenderbufferParameteriv(GL_RENDERBUFFER,'
- print ' GL_RENDERBUFFER_SAMPLES, &stencilSamples);'
- print ' glBindRenderbuffer(GL_RENDERBUFFER, boundRb);'
- print
- print ' if (colorSamples || depthSamples || stencilSamples) {'
- print ' //glReadPixels doesnt support multisampled buffers so we need'
- print ' // to blit the fbo to a temporary one'
- print ' fboCopy = downsampledFramebuffer(boundDrawFbo, drawbuffer,'
- print ' colorRb, depthRb, stencilRb,'
- print ' rbs, &numRbs);'
- print ' }'
- print ' glDrawBuffer(drawbuffer);'
- print ' glReadBuffer(drawbuffer);'
- print
- print ' writeDrawBuffers(json, depthRb, stencilRb);'
- print
- print ' if (fboCopy) {'
- print ' glBindFramebuffer(GL_FRAMEBUFFER, boundDrawFbo);'
- print ' glBindFramebuffer(GL_READ_FRAMEBUFFER, boundReadFbo);'
- print ' glBindFramebuffer(GL_DRAW_FRAMEBUFFER, boundDrawFbo);'
- print ' glBindRenderbuffer(GL_RENDERBUFFER_BINDING, boundRb);'
- print ' glDeleteRenderbuffers(numRbs, rbs);'
- print ' glDeleteFramebuffers(1, &fboCopy);'
- print ' }'
- print ' }'
- print
- print ' json.endObject();'
- print ' json.endMember(); // framebuffer'
- pass
-
def dump_atoms(self, getter, *args):
for function, type, count, name in parameters:
inflection = getter.inflector.radical + getter.suffix