gpt4 book ai didi

java - 带纹理的 VBO,没有弃用的功能

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:32:31 25 4
gpt4 key购买 nike

我正在尝试使用 VBO、VAO、IBO 和着色器编写一个基本的四边形渲染器。我试图主要只使用一个 VBO、VAO、IBO,并在添加/删除元素时重新缓冲数据。大多数情况下一切正常,直到我决定实现纹理而不是颜色分级。

无论我尝试什么,它都不会绘制任何内容,因为我想避免使用已弃用的函数(如 ClientStates),并可能使用着色器中的纹理。

除了什么都没有绘制的问题之外,我还遇到了纹理保存在 BRectangle 类中的问题,现在我不知道如何在使用 DrawElements 时访问它们。

我可以重复使用我的 IBO,这样我就不必添加额外的索引了吗?

我目前的做法:

Renderer,你可以添加一个Rectangle atm,它会缓冲需要的数据。

    public class ShaderRenderer {

public static final int POSITION_INDEX = 0; // index of vertex attribute "in_Position"
public static final int TEXTURE_INDEX = 1; // index of vertex attribute "in_Texture"

public static final int FLOAT_NUM_BYTES; // sizeof(float) in bytes
public static final int INT_NUM_BYTES; // sizeof(int) in bytes
public static final int VEC4_BYTES; // sizeof(vec4) in bytes

static {
FLOAT_NUM_BYTES = Float.SIZE / Byte.SIZE;
INT_NUM_BYTES = Integer.SIZE / Byte.SIZE;
VEC4_BYTES = 4 * FLOAT_NUM_BYTES;
}

private VAO vao = new VAO();
private VBO vbo = new VBO();
private IBO ibo = new IBO();

private int elements = 0;

public ShaderRenderer() {
try {
ShaderUtilities.compileShader("shaders/screen.vert", "shaders/screen.frag", POSITION_INDEX, TEXTURE_INDEX);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public void add( BRectangle rect ) {

// Bind the VAO
// This OpenGL-object groups the "in_Position" and "in_Color"
// vertex attributes.
vao.bind();

// Bind the VBO and add the FloatBuffer from the Rect
vbo.bind();
vbo.addBuffer(rect.vertexData);

ibo.bind();
ibo.addIndices(generateIndices());
ibo.buffer();

//==============================================================
// Now we tell OpenGL that we will use POSITION_INDEX and COLOR_INDEX
// to communicate respectively the vertex positions and vertex colors
// to our shaders.
{
// First we enable the indices. This will affect the vertex
// array object from above.
glEnableVertexAttribArray(POSITION_INDEX);
Util.checkGLError();


// Then we tell OpenGL how it should read the GL_ARRAY_BUFFER
// (to which we have bound our vertex data, see above).

// The position data starts at the beginning of the vertex data
glVertexAttribPointer(POSITION_INDEX, 4, GL_FLOAT, false,
2 * VEC4_BYTES, 0);
Util.checkGLError();

// The color data starts after the first 4 floats of position data
glVertexAttribPointer(TEXTURE_INDEX, 2, GL_FLOAT, false,
0, VEC4_BYTES);
Util.checkGLError();
}

vbo.bufferData();

// Just to be VERY clean, we will unbind the vertex attribute object
// and only bind it when we render. This way we cannot accidentally modify
// it anymore.
vao.unbind();

// Only after the vertex array is disabled, we unbind the buffers
// to the GL_ARRAY_BUFFER and GL_ELEMENT_ARRAY_BUFFER targets, because
// otherwise the vertex array object would become invalid again.
vbo.unbind();

ibo.unbind();
}

void DestroyVBO() {

glDisableVertexAttribArray(POSITION_INDEX);
Util.checkGLError();

glDisableVertexAttribArray(TEXTURE_INDEX);
Util.checkGLError();

glBindBuffer(GL_ARRAY_BUFFER, 0);
Util.checkGLError();

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
Util.checkGLError();

glDeleteBuffers(ibo.id);
Util.checkGLError();

glDeleteBuffers(vbo.id);
Util.checkGLError();

glBindVertexArray(0);
Util.checkGLError();

glDeleteVertexArrays(vao.id);
Util.checkGLError();
}


private int[] generateIndices() {
int c = elements * 3;
int v[] = { c, c+1, c+2,
c, c+3, c+2};
elements++;
return v;
}

public void render () {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Util.checkGLError();


vao.bind();
glDrawElements(
GL_TRIANGLES,
ibo.size,
GL_UNSIGNED_INT,
0);
Util.checkGLError();

vao.unbind();
}

}

我的基本矩形类

public class BRectangle  {
final int amountOfVertices = 8;
final int vertexSize = 3;
final int textureSize = 2;

public FloatBuffer vertexData;

Texture texture;

public BRectangle(float x, float y ) {
float[] VerticesArray = new float[]{
-0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.1f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
-0.1f, 0.4f, 0.0f, 1.0f, 1.0f, 1.0f,
-0.5f, 0.4f, 0.0f, 1.0f, 0.0f, 1.0f
};
vertexData = BufferUtils.createFloatBuffer(24);
vertexData.put(VerticesArray);



try {
texture = Textures.loadTexture("data/floor.jpg");
} catch (IOException e) {
e.printStackTrace();
}
glBindTexture(GL_TEXTURE_2D, texture.getTextureID());

}

}

main[] 的测试

public class ShaderTest {

ShaderRenderer sr;

FpsCounter c;

public ShaderTest() {
}

public void create() throws LWJGLException, Exception {

new SimpleDisplay(800, 600, "test", false, false);
glOrtho(0, 800, 0, 600, 1, -1);
//Keyboard
Keyboard.create();

c = new FpsCounter();

Textures.setUpTextureLoader();

//Mouse
Mouse.setGrabbed(false);
Mouse.create();

sr = new ShaderRenderer();
//OpenGL
initGL();


}


public void destroy() {
Mouse.destroy();
Keyboard.destroy();
Display.destroy();
}

public void initGL() throws IOException {



ShaderUtilities.compileShader("shaders/screen.vert", "shaders/screen.frag", ShaderRenderer.POSITION_INDEX, ShaderRenderer.TEXTURE_INDEX);
sr.add(new BRectangle(0f, 0f));
}

public void processKeyboard() {
}

public void processMouse() {
}

public void render() throws LWJGLException {
sr.render();
}


public void run() throws LWJGLException {
while (!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
if (Display.isVisible()) {
processKeyboard();
processMouse();
update();
render();
} else {
if (Display.isDirty()) {
render();
}
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
}

Display.update();
//Display.sync(60);
}
}

public void update() {
c.updateFPS();
}

public static void main(String[] args) {
ShaderTest main = null;
try {
main = new ShaderTest();
main.create();
main.run();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (main != null) {
main.destroy();
}
}
}
}

和 openglinit

public static void initGLSlim() {
glClearColor(0, 0, 0, 0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);

glEnable(GL11.GL_TEXTURE_2D);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 800, 600, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

}

顶点着色器

#version 140

in vec4 in_Position;
in vec2 in_Texture;
out vec2 out_Texture;

void main(void)
{
gl_Position = vec4(in_Position.x *0.75 ,in_Position.y, in_Position.z, in_Position.w);
out_Texture = in_Texture;
}

片段着色器

#version 140

in vec2 out_Texture;
uniform sampler2D mytexture;
out vec4 fragColor;

void main(void)
{
fragColor = texture2D(mytexture, out_Texture);
}

最佳答案

您的步幅参数不正确。

这是你拥有的:

glVertexAttribPointer(POSITION_INDEX, 4, GL_FLOAT, false, 2 * VEC4_BYTES, 0); 
glVertexAttribPointer(TEXTURE_INDEX, 2, GL_FLOAT, false, 0, VEC4_BYTES);

您告诉位置索引它有 8 个 float 步幅,这是不正确的。据我所知,您正在上传 4 个顶点,每个顶点有 6 个 float (4x 位置 + 2x 纹理)。这意味着您的 POSITION 步幅应该是 6 * FLOAT_NUM_BYTES

你的纹理步幅应该是相同的,因为它被打包到同一个数组中。在这里你告诉它 texcoords 是紧密包​​装的,但实际上每 6 个 float 只有一对 texcoords。因此,您在这里再次需要 6 * FLOAT_NUM_BYTES


And can I reuse my IBO, so I don't have to add the additional indices?

是的,您可以使用 IBO 绘制任意数量的对象,前提是它们都需要相同的索引。


其他不太严肃的评论:

  • 你不需要在初始化时将 clearColor 置零,它是零默认。
  • 你不需要禁用 depth_test/lighting初始化,默认情况下它们是关闭的。
  • 在使用着色器时不要调用 glEnable(GL_TEXTURE_2D)。这switch 只为固定管道启用纹理,它对着色器程序没有影响。如果您移动到核心配置文件,这将产生错误,因此只需删除它即可。

关于java - 带纹理的 VBO,没有弃用的功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12179302/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com