Anonymous
Отчет renderdoc об отсутствии привязки вершинного шейдера при отрисовке корректно работающего приложения [закрыто]
Сообщение
Anonymous » 31 окт 2024, 05:19
Я пытаюсь отладить свое приложение, но renderdoc продолжает выдавать эту ошибку:
Код: Выделить всё
43 API High Miscellaneous 1280 Error has been generated. GL error GL_INVALID_ENUM in IsEnabled: (ID: 3525876922) Generic error
43 Incorrect API Use High Undefined 0 No vertex shader bound at draw!
И об ошибке сообщается только один раз:
скриншот захвата
скриншот ошибки
GL_INVALID_ENUM взят из glDrawArraysInstanced, однако параметр «mode», переданный в функцию, должен быть в порядке (GL_TRIANGLE_STRIP).
Есть ли какие-либо подсказки, чтобы найти причину этого?
РЕДАКТИРОВАТЬ:
Исходный код для создания моей шейдерной программы:
Код: Выделить всё
static void
CheckCompileShaderError(GLuint shader, const char **sources, int n, const char *hint = nullptr) {
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
GLsizei size = 1024 * 1024;
auto *buffer = static_cast(malloc(size + 1));
GLsizei len = 0;
glGetShaderInfoLog(shader, size, &len, buffer);
buffer[len > size ? size : len] = '\0';
fprintf(stderr, "Shader %s error:\n%s\n", hint ? hint : "\b", buffer);
fflush(stderr);
free(buffer);
}
}
void CompileShader(GLuint shader, const char **sources, int n, const char *hint) {
glShaderSource(shader, n, sources, nullptr);
glCompileShader(shader);
CheckCompileShaderError(shader, sources, n, hint);
}
void CheckLinkProgramError(GLuint prog, const char *hint) {
GLint status;
glGetProgramiv(prog, GL_LINK_STATUS, &status);
if (status != GL_TRUE) {
GLsizei size = 1024 * 1024;
auto *buffer = static_cast(malloc(size + 1));
GLsizei len = 0;
glGetProgramInfoLog(prog, size, &len, buffer);
buffer[len > size ? size : len] = '\0';
fprintf(stderr, "Program %s error:\n%s\n", hint ? hint : "\b", buffer);
fflush(stderr);
free(buffer);
}
}
// pre-allocate buffers
PainterImpl::PainterImpl() : // NOLINT(cppcoreguidelines-pro-type-member-init)
debugFlags_(DebugFlags::None),
pathCmdBuffer_(INIT_PATH_COMMANDS_SIZE),
pathPointBuffer_(INIT_PATH_POINTS_SIZE),
segmentBuffer_(INIT_SEGMENTS_SIZE),
pathBuffer_(INIT_PATHS_SIZE) {
reset();
// read shader sources
const auto *vert = ReadShader("../assets/shaders/primitive.vert.glsl");
const auto *frag = ReadShader("../assets/shaders/primitive.frag.glsl");
// create, compile and attach shaders
prog_ = glCreateProgram();
vert_ = glCreateShader(GL_VERTEX_SHADER);
frag_ = glCreateShader(GL_FRAGMENT_SHADER);
CompileShader(vert_, &vert, 1, "VertexShader-PRIMITIVE");
glAttachShader(prog_, vert_);
CompileShader(frag_, &frag, 1, "FragmentShader-PRIMITIVE");
glAttachShader(prog_, frag_);
glObjectLabel(GL_PROGRAM, prog_, 7, "Program");
glObjectLabel(GL_SHADER, vert_, -1, "VertexShader");
glObjectLabel(GL_SHADER, frag_, -1, "FragmentShader");
free((void *)vert);
free((void *)frag);
// bind vertex attribute location
// NOTE: If you have linked program, then calls to glBindAttribLocation will do nothing,
// since they only have an effect on subsequent linking operations.
glBindAttribLocation(prog_, ATTR_POS, "aPos");
glBindAttribLocation(prog_, ATTR_QUAD_BOUND, "aQuadBound");
glBindAttribLocation(prog_, ATTR_TEX_BOUND, "aTexBound");
glBindAttribLocation(prog_, ATTR_TYPE, "aType");
glBindAttribLocation(prog_, ATTR_FLAGS, "aFlags");
glBindAttribLocation(prog_, ATTR_TRANSFORM_IDX, "aTransformIdx");
glBindAttribLocation(prog_, ATTR_PAINT_IDX, "aPaintIdx");
glBindAttribLocation(prog_, ATTR_SCISSOR_IDX, "aScissorIdx");
glBindAttribLocation(prog_, ATTR_GLYPH_IDX, "aGlyphIdx");
glBindAttribLocation(prog_, ATTR_START, "aStart");
glBindAttribLocation(prog_, ATTR_COUNT, "aCount");
glBindAttribLocation(prog_, ATTR_RADIUS, "aRadius");
glBindAttribLocation(prog_, ATTR_STROKE_WIDTH, "aStrokeWidth");
glBindAttribLocation(prog_, ATTR_P0, "aP0");
glBindAttribLocation(prog_, ATTR_P1, "aP1");
glBindAttribLocation(prog_, ATTR_P2, "aP2");
// link program
glLinkProgram(prog_);
CheckLinkProgramError(prog_, "Program-PRIMITIVE");
// get uniform location
loc_[UNIFORM_WIN] = glGetUniformLocation(prog_, "uWinSize");
loc_[UNIFORM_PX_RATIO] = glGetUniformLocation(prog_, "uPxRatio");
loc_[UNIFORM_TRANSFORM_TEX] = glGetUniformLocation(prog_, "uTransformTex");
loc_[UNIFORM_POINTS_TEX] = glGetUniformLocation(prog_, "uPointsTex");
loc_[UNIFORM_PAINTS_TEX] = glGetUniformLocation(prog_, "uPaintsTex");
loc_[UNIFORM_SCISSORS_TEX] = glGetUniformLocation(prog_, "uScissorsTex");
loc_[UNIFORM_FONT_INDICES] = glGetUniformLocation(prog_, "uGlyphs");
loc_[UNIFORM_FONT_CURVES_TEX] = glGetUniformLocation(prog_, "uFontCurves");
loc_[UNIFORM_FLAGS] = glGetUniformLocation(prog_, "uFlags");
// generate vertex arrays and vertex buffers
glGenVertexArrays(MAX_VERTEX_ARRAYS, vao_);
glGenBuffers(MAX_VERTEX_BUFFERS, vbo_);
glObjectLabel(GL_VERTEX_ARRAY, vao_[VARR_INSTANCED], -1, "VertexArray-INSTANCED");
glObjectLabel(GL_VERTEX_ARRAY, vao_[VARR_COMPLEX_FILL], -1, "VertexArray-COMPLEX_FILL");
glObjectLabel(GL_BUFFER, vbo_[VBUF_QUAD], -1, "VertexBuffer-PRIM_QUAD");
glObjectLabel(GL_BUFFER, vbo_[VBUF_DATA], -1, "VertexBuffer-DATA");
// initialize vertex array
glBindVertexArray(vao_[VARR_INSTANCED]);
glEnableVertexAttribArray(ATTR_POS);
glEnableVertexAttribArray(ATTR_QUAD_BOUND);
glEnableVertexAttribArray(ATTR_TEX_BOUND);
glEnableVertexAttribArray(ATTR_TYPE);
glEnableVertexAttribArray(ATTR_FLAGS);
glEnableVertexAttribArray(ATTR_TRANSFORM_IDX);
glEnableVertexAttribArray(ATTR_PAINT_IDX);
glEnableVertexAttribArray(ATTR_SCISSOR_IDX);
glEnableVertexAttribArray(ATTR_GLYPH_IDX);
glEnableVertexAttribArray(ATTR_START);
glEnableVertexAttribArray(ATTR_COUNT);
glEnableVertexAttribArray(ATTR_RADIUS);
glEnableVertexAttribArray(ATTR_STROKE_WIDTH);
glEnableVertexAttribArray(ATTR_P0);
glEnableVertexAttribArray(ATTR_P1);
glEnableVertexAttribArray(ATTR_P2);
// instancing quad
float a = 1.0f;
glm::vec2 quad[] = {{-a, -a}, {a, -a}, {-a, a}, {a, a}};
glBindBuffer(GL_ARRAY_BUFFER, vbo_[VBUF_QUAD]);
glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW);
glVertexAttribPointer(ATTR_POS, 2, GL_FLOAT, GL_FALSE, 0, offset(0));
// call data
// NOTE: integer input attribute should use glVertexAttribIPointer
glBindBuffer(GL_ARRAY_BUFFER, vbo_[VBUF_DATA]);
glBufferData(GL_ARRAY_BUFFER, 1024 * sizeof(CallData), nullptr, GL_STREAM_DRAW);
glVertexAttribPointer(ATTR_QUAD_BOUND, 4, GL_FLOAT, GL_FALSE, sizeof(CallData), offset(offsetof(CallData, quadBound)));
glVertexAttribPointer(ATTR_TEX_BOUND, 4, GL_FLOAT, GL_FALSE, sizeof(CallData), offset(offsetof(CallData, texBound)));
glVertexAttribIPointer(ATTR_TYPE, 1, GL_INT, sizeof(CallData), offset(offsetof(CallData, type)));
glVertexAttribIPointer(ATTR_FLAGS, 1, GL_INT, sizeof(CallData), offset(offsetof(CallData, flags)));
glVertexAttribIPointer(ATTR_TRANSFORM_IDX, 1, GL_INT, sizeof(CallData), offset(offsetof(CallData, transformIdx)));
glVertexAttribIPointer(ATTR_PAINT_IDX, 1, GL_INT, sizeof(CallData), offset(offsetof(CallData, paintIdx)));
glVertexAttribIPointer(ATTR_SCISSOR_IDX, 1, GL_INT, sizeof(CallData), offset(offsetof(CallData, scissorIdx)));
glVertexAttribIPointer(ATTR_GLYPH_IDX, 1, GL_INT, sizeof(CallData), offset(offsetof(CallData, glyphIdx)));
glVertexAttribIPointer(ATTR_START, 1, GL_INT, sizeof(CallData), offset(offsetof(CallData, start)));
glVertexAttribIPointer(ATTR_COUNT, 1, GL_INT, sizeof(CallData), offset(offsetof(CallData, count)));
glVertexAttribPointer(ATTR_RADIUS, 1, GL_FLOAT, GL_FALSE, sizeof(CallData), offset(offsetof(CallData, radius)));
glVertexAttribPointer(ATTR_STROKE_WIDTH, 1, GL_FLOAT, GL_FALSE, sizeof(CallData), offset(offsetof(CallData, strokeWidth)));
glVertexAttribPointer(ATTR_P0, 2, GL_FLOAT, GL_FALSE, sizeof(CallData), offset(offsetof(CallData, p0)));
glVertexAttribPointer(ATTR_P1, 2, GL_FLOAT, GL_FALSE, sizeof(CallData), offset(offsetof(CallData, p1)));
glVertexAttribPointer(ATTR_P2, 2, GL_FLOAT, GL_FALSE, sizeof(CallData), offset(offsetof(CallData, p2)));
// setup instancing
glVertexAttribDivisor(ATTR_QUAD_BOUND, 1);
glVertexAttribDivisor(ATTR_TEX_BOUND, 1);
glVertexAttribDivisor(ATTR_TYPE, 1);
glVertexAttribDivisor(ATTR_FLAGS, 1);
glVertexAttribDivisor(ATTR_TRANSFORM_IDX, 1);
glVertexAttribDivisor(ATTR_PAINT_IDX, 1);
glVertexAttribDivisor(ATTR_SCISSOR_IDX, 1);
glVertexAttribDivisor(ATTR_GLYPH_IDX, 1);
glVertexAttribDivisor(ATTR_START, 1);
glVertexAttribDivisor(ATTR_COUNT, 1);
glVertexAttribDivisor(ATTR_RADIUS, 1);
glVertexAttribDivisor(ATTR_STROKE_WIDTH, 1);
glVertexAttribDivisor(ATTR_P0, 1);
glVertexAttribDivisor(ATTR_P1, 1);
glVertexAttribDivisor(ATTR_P2, 1);
CheckGLError("Setup-Instancing");
// generate 1d lookup textures (vec2/float for each texel)
const auto flag = TexFlags::T1D | TexFlags::FmtAuto | TexFlags::Nearest;
tex_[TEX_POINTS] = createTexture(1024 * POINT_FLOATS / 2, 1, TexFlags::RG32F | flag, nullptr);
tex_[TEX_SCISSORS] = createTexture(128 * SCISSOR_FLOATS / 2, 1, TexFlags::RG32F | flag, nullptr);
tex_[TEX_PAINTS] = createTexture(128 * PAINT_FLOATS, 1, TexFlags::R32F | flag, nullptr);
tex_[TEX_TRANSFORMS] = createTexture(128 * TRANSFORM_FLOATS / 2, 1, TexFlags::RG32F | flag, nullptr);
glObjectLabel(GL_TEXTURE, getTextureId(tex_[TEX_POINTS]), -1, "Texture-POINTS");
glObjectLabel(GL_TEXTURE, getTextureId(tex_[TEX_SCISSORS]), -1, "Texture-SCISSORS");
glObjectLabel(GL_TEXTURE, getTextureId(tex_[TEX_PAINTS]), -1, "Texture-PAINTS");
glObjectLabel(GL_TEXTURE, getTextureId(tex_[TEX_TRANSFORMS]), -1, "Texture-TRANSFORMS");
CheckGLError("Create-Lookup-Textures");
// texture buffers needed for font rendering
GLuint glyphTexture, curveTexture;
glGenTextures(1, &glyphTexture);
glGenTextures(1, &curveTexture);
// glyphs
glBindBuffer(GL_TEXTURE_BUFFER, vbo_[VBUF_FONT_INDICES]);
glBufferData(GL_TEXTURE_BUFFER, sizeof(Range) * 1024, nullptr, GL_STATIC_DRAW);
glBindTexture(GL_TEXTURE_BUFFER, glyphTexture);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32I, vbo_[VBUF_FONT_INDICES]);
// font curves
glBindBuffer(GL_TEXTURE_BUFFER, vbo_[VBUF_FONT_CURVES]);
glBufferData(GL_TEXTURE_BUFFER, sizeof(FontCurveData) * 1024, nullptr, GL_STATIC_DRAW);
glBindTexture(GL_TEXTURE_BUFFER, curveTexture);
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, vbo_[VBUF_FONT_CURVES]);
// register
tex_[TEX_FONT_INDICES] = createTexture(glyphTexture, -1, -1, TexFlags::RG32I); // no size information
tex_[TEX_FONT_CURVES] = createTexture(curveTexture, -1, -1, TexFlags::R32I);
glObjectLabel(GL_TEXTURE, glyphTexture, -1, "Texture-FONT_INDICES");
glObjectLabel(GL_TEXTURE, curveTexture, -1, "Texture-FONT_CURVES");
CheckGLError("Create-Font-Textures");
// cleanup
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glBindVertexArray(0);
}
Сброс данных о вызовах:
Код: Выделить всё
void PainterImpl::endFrame() {
// translate DrawCommand
translateCommands();
if (callBuffer_.empty()) return;
if (enum_has_flag(debugFlags_, DebugFlags::WireFrame)) { WireframeMode(true); }
// set blend
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_DEPTH_TEST);
glUseProgram(prog_);
// glActiveTexture(GL_TEXTURE0);
// TODO: user provided texture, used for arbitrary gradient or image pattern paint.
// scissors - 48bytes, 12 floats, 6 vectors.
const auto scissorBufferSize = static_cast(scissorBuffer_.size() * SCISSOR_FLOATS / 2);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_1D, getTextureId(tex_[TEX_SCISSORS]));
glTexImage1D(GL_TEXTURE_1D, 0, GL_RG32F, scissorBufferSize, 0, GL_RG, GL_FLOAT, scissorBuffer_.data());
CheckGLError("Upload-Scissors");
// points for primitives
const auto pointBufferSize = static_cast(pointBuffer_.size() * POINT_FLOATS / 2);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_1D, getTextureId(tex_[TEX_POINTS]));
glTexImage1D(GL_TEXTURE_1D, 0, GL_RG32F, pointBufferSize, 0, GL_RG, GL_FLOAT, pointBuffer_.data());
CheckGLError("Upload-Points");
// paints - 18 floats
const auto paintBufferSize = static_cast(paintBuffer_.size() * PAINT_FLOATS);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_1D, getTextureId(tex_[TEX_PAINTS]));
glTexImage1D(GL_TEXTURE_1D, 0, GL_R32F, paintBufferSize, 0, GL_RED, GL_FLOAT, paintBuffer_.data());
CheckGLError("Upload-Paints");
// transforms - 6 floats
const auto transformBufferSize = static_cast(transformBuffer_.size() * TRANSFORM_FLOATS / 2);
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_1D, getTextureId(tex_[TEX_TRANSFORMS]));
glTexImage1D(GL_TEXTURE_1D, 0, GL_RG32F, transformBufferSize, 0, GL_RG, GL_FLOAT, transformBuffer_.data());
CheckGLError("Upload-Transforms");
// font indices buffer
glBindBuffer(GL_TEXTURE_BUFFER, vbo_[VBUF_FONT_INDICES]);
glBufferData(GL_TEXTURE_BUFFER, fontGlyphBuffer_.getSizeInBytes(), fontGlyphBuffer_.data(), GL_STATIC_DRAW);
glActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_BUFFER, getTextureId(tex_[TEX_FONT_INDICES]));
CheckGLError("Upload-Font-Indices");
// font curves buffer
glBindBuffer(GL_TEXTURE_BUFFER, vbo_[VBUF_FONT_CURVES]);
glBufferData(GL_TEXTURE_BUFFER, fontCurveBuffer_.getSizeInBytes(), fontCurveBuffer_.data(), GL_STATIC_DRAW);
glActiveTexture(GL_TEXTURE6);
glBindTexture(GL_TEXTURE_BUFFER, getTextureId(tex_[TEX_FONT_CURVES]));
CheckGLError("Upload-Font-Curves");
// set uniforms
float win[2] = {winWidth_, winHeight_};
glUniform2fv(loc_[UNIFORM_WIN], 1, win);
glUniform1f(loc_[UNIFORM_PX_RATIO], devicePixelRatio_);
glUniform1i(loc_[UNIFORM_SCISSORS_TEX], 1);
glUniform1i(loc_[UNIFORM_POINTS_TEX], 2);
glUniform1i(loc_[UNIFORM_PAINTS_TEX], 3);
glUniform1i(loc_[UNIFORM_TRANSFORM_TEX], 4);
glUniform1i(loc_[UNIFORM_FONT_INDICES], 5);
glUniform1i(loc_[UNIFORM_FONT_CURVES_TEX], 6);
glUniform1f(loc_[UNIFORM_AA_WINDOW_SIZE], 1.4f);
DebugFlags flags = (debugFlags_ & DebugFlags::FontSuperSampleAA) | (debugFlags_ & DebugFlags::ShowFontControlPoint);
glUniform1i(loc_[UNIFORM_FLAGS], static_cast(flags)); // flags used by shader won't exceed "int"'s range
CheckGLError("Set-Uniforms");
// bind vertex array
glBindVertexArray(vao_[VARR_INSTANCED]);
// fill buffer
const auto callBufferSize = static_cast(sizeof(CallData) * callBuffer_.size());
glBindBuffer(GL_ARRAY_BUFFER, vbo_[VBUF_DATA]);
glBufferData(GL_ARRAY_BUFFER, callBufferSize, callBuffer_.data(), GL_STREAM_DRAW);
// draw
CheckGLError("Pre-Draw");
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, callBuffer_.size());
CheckGLError("Draw");
// reset state and cleanup
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_TEXTURE_BUFFER, 0);
glBindVertexArray(0);
glUseProgram(0);
glDisable(GL_BLEND);
if (enum_has_flag(debugFlags_, DebugFlags::WireFrame)) { WireframeMode(false); }
}
Во время этих двух функций
никаких других вызовов API opengl не происходит, поскольку я просто обновляю callBuffer_.
Подробнее здесь:
https://stackoverflow.com/questions/791 ... pplication
1730341153
Anonymous
Я пытаюсь отладить свое приложение, но renderdoc продолжает выдавать эту ошибку: [code]43 API High Miscellaneous 1280 Error has been generated. GL error GL_INVALID_ENUM in IsEnabled: (ID: 3525876922) Generic error 43 Incorrect API Use High Undefined 0 No vertex shader bound at draw! [/code] И об ошибке сообщается только один раз: скриншот захвата скриншот ошибки GL_INVALID_ENUM взят из glDrawArraysInstanced, однако параметр «mode», переданный в функцию, должен быть в порядке (GL_TRIANGLE_STRIP). Есть ли какие-либо подсказки, чтобы найти причину этого? РЕДАКТИРОВАТЬ: Исходный код для создания моей шейдерной программы: [code] static void CheckCompileShaderError(GLuint shader, const char **sources, int n, const char *hint = nullptr) { GLint status; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (status != GL_TRUE) { GLsizei size = 1024 * 1024; auto *buffer = static_cast(malloc(size + 1)); GLsizei len = 0; glGetShaderInfoLog(shader, size, &len, buffer); buffer[len > size ? size : len] = '\0'; fprintf(stderr, "Shader %s error:\n%s\n", hint ? hint : "\b", buffer); fflush(stderr); free(buffer); } } void CompileShader(GLuint shader, const char **sources, int n, const char *hint) { glShaderSource(shader, n, sources, nullptr); glCompileShader(shader); CheckCompileShaderError(shader, sources, n, hint); } void CheckLinkProgramError(GLuint prog, const char *hint) { GLint status; glGetProgramiv(prog, GL_LINK_STATUS, &status); if (status != GL_TRUE) { GLsizei size = 1024 * 1024; auto *buffer = static_cast(malloc(size + 1)); GLsizei len = 0; glGetProgramInfoLog(prog, size, &len, buffer); buffer[len > size ? size : len] = '\0'; fprintf(stderr, "Program %s error:\n%s\n", hint ? hint : "\b", buffer); fflush(stderr); free(buffer); } } // pre-allocate buffers PainterImpl::PainterImpl() : // NOLINT(cppcoreguidelines-pro-type-member-init) debugFlags_(DebugFlags::None), pathCmdBuffer_(INIT_PATH_COMMANDS_SIZE), pathPointBuffer_(INIT_PATH_POINTS_SIZE), segmentBuffer_(INIT_SEGMENTS_SIZE), pathBuffer_(INIT_PATHS_SIZE) { reset(); // read shader sources const auto *vert = ReadShader("../assets/shaders/primitive.vert.glsl"); const auto *frag = ReadShader("../assets/shaders/primitive.frag.glsl"); // create, compile and attach shaders prog_ = glCreateProgram(); vert_ = glCreateShader(GL_VERTEX_SHADER); frag_ = glCreateShader(GL_FRAGMENT_SHADER); CompileShader(vert_, &vert, 1, "VertexShader-PRIMITIVE"); glAttachShader(prog_, vert_); CompileShader(frag_, &frag, 1, "FragmentShader-PRIMITIVE"); glAttachShader(prog_, frag_); glObjectLabel(GL_PROGRAM, prog_, 7, "Program"); glObjectLabel(GL_SHADER, vert_, -1, "VertexShader"); glObjectLabel(GL_SHADER, frag_, -1, "FragmentShader"); free((void *)vert); free((void *)frag); // bind vertex attribute location // NOTE: If you have linked program, then calls to glBindAttribLocation will do nothing, // since they only have an effect on subsequent linking operations. glBindAttribLocation(prog_, ATTR_POS, "aPos"); glBindAttribLocation(prog_, ATTR_QUAD_BOUND, "aQuadBound"); glBindAttribLocation(prog_, ATTR_TEX_BOUND, "aTexBound"); glBindAttribLocation(prog_, ATTR_TYPE, "aType"); glBindAttribLocation(prog_, ATTR_FLAGS, "aFlags"); glBindAttribLocation(prog_, ATTR_TRANSFORM_IDX, "aTransformIdx"); glBindAttribLocation(prog_, ATTR_PAINT_IDX, "aPaintIdx"); glBindAttribLocation(prog_, ATTR_SCISSOR_IDX, "aScissorIdx"); glBindAttribLocation(prog_, ATTR_GLYPH_IDX, "aGlyphIdx"); glBindAttribLocation(prog_, ATTR_START, "aStart"); glBindAttribLocation(prog_, ATTR_COUNT, "aCount"); glBindAttribLocation(prog_, ATTR_RADIUS, "aRadius"); glBindAttribLocation(prog_, ATTR_STROKE_WIDTH, "aStrokeWidth"); glBindAttribLocation(prog_, ATTR_P0, "aP0"); glBindAttribLocation(prog_, ATTR_P1, "aP1"); glBindAttribLocation(prog_, ATTR_P2, "aP2"); // link program glLinkProgram(prog_); CheckLinkProgramError(prog_, "Program-PRIMITIVE"); // get uniform location loc_[UNIFORM_WIN] = glGetUniformLocation(prog_, "uWinSize"); loc_[UNIFORM_PX_RATIO] = glGetUniformLocation(prog_, "uPxRatio"); loc_[UNIFORM_TRANSFORM_TEX] = glGetUniformLocation(prog_, "uTransformTex"); loc_[UNIFORM_POINTS_TEX] = glGetUniformLocation(prog_, "uPointsTex"); loc_[UNIFORM_PAINTS_TEX] = glGetUniformLocation(prog_, "uPaintsTex"); loc_[UNIFORM_SCISSORS_TEX] = glGetUniformLocation(prog_, "uScissorsTex"); loc_[UNIFORM_FONT_INDICES] = glGetUniformLocation(prog_, "uGlyphs"); loc_[UNIFORM_FONT_CURVES_TEX] = glGetUniformLocation(prog_, "uFontCurves"); loc_[UNIFORM_FLAGS] = glGetUniformLocation(prog_, "uFlags"); // generate vertex arrays and vertex buffers glGenVertexArrays(MAX_VERTEX_ARRAYS, vao_); glGenBuffers(MAX_VERTEX_BUFFERS, vbo_); glObjectLabel(GL_VERTEX_ARRAY, vao_[VARR_INSTANCED], -1, "VertexArray-INSTANCED"); glObjectLabel(GL_VERTEX_ARRAY, vao_[VARR_COMPLEX_FILL], -1, "VertexArray-COMPLEX_FILL"); glObjectLabel(GL_BUFFER, vbo_[VBUF_QUAD], -1, "VertexBuffer-PRIM_QUAD"); glObjectLabel(GL_BUFFER, vbo_[VBUF_DATA], -1, "VertexBuffer-DATA"); // initialize vertex array glBindVertexArray(vao_[VARR_INSTANCED]); glEnableVertexAttribArray(ATTR_POS); glEnableVertexAttribArray(ATTR_QUAD_BOUND); glEnableVertexAttribArray(ATTR_TEX_BOUND); glEnableVertexAttribArray(ATTR_TYPE); glEnableVertexAttribArray(ATTR_FLAGS); glEnableVertexAttribArray(ATTR_TRANSFORM_IDX); glEnableVertexAttribArray(ATTR_PAINT_IDX); glEnableVertexAttribArray(ATTR_SCISSOR_IDX); glEnableVertexAttribArray(ATTR_GLYPH_IDX); glEnableVertexAttribArray(ATTR_START); glEnableVertexAttribArray(ATTR_COUNT); glEnableVertexAttribArray(ATTR_RADIUS); glEnableVertexAttribArray(ATTR_STROKE_WIDTH); glEnableVertexAttribArray(ATTR_P0); glEnableVertexAttribArray(ATTR_P1); glEnableVertexAttribArray(ATTR_P2); // instancing quad float a = 1.0f; glm::vec2 quad[] = {{-a, -a}, {a, -a}, {-a, a}, {a, a}}; glBindBuffer(GL_ARRAY_BUFFER, vbo_[VBUF_QUAD]); glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW); glVertexAttribPointer(ATTR_POS, 2, GL_FLOAT, GL_FALSE, 0, offset(0)); // call data // NOTE: integer input attribute should use glVertexAttribIPointer glBindBuffer(GL_ARRAY_BUFFER, vbo_[VBUF_DATA]); glBufferData(GL_ARRAY_BUFFER, 1024 * sizeof(CallData), nullptr, GL_STREAM_DRAW); glVertexAttribPointer(ATTR_QUAD_BOUND, 4, GL_FLOAT, GL_FALSE, sizeof(CallData), offset(offsetof(CallData, quadBound))); glVertexAttribPointer(ATTR_TEX_BOUND, 4, GL_FLOAT, GL_FALSE, sizeof(CallData), offset(offsetof(CallData, texBound))); glVertexAttribIPointer(ATTR_TYPE, 1, GL_INT, sizeof(CallData), offset(offsetof(CallData, type))); glVertexAttribIPointer(ATTR_FLAGS, 1, GL_INT, sizeof(CallData), offset(offsetof(CallData, flags))); glVertexAttribIPointer(ATTR_TRANSFORM_IDX, 1, GL_INT, sizeof(CallData), offset(offsetof(CallData, transformIdx))); glVertexAttribIPointer(ATTR_PAINT_IDX, 1, GL_INT, sizeof(CallData), offset(offsetof(CallData, paintIdx))); glVertexAttribIPointer(ATTR_SCISSOR_IDX, 1, GL_INT, sizeof(CallData), offset(offsetof(CallData, scissorIdx))); glVertexAttribIPointer(ATTR_GLYPH_IDX, 1, GL_INT, sizeof(CallData), offset(offsetof(CallData, glyphIdx))); glVertexAttribIPointer(ATTR_START, 1, GL_INT, sizeof(CallData), offset(offsetof(CallData, start))); glVertexAttribIPointer(ATTR_COUNT, 1, GL_INT, sizeof(CallData), offset(offsetof(CallData, count))); glVertexAttribPointer(ATTR_RADIUS, 1, GL_FLOAT, GL_FALSE, sizeof(CallData), offset(offsetof(CallData, radius))); glVertexAttribPointer(ATTR_STROKE_WIDTH, 1, GL_FLOAT, GL_FALSE, sizeof(CallData), offset(offsetof(CallData, strokeWidth))); glVertexAttribPointer(ATTR_P0, 2, GL_FLOAT, GL_FALSE, sizeof(CallData), offset(offsetof(CallData, p0))); glVertexAttribPointer(ATTR_P1, 2, GL_FLOAT, GL_FALSE, sizeof(CallData), offset(offsetof(CallData, p1))); glVertexAttribPointer(ATTR_P2, 2, GL_FLOAT, GL_FALSE, sizeof(CallData), offset(offsetof(CallData, p2))); // setup instancing glVertexAttribDivisor(ATTR_QUAD_BOUND, 1); glVertexAttribDivisor(ATTR_TEX_BOUND, 1); glVertexAttribDivisor(ATTR_TYPE, 1); glVertexAttribDivisor(ATTR_FLAGS, 1); glVertexAttribDivisor(ATTR_TRANSFORM_IDX, 1); glVertexAttribDivisor(ATTR_PAINT_IDX, 1); glVertexAttribDivisor(ATTR_SCISSOR_IDX, 1); glVertexAttribDivisor(ATTR_GLYPH_IDX, 1); glVertexAttribDivisor(ATTR_START, 1); glVertexAttribDivisor(ATTR_COUNT, 1); glVertexAttribDivisor(ATTR_RADIUS, 1); glVertexAttribDivisor(ATTR_STROKE_WIDTH, 1); glVertexAttribDivisor(ATTR_P0, 1); glVertexAttribDivisor(ATTR_P1, 1); glVertexAttribDivisor(ATTR_P2, 1); CheckGLError("Setup-Instancing"); // generate 1d lookup textures (vec2/float for each texel) const auto flag = TexFlags::T1D | TexFlags::FmtAuto | TexFlags::Nearest; tex_[TEX_POINTS] = createTexture(1024 * POINT_FLOATS / 2, 1, TexFlags::RG32F | flag, nullptr); tex_[TEX_SCISSORS] = createTexture(128 * SCISSOR_FLOATS / 2, 1, TexFlags::RG32F | flag, nullptr); tex_[TEX_PAINTS] = createTexture(128 * PAINT_FLOATS, 1, TexFlags::R32F | flag, nullptr); tex_[TEX_TRANSFORMS] = createTexture(128 * TRANSFORM_FLOATS / 2, 1, TexFlags::RG32F | flag, nullptr); glObjectLabel(GL_TEXTURE, getTextureId(tex_[TEX_POINTS]), -1, "Texture-POINTS"); glObjectLabel(GL_TEXTURE, getTextureId(tex_[TEX_SCISSORS]), -1, "Texture-SCISSORS"); glObjectLabel(GL_TEXTURE, getTextureId(tex_[TEX_PAINTS]), -1, "Texture-PAINTS"); glObjectLabel(GL_TEXTURE, getTextureId(tex_[TEX_TRANSFORMS]), -1, "Texture-TRANSFORMS"); CheckGLError("Create-Lookup-Textures"); // texture buffers needed for font rendering GLuint glyphTexture, curveTexture; glGenTextures(1, &glyphTexture); glGenTextures(1, &curveTexture); // glyphs glBindBuffer(GL_TEXTURE_BUFFER, vbo_[VBUF_FONT_INDICES]); glBufferData(GL_TEXTURE_BUFFER, sizeof(Range) * 1024, nullptr, GL_STATIC_DRAW); glBindTexture(GL_TEXTURE_BUFFER, glyphTexture); glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32I, vbo_[VBUF_FONT_INDICES]); // font curves glBindBuffer(GL_TEXTURE_BUFFER, vbo_[VBUF_FONT_CURVES]); glBufferData(GL_TEXTURE_BUFFER, sizeof(FontCurveData) * 1024, nullptr, GL_STATIC_DRAW); glBindTexture(GL_TEXTURE_BUFFER, curveTexture); glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, vbo_[VBUF_FONT_CURVES]); // register tex_[TEX_FONT_INDICES] = createTexture(glyphTexture, -1, -1, TexFlags::RG32I); // no size information tex_[TEX_FONT_CURVES] = createTexture(curveTexture, -1, -1, TexFlags::R32I); glObjectLabel(GL_TEXTURE, glyphTexture, -1, "Texture-FONT_INDICES"); glObjectLabel(GL_TEXTURE, curveTexture, -1, "Texture-FONT_CURVES"); CheckGLError("Create-Font-Textures"); // cleanup glBindBuffer(GL_ARRAY_BUFFER, 0); glBindTexture(GL_TEXTURE_BUFFER, 0); glBindVertexArray(0); } [/code] Сброс данных о вызовах: [code]void PainterImpl::endFrame() { // translate DrawCommand translateCommands(); if (callBuffer_.empty()) return; if (enum_has_flag(debugFlags_, DebugFlags::WireFrame)) { WireframeMode(true); } // set blend glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_DEPTH_TEST); glUseProgram(prog_); // glActiveTexture(GL_TEXTURE0); // TODO: user provided texture, used for arbitrary gradient or image pattern paint. // scissors - 48bytes, 12 floats, 6 vectors. const auto scissorBufferSize = static_cast(scissorBuffer_.size() * SCISSOR_FLOATS / 2); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_1D, getTextureId(tex_[TEX_SCISSORS])); glTexImage1D(GL_TEXTURE_1D, 0, GL_RG32F, scissorBufferSize, 0, GL_RG, GL_FLOAT, scissorBuffer_.data()); CheckGLError("Upload-Scissors"); // points for primitives const auto pointBufferSize = static_cast(pointBuffer_.size() * POINT_FLOATS / 2); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_1D, getTextureId(tex_[TEX_POINTS])); glTexImage1D(GL_TEXTURE_1D, 0, GL_RG32F, pointBufferSize, 0, GL_RG, GL_FLOAT, pointBuffer_.data()); CheckGLError("Upload-Points"); // paints - 18 floats const auto paintBufferSize = static_cast(paintBuffer_.size() * PAINT_FLOATS); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_1D, getTextureId(tex_[TEX_PAINTS])); glTexImage1D(GL_TEXTURE_1D, 0, GL_R32F, paintBufferSize, 0, GL_RED, GL_FLOAT, paintBuffer_.data()); CheckGLError("Upload-Paints"); // transforms - 6 floats const auto transformBufferSize = static_cast(transformBuffer_.size() * TRANSFORM_FLOATS / 2); glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_1D, getTextureId(tex_[TEX_TRANSFORMS])); glTexImage1D(GL_TEXTURE_1D, 0, GL_RG32F, transformBufferSize, 0, GL_RG, GL_FLOAT, transformBuffer_.data()); CheckGLError("Upload-Transforms"); // font indices buffer glBindBuffer(GL_TEXTURE_BUFFER, vbo_[VBUF_FONT_INDICES]); glBufferData(GL_TEXTURE_BUFFER, fontGlyphBuffer_.getSizeInBytes(), fontGlyphBuffer_.data(), GL_STATIC_DRAW); glActiveTexture(GL_TEXTURE5); glBindTexture(GL_TEXTURE_BUFFER, getTextureId(tex_[TEX_FONT_INDICES])); CheckGLError("Upload-Font-Indices"); // font curves buffer glBindBuffer(GL_TEXTURE_BUFFER, vbo_[VBUF_FONT_CURVES]); glBufferData(GL_TEXTURE_BUFFER, fontCurveBuffer_.getSizeInBytes(), fontCurveBuffer_.data(), GL_STATIC_DRAW); glActiveTexture(GL_TEXTURE6); glBindTexture(GL_TEXTURE_BUFFER, getTextureId(tex_[TEX_FONT_CURVES])); CheckGLError("Upload-Font-Curves"); // set uniforms float win[2] = {winWidth_, winHeight_}; glUniform2fv(loc_[UNIFORM_WIN], 1, win); glUniform1f(loc_[UNIFORM_PX_RATIO], devicePixelRatio_); glUniform1i(loc_[UNIFORM_SCISSORS_TEX], 1); glUniform1i(loc_[UNIFORM_POINTS_TEX], 2); glUniform1i(loc_[UNIFORM_PAINTS_TEX], 3); glUniform1i(loc_[UNIFORM_TRANSFORM_TEX], 4); glUniform1i(loc_[UNIFORM_FONT_INDICES], 5); glUniform1i(loc_[UNIFORM_FONT_CURVES_TEX], 6); glUniform1f(loc_[UNIFORM_AA_WINDOW_SIZE], 1.4f); DebugFlags flags = (debugFlags_ & DebugFlags::FontSuperSampleAA) | (debugFlags_ & DebugFlags::ShowFontControlPoint); glUniform1i(loc_[UNIFORM_FLAGS], static_cast(flags)); // flags used by shader won't exceed "int"'s range CheckGLError("Set-Uniforms"); // bind vertex array glBindVertexArray(vao_[VARR_INSTANCED]); // fill buffer const auto callBufferSize = static_cast(sizeof(CallData) * callBuffer_.size()); glBindBuffer(GL_ARRAY_BUFFER, vbo_[VBUF_DATA]); glBufferData(GL_ARRAY_BUFFER, callBufferSize, callBuffer_.data(), GL_STREAM_DRAW); // draw CheckGLError("Pre-Draw"); glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, callBuffer_.size()); CheckGLError("Draw"); // reset state and cleanup glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_TEXTURE_BUFFER, 0); glBindVertexArray(0); glUseProgram(0); glDisable(GL_BLEND); if (enum_has_flag(debugFlags_, DebugFlags::WireFrame)) { WireframeMode(false); } } [/code] Во время этих двух функций [b]никаких других[/b] вызовов API opengl не происходит, поскольку я просто обновляю callBuffer_. Подробнее здесь: [url]https://stackoverflow.com/questions/79124535/renderdoc-report-no-vertex-shader-bound-at-draw-on-correclty-running-application[/url]