- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在 Java 中使用 lwjgl 3 开发游戏,它工作正常,但当我想使用着色器时,OpenGL 发送 STACK_UNDERFLOW 错误 (1284)。
我使用 3 个缓冲区:顶点缓冲区、颜色缓冲区、索引缓冲区;
我的旧代码:
private int vbo;
private int cbo;
private int ibo;
private FloatBuffer buffer;
private FloatBuffer colorBuffer;
private IntBuffer indexBuffer;
private IcoSphere sphere;
int radius = 200;
@Override
public void init() {
sphere = new IcoSphere(9, radius);
sphere.generate();
generateBuffer();
}
private void generateBuffer() {
buffer = BufferUtils.createFloatBuffer(sphere.getVertexCount() * 3);
colorBuffer = BufferUtils.createFloatBuffer(sphere.getFacesCount() * 4 * 4);
indexBuffer = BufferUtils.createIntBuffer(sphere.getFacesCount());
Random r = new Random();
OpenSimplexNoise noise = new OpenSimplexNoise();
ArrayList<Vector3f> vertex = sphere.getVertex();
float[] v = new float[vertex.size() * 3];
for (int i = 0; i < vertex.size(); i++) {
vertex.get(i).normalize();
vertex.get(i).mul(sphere.getRadius() + (float) noise.eval(
vertex.get(i).x * 8,
vertex.get(i).y * 8,
vertex.get(i).z * 8
) * 12);
v[i * 3 + 0] = vertex.get(i).x;
v[i * 3 + 1] = vertex.get(i).y;
v[i * 3 + 2] = vertex.get(i).z;
}
buffer.put(sphere.getVertexArray());
indexBuffer.put(sphere.getIndexArray());
for (int i = 0; i < sphere.getFacesCount(); i++) {
colorBuffer.put(new float[] {
r.nextFloat(), r.nextFloat(), r.nextFloat(), 1,
r.nextFloat(), r.nextFloat(), r.nextFloat(), 1,
r.nextFloat(), r.nextFloat(), r.nextFloat(), 1
});
}
buffer.flip();
colorBuffer.flip();
indexBuffer.flip();
createBuffer();
}
private void createBuffer() {
vbo = glGenBuffers();
cbo = glGenBuffers();
ibo = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, cbo);
glBufferData(GL_ARRAY_BUFFER, colorBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
@Override
public void update() {
}
@Override
public void render() {
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexPointer(3, GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, cbo);
glColorPointer(4, GL_FLOAT, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, sphere.getFacesCount() * 3, GL_UNSIGNED_INT, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
添加着色器后我的新代码:
GlUtils.glCall(() -> ..);
用于捕获 opengl 错误。
private int vbo;
private int cbo;
private int ibo;
private FloatBuffer buffer;
private FloatBuffer colorBuffer;
private IntBuffer indexBuffer;
private IcoSphere sphere;
int radius = 200;
@Override
public void init() {
sphere = new IcoSphere(9, radius);
sphere.generate();
generateBuffer();
}
private void generateBuffer() {
buffer = BufferUtils.createFloatBuffer(sphere.getVertexCount() * 3);
colorBuffer = BufferUtils.createFloatBuffer(sphere.getFacesCount() * 4 * 4);
indexBuffer = BufferUtils.createIntBuffer(sphere.getFacesCount());
Random r = new Random();
OpenSimplexNoise noise = new OpenSimplexNoise();
ArrayList<Vector3f> vertex = sphere.getVertex();
float[] v = new float[vertex.size() * 3];
for (int i = 0; i < vertex.size(); i++) {
vertex.get(i).normalize();
vertex.get(i).mul(sphere.getRadius() + (float) noise.eval(
vertex.get(i).x * 8,
vertex.get(i).y * 8,
vertex.get(i).z * 8
) * 12);
v[i * 3 + 0] = vertex.get(i).x;
v[i * 3 + 1] = vertex.get(i).y;
v[i * 3 + 2] = vertex.get(i).z;
}
buffer.put(sphere.getVertexArray());
indexBuffer.put(sphere.getIndexArray());
for (int i = 0; i < sphere.getFacesCount(); i++) {
colorBuffer.put(new float[] {
r.nextFloat(), r.nextFloat(), r.nextFloat(), 1,
r.nextFloat(), r.nextFloat(), r.nextFloat(), 1,
r.nextFloat(), r.nextFloat(), r.nextFloat(), 1
});
}
buffer.flip();
colorBuffer.flip();
indexBuffer.flip();
createBuffer();
}
private void createBuffer() {
vbo = glGenBuffers();
cbo = glGenBuffers();
ibo = glGenBuffers();
GlUtils.glCall(() -> glBindBuffer(GL_ARRAY_BUFFER, vbo));
GlUtils.glCall(() -> glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW));
GlUtils.glCall(() -> glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0));
GlUtils.glCall(() -> glBindBuffer(GL_ARRAY_BUFFER, cbo));
GlUtils.glCall(() -> glBufferData(GL_ARRAY_BUFFER, colorBuffer, GL_STATIC_DRAW));
GlUtils.glCall(() -> glVertexAttribPointer(1, 4, GL_FLOAT, false, 0, 0));
GlUtils.glCall(() -> glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo));
GlUtils.glCall(() -> glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBuffer, GL_STATIC_DRAW));
GlUtils.glCall(() -> glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
GlUtils.glCall(() -> glBindBuffer(GL_ARRAY_BUFFER, 0));
}
@Override
public void update() {
}
@Override
public void render() {
Shader.MAIN.bind();
GlUtils.glCall(() -> glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0));
GlUtils.glCall(() -> glEnableVertexAttribArray(0));
GlUtils.glCall(() -> glEnableVertexAttribArray(1));
GlUtils.glCall(() -> glDrawElements(GL_TRIANGLES, indexBuffer));
GlUtils.glCall(() -> glDisableVertexAttribArray(0));
GlUtils.glCall(() -> glDisableVertexAttribArray(1));
Shader.MAIN.unbind();
}
我的着色器:
碎片
#version 410
out vec4 vertColor;
void main(){
gl_FragColor = vertColor;
}
垂直
#version 410
layout (location=0) in vec3 position;
void main()
{
gl_Position = vec4(position, 1.0);
}
最佳答案
当您使用着色器程序时,您可以使用客户端功能以与之前相同的方式绘制网格。
您所要做的就是使用 glEnableVertexAttribArray
和 glVertexAttribPointer
而不是 glEnableClientState
、glVertexPointer
和 glColorPointer
:
创建缓冲区:
vbo = glGenBuffers();
cbo = glGenBuffers();
ibo = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, cbo);
glBufferData(GL_ARRAY_BUFFER, colorBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBuffer, GL_STATIC_DRAW);
绘制网格
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, cbo);
glVertexAttribPointer(1, 4, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, sphere.getFacesCount() * 3, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
你实际做的是使用默认 Vertex Array Object (0) 为规范。请注意,默认 VAO (0) 仅在兼容性配置文件 OpenGL Context 中有效。 .
<小时/>可以通过使用名为 Vertex Array Object 来改进这一点。请注意,您必须在核心配置文件 OpenGL Context 中使用命名的 VAO :
private int vao;
vao = glGenVertexArrays();
vbo = glGenBuffers();
cbo = glGenBuffers();
ibo = glGenBuffers();
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, cbo);
glBufferData(GL_ARRAY_BUFFER, colorBuffer, GL_STATIC_DRAW);
glVertexAttribPointer(1, 4, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBuffer, GL_STATIC_DRAW);
glBindVertexArray(0);
顶点数组规范在顶点数组对象中声明。因此不需要glDisableVertexAttribArray
。
此外Index buffers (GL_ELEMENT_ARRAY_BUFFER
) 也在 VAO 中说明。 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
会破坏绑定(bind)。
现在,在绘制网格时绑定(bind) VAO 就足够了:
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, sphere.getFacesCount() * 3, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
<小时/>
您有 2 个颜色属性,顶点坐标和颜色。这 2 个属性是 Vertex Shader 的输入。顶点坐标用于设置gl_Position
。颜色必须传递到 Fragment Shader 。它是顶点着色器的输出和片段着色器的输入。在片段着色器中,颜色被写入输出fragColor
。片段着色器的输出写入frambuffer:
顶点着色器:
layout (location=0) in vec3 position;
layout (location=1) in vec4 color;
out vec4 vertColor;
void main()
{
vertColor = color;
gl_Position = vec4(position, 1.0);
}
片段着色器:
#version 410
in vec4 vertColor;
out vec4 fragColor;
void main()
{
fragColor = vertColor;
}
关于java - 当我尝试使用着色器时,OpenGL 向我发送堆栈下溢错误 (Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61040867/
我已经使用 vue-cli 两个星期了,直到今天一切正常。我在本地建立这个项目。 https://drive.google.com/open?id=0BwGw1zyyKjW7S3RYWXRaX24tQ
您好,我正在尝试使用 python 库 pytesseract 从图像中提取文本。请找到代码: from PIL import Image from pytesseract import image_
我的错误 /usr/bin/ld: errno: TLS definition in /lib/libc.so.6 section .tbss mismatches non-TLS reference
我已经训练了一个模型,我正在尝试使用 predict函数但它返回以下错误。 Error in contrasts<-(*tmp*, value = contr.funs[1 + isOF[nn]])
根据Microsoft DataConnectors的信息我想通过 this ODBC driver 创建一个从 PowerBi 到 PostgreSQL 的连接器使用直接查询。我重用了 Micros
我已经为 SoundManagement 创建了一个包,其中有一个扩展 MediaPlayer 的类。我希望全局控制这个变量。这是我的代码: package soundmanagement; impo
我在Heroku上部署了一个应用程序。我正在使用免费服务。 我经常收到以下错误消息。 PG::Error: ERROR: out of memory 如果刷新浏览器,就可以了。但是随后,它又随机发生
我正在运行 LAMP 服务器,这个 .htaccess 给我一个 500 错误。其作用是过滤关键字并重定向到相应的域名。 Options +FollowSymLinks RewriteEngine
我有两个驱动器 A 和 B。使用 python 脚本,我在“A”驱动器中创建一些文件,并运行 powerscript,该脚本以 1 秒的间隔将驱动器 A 中的所有文件复制到驱动器 B。 我在 powe
下面的函数一直返回这个错误信息。我认为可能是 double_precision 字段类型导致了这种情况,我尝试使用 CAST,但要么不是这样,要么我没有做对...帮助? 这是错误: ERROR: i
这个问题已经有答案了: Syntax error due to using a reserved word as a table or column name in MySQL (1 个回答) 已关闭
我的数据库有这个小问题。 我创建了一个表“articoli”,其中包含商品的品牌、型号和价格。 每篇文章都由一个 id (ID_ARTICOLO)` 定义,它是一个自动递增字段。 好吧,现在当我尝试插
我是新来的。我目前正在 DeVry 在线学习中级 C++ 编程。我们正在使用 C++ Primer Plus 这本书,到目前为止我一直做得很好。我的老师最近向我们扔了一个曲线球。我目前的任务是这样的:
这个问题在这里已经有了答案: What is an undefined reference/unresolved external symbol error and how do I fix it?
我的网站中有一段代码有问题;此错误仅发生在 Internet Explorer 7 中。 我没有在这里发布我所有的 HTML/CSS 标记,而是发布了网站的一个版本 here . 如您所见,我在列中有
如果尝试在 USB 设备上构建 node.js 应用程序时在我的树莓派上使用 npm 时遇到一些问题。 package.json 看起来像这样: { "name" : "node-todo",
在 Python 中,您有 None单例,在某些情况下表现得很奇怪: >>> a = None >>> type(a) >>> isinstance(a,None) Traceback (most
这是我的 build.gradle (Module:app) 文件: apply plugin: 'com.android.application' android { compileSdkV
我是 android 的新手,我的项目刚才编译和运行正常,但在我尝试实现抽屉导航后,它给了我这个错误 FAILURE: Build failed with an exception. What wen
谁能解释一下?我想我正在做一些非常愚蠢的事情,并且急切地等待着启蒙。 我得到这个输出: phpversion() == 7.2.25-1+0~20191128.32+debian8~1.gbp108
我是一名优秀的程序员,十分优秀!