- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我是 OpenGL 的新手,目前正在处理一个简单的程序。
我遇到的问题是当我传递一个数组来表示点的颜色时,颜色最终变成了黑色。如果我只是在片段着色器中明确定义一种颜色,并且如果我在 VAO 中切换数据索引,则三角形会移动到颜色点。
我尝试使用 API 跟踪并得到以下信息:
6872: message: major api error 1282: GL_INVALID_OPERATION error generated. <program> is not a program object, or <shader> is not a shader object.
6872 @0 glAttachShader(program = 1, shader = 1)
6872: warning: glGetError(glAttachShader) = GL_INVALID_OPERATION
6876: message: major api error 1282: GL_INVALID_OPERATION error generated. Handle does not refer to the expected type of object (GL_SHADER_OBJECT_ARB).
6876 @0 glDeleteShader(shader = 1)
6876: warning: glGetError(glDeleteShader) = GL_INVALID_OPERATION
6878: message: major api error 1282: GL_INVALID_OPERATION error generated. Handle does not refer to the expected type of object (GL_SHADER_OBJECT_ARB).
6878 @0 glDeleteShader(shader = 1)
6878: warning: glGetError(glDeleteShader) = GL_INVALID_OPERATION
Rendered 507 frames in 8.52598 secs, average of 59.4653 fps
我所有的代码都是 here , 但它正在进行中。可能导致某种类型问题的位是下面的绘图部分:
// TODO: Use this code once per mesh
// Make a VBO to hold points
GLuint vbo = 0;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, points.size() * sizeof(GLfloat), &points[0], drawType);
// VBO TO hold colors
GLuint colorVbo = 0;
glGenBuffers(1, &colorVbo);
glBindBuffer(GL_ARRAY_BUFFER, colorVbo);
float colors[] = {
0.5, 0.0, 0.0,
0.0, 0.5, 0.0,
0.0, 0.0, 0.5
};
glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), colors, GL_STATIC_DRAW);
// Make a VAO for the points VBO
GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Points
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
// Colors
glBindBuffer(GL_ARRAY_BUFFER, colorVbo);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
GLint colorpos = glGetAttribLocation(Program::getCurrentProgram(), "vertColor");
glEnableVertexAttribArray(0); // Points
glEnableVertexAttribArray(1); // Colors
glLinkProgram(Program::getCurrentProgram());
// Draw Mesh
glDrawArrays(drawShape, 0, points.size()/2);
}
您可能需要了解的一些事情是 points
是 Vector<float>
, Program::getCurrentProgram()
是一个返回当前正在使用的程序的静态函数,drawShape
在这种情况下是 GL_TRIANGLES
.
顶点着色器:
#version 400 core
layout(location=0) in vec3 vert;
layout(location=1) in vec3 vertColor;
out vec3 color;
void main()
{
color = vertColor;
gl_Position = vec4(vert, 1);
}
片段着色器:
#version 400 core
in vec3 color;
out vec4 finalColor;
void main()
{
finalColor = vec4(color, 1.0);
}
如果这是一个需要仔细研究的问题,我深表歉意。在过去一天左右的时间里,我环顾四周,尝试了几种不同的方法,但都没有用。如果需要任何其他信息以便其他人不必整理我的所有代码,请告诉我。
我从 apitrace 得到的结果似乎表明我可能对着色器 ID 做错了什么,尽管如果我将颜色编码到片段着色器中并且颜色随后起作用,该错误仍然会发生。
我正在使用 GLFW 创建我的 OpenGL 上下文。我已经设置了一个错误回调,但我没有从中得到任何东西,我的印象是它也应该通过 OpenGL 错误,尽管我在他们的常见问题解答中没有看到任何明确说明这一点。
我还在编译着色器和链接程序时检查错误,但那里也没有发生任何事情。
此外,我想知道使用 C++ 是否会在对象超出范围和 delete
时冒丢失 OpenGL 状态的风险被称为。
编辑:这里有一些我没有展示的提到的东西:
着色器初始化:
// Create OpenGL Shader
shaderID = glCreateShader(shaderType);
glShaderSource(shaderID, 1, &cShaderString, NULL);
// Compile
glCompileShader(shaderID);
Shader Destructor 只是调用 glDeleteShader(shaderID);
这是非常标准的。这是在着色器类和 shaderID
的构造函数中是 Shader
的成员变量. shaderType
是 GLenum
在这种情况下是 GL_VERTEX_SHADER
或 GL_FRAGMENT_SHADER
.
程序初始化: //创建程序 programID = glCreateProgram();
// Iterate through Shaders
for(std::vector<Shader>::iterator shader = shaders.begin(); shader != shaders.end(); shader++)
{
// Attach Shader
glAttachShader(programID, shader->getShaderID());
}
// Link program
glLinkProgram(programID);
程序析构函数:
// Iterate through attached shaders
for(std::vector<Shader>::iterator shader = shaders.begin(); shader != shaders.end(); shader++)
{
// Detach Shader
glDetachShader(programID, shader->getShaderID());
}
// Delete program
glDeleteProgram(programID);
再一次,这看起来很标准并且在 Program
的构造函数中类。
编辑 2: 在弄乱了一些代码之后,我发现了一件相当奇怪的事情。如果我将创建和绑定(bind)缓冲区并将三角形绘制到我用作表示三角形的类的构造函数的代码移动,我得到的位置是颜色而不是位置。这与我在数据上切换索引(位置为 1,颜色为 0)时发生的事情相同。
Edit 3: 实际上,仔细看了一下,它似乎画了一个与颜色完全不同的三角形。为 Triangle 类创建一个 vao 成员并在绘制时绑定(bind)它似乎解决了这个问题。
编辑 4: 似乎 glValidateProgram()
确实产生了成功的结果,这让我怀疑它的着色器有问题。
最佳答案
Also, I was wondering if using C++ could risk losing OpenGL states once an object goes out of scope and delete is called.
是的,有。我相信这正是这里正在发生的事情。这并不意味着您不能将 OpenGL 对象包装在 C++ 类中,但您必须非常小心。
您在这里遇到的问题是您在 C++ 对象的析构函数中删除了包装的 OpenGL 对象。因此,只要其中一个对象超出范围,或由于任何其他原因被销毁,它就会带走相应的 OpenGL 对象。
如果您复制对象,这会导致特别难看的问题。让我们看一个人工示例:
Shader a(...);
{
Shader b = a;
}
在此之后,您在a
的构造函数中创建的OpenGL 对象将被删除。当创建 b
作为 a
的拷贝时,默认的复制构造函数会将存储在 a
中的着色器 id 复制到 b
。然后,当 b
超出范围时,其析构函数会删除着色器 ID。它仍然存储在a
中,但现在无效了。
当然你不会像上面那样写代码。但是,如果您按值将对象传递给函数/方法,您可能会遇到非常相似的情况,这部分发生在您的代码中。
更危险的是,因为更难识别,如果将这些对象存储在像 std::vector
这样的容器中会发生什么。 vector
在添加新元素会超出其当前容量时重新分配其内存。在重新分配期间,它会创建 vector
中所有现有元素的拷贝(调用复制构造函数),然后销毁原始元素。这又与上面的示例非常相似,您最终会得到引用已删除 OpenGL 对象的对象。
这正是您的情况。您将 Shader
对象插入一个 vector
,并且已经在 vector
中的对象的 OpenGL id 作为 的一部分被删除vector
在你插入更多元素时被重新分配。
核心问题是不能安全地复制这些C++对象。默认复制行为(按成员分配)不起作用。通常,您需要在 C++ 中为默认实现不足的类实现复制构造函数和赋值运算符。但是,如果您将 OpenGL 对象的 ID 作为成员,那么确实没有什么好方法可以做到这一点,除非您实现更复杂的方案,可能涉及共享子对象、引用计数等。
我一直建议的一件事是为无法正确复制的类设置私有(private)复制构造函数和赋值运算符。如果您不小心复制对象,这将确保您得到编译时错误,而不是神秘的运行时行为。
然后,要将对象存储在容器中,最简单的方法是在容器中存储指向对象的指针,而不是对象本身。您可以在执行此操作时使用智能指针(例如 smart_ptr
)来简化内存管理。
关于c++ - 传递给着色器的颜色不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26665382/
我之前让 dll 注入(inject)器变得简单,但我有 Windows 7,我用 C# 和 C++ 做了它,它工作得很好!但是现在当我在 Windows 8 中尝试相同的代码时,它似乎没有以正确的方
我正在尝试制作一个名为 core-splitter 的元素,该元素在 1.0 中已弃用,因为它在我们的项目中起着关键作用。 如果您不知道 core-splitter 的作用,我可以提供一个简短的描述。
我有几个不同的蜘蛛,想一次运行所有它们。基于 this和 this ,我可以在同一个进程中运行多个蜘蛛。但是,我不知道如何设计一个信号系统来在所有蜘蛛都完成后停止 react 器。 我试过了: cra
有没有办法在达到特定条件时停止扭曲 react 器。例如,如果一个变量被设置为某个值,那么 react 器应该停止吗? 最佳答案 理想情况下,您不会将变量设置为一个值并停止 react 器,而是调用
https://code.angularjs.org/1.0.0rc9/angular-1.0.0rc9.js 上面的链接定义了外部js文件,我不知道Angular-1.0.0rc9.js的注入(in
我正在尝试运行一个函数并将服务注入(inject)其中。我认为这可以使用 $injector 轻松完成.所以我尝试了以下(简化示例): angular.injector().invoke( [ "$q
在 google Guice 中,我可以使用函数 createInjector 创建基于多个模块的注入(inject)器。 因为我使用 GWT.create 在 GoogleGin 中实例化注入(in
我在 ASP.NET Core 1.1 解决方案中使用配置绑定(bind)。基本上,我在“ConfigureServices Startup”部分中有一些用于绑定(bind)的简单代码,如下所示: s
我在 Spring MVC 中设置 initBinder 时遇到一些问题。我有一个 ModelAttribute,它有一个有时会显示的字段。 public class Model { privat
我正在尝试通过jquery post发布knockoutjs View 模型 var $form = $('#barcodeTemplate form'); var data = ko.toJS(vm
如何为包含多态对象集合的复杂模型编写自定义模型绑定(bind)程序? 我有下一个模型结构: public class CustomAttributeValueViewModel { publi
您好,我正在尝试实现我在 this article 中找到的扩展方法对于简单的注入(inject)器,因为它不支持开箱即用的特定构造函数的注册。 根据这篇文章,我需要用一个假的委托(delegate)
你好,我想自动注册我的依赖项。 我现在拥有的是: public interface IRepository where T : class public interface IFolderReposi
我正在使用 Jasmine 测试一些 Angular.js 代码。为此,我需要一个 Angular 注入(inject)器: var injector = angular.injector(['ng'
我正在使用 Matlab 代码生成器。不可能包含代码风格指南。这就是为什么我正在寻找一个工具来“ reshape ”、重命名和重新格式化生成的代码,根据我的: 功能横幅约定 文件横幅约定 命名约定 等
这个问题在这里已经有了答案: Where and why do I have to put the "template" and "typename" keywords? (8 个答案) 关闭 8
我开发了一种工具,可以更改某些程序的外观。为此,我需要在某些进程中注入(inject)一个 dll。 现在我基本上使用这个 approach .问题通常是人们无法注入(inject) dll,因为他们
我想使用 swing、spring 和 hibernate 编写一个 java 应用程序。 我想使用数据绑定(bind)器用 bean 的值填充 gui,并且我还希望它反射(reflect) gui
我有这段代码,当两个蜘蛛完成后,程序仍在运行。 #!C:\Python27\python.exe from twisted.internet import reactor from scrapy.cr
要点是 Spring Batch (v2) 测试框架具有带有 @Autowired 注释的 JobLauncherTestUtils.setJob。我们的测试套件有多个 Job 类提供者。因为这个类不
我是一名优秀的程序员,十分优秀!