Java 带纹理的VBO,没有不推荐的函数
我正在尝试编写一个基本的四元渲染器,使用VBO、VAO、IBO和着色器。 我试图在添加/删除元素时只使用一个VBO、VAO、IBO和rebuffer来删除数据。 在我决定实现纹理而不是颜色渐变之前,一切都很好 不管我怎么做,它都不会画任何东西,因为我想避免使用不推荐的函数,比如ClientState,或者使用着色器中的纹理 在问题旁边,没有绘制任何内容,我的问题是纹理保存在BRectangle类中,现在我不知道如何在使用抽屉元素时访问它们 我可以重用我的IBO吗,这样我就不必添加额外的索引了 我目前的做法是: 在渲染器中,您可以添加一个矩形atm,它将缓冲所需的数据Java 带纹理的VBO,没有不推荐的函数,java,opengl,lwjgl,vbo,Java,Opengl,Lwjgl,Vbo,我正在尝试编写一个基本的四元渲染器,使用VBO、VAO、IBO和着色器。 我试图在添加/删除元素时只使用一个VBO、VAO、IBO和rebuffer来删除数据。 在我决定实现纹理而不是颜色渐变之前,一切都很好 不管我怎么做,它都不会画任何东西,因为我想避免使用不推荐的函数,比如ClientState,或者使用着色器中的纹理 在问题旁边,没有绘制任何内容,我的问题是纹理保存在BRectangle类中,现在我不知道如何在使用抽屉元素时访问它们 我可以重用我的IBO吗,这样我就不必添加额外的索引了 我
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个浮动步幅,这是不正确的。据我所知,您正在上载4个顶点,每个顶点有6个浮动(4个位置+2个纹理)。这意味着您的位置步幅应为6*FLOAT\u NUM\u字节
你的纹理步幅应该是相同的,因为它被压缩到同一个数组中。在这里,你告诉它texcoords是紧凑的,但实际上每6个浮点数只有一对texcoords。所以这里同样需要6*FLOAT\u NUM\u字节
我可以重用我的IBO吗,这样我就不必添加额外的索引了
是的,您可以使用IBO绘制任意数量的对象,前提是它们都需要相同的索引
其他不那么严肃的评论:
- 您不需要在初始化时将颜色清除为零,它是零
默认李>
- 您不需要在中禁用深度测试/照明
初始化时,默认情况下它们处于关闭状态李>
- 使用着色器时不要调用glEnable(GL_TEXTURE_2D)。这
开关仅为固定管道启用纹理,对着色器程序没有影响。这将产生一个错误,如果你曾经移动到一个核心配置文件,所以只是摆脱它
我更改了步幅,但仍然没有显示任何内容(我的普通gl_四元测试显示纹理)。另外,如何重用IBO?如果我只使用0-3并设置它,则不会绘制下一个四边形。@Frotty我不确定为什么它不会显示,尽管代码中缺少一些关键部分。是否在任何位置设置“mytexture”统一值?能否显示构建纹理的代码(glTexImage2d)?如果你把所有的东西都完整地贴出来,这样就不会遗漏任何东西,那可能是最好的。不,我可能没有设置它。我从3d纹理教程中复制了它,因为我在2d中没有找到任何东西。我把所有东西都放进了存储库。但我也包含非常旧的代码。谢谢你花时间!嗯,代码比我想象的要多。我要检查的另外两件事是:确保将glUniform1i的“纹理统一”值设置为零(如果您使用的是“采样器零”),还确保您的纹理没有使用mipmaps(),我想我不必使用它,因为我使用的是lwjgl纹理?它与glQuad一起工作。同样正如我所说,不需要很多代码,因为ShaderTest只使用我在post中放置的文件以及VBO、IBo等类。无论如何,谢谢,我将尝试查看该链接。。