当前位置: 首页 > 知识库问答 >
问题:

lwjgl-仅在四边形上渲染左上角像素

龚奇逸
2023-03-14

在过去的几天里,我一直在尝试将纹理缩放为Quad(OpenGL 3)...

但由于某些原因,我只得到渲染到四元网格上的图像左上角像素,我使用平滑的UTIL加载和绑定纹理。。。。

代码如下:

主要游戏。Java语言

package test.game;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.ContextAttribs;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.PixelFormat;
import org.newdawn.slick.opengl.Texture;

import test.engine.Loader;
import test.engine.rendersystem.Model;
import test.engine.rendersystem.ShaderProgram;

import static org.lwjgl.opengl.GL11.*;

import java.io.IOException;
import java.util.HashMap;

public class MainGame {

// Constants
public static final String WINDOW_TITLE = "Neon Indev";
public static final int WIDTH = 800;
public static final int HEIGHT = 480;
public static final ContextAttribs OPENGL_CONTEXTS_ATTRIBS = new ContextAttribs(3, 2).withForwardCompatible(true).withProfileCore(true);
public static final int SYNC_FPS = 60;

static float[] vertexData = 
    {
            -0.5f, 0.5f,
            0.5f, 0.5f,
            0.5f, -0.5f,
            -0.5f, -0.5f
    };
static float[] colorData = { 0f, 1f, 1f, 1f,
                            0f, 1f, 1f, 1f,
                            0f, 1f, 1f, 1f,
                            0f, 1f, 1f, 1f,
                            0f, 1f, 1f, 1f,
                            0f, 1f, 1f, 1f};
static int[] indexData = {
        0, 1, 3,
        3, 1, 2
};

static float[] texData = {
        0,0,
        1,0,
        1,1,
        0,1
};

static Model model;
static ShaderProgram shader;
static Texture testTexture;

public static void main(String[] args) {
    init();
    render();
}

private static void init() {
    // Display Initialization
    try {
        Display.setTitle(WINDOW_TITLE);
        Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
        Display.create(new PixelFormat(), OPENGL_CONTEXTS_ATTRIBS);
    } catch (LWJGLException e) {
        e.printStackTrace();
        System.exit(1);
    }

    // OpenGL Initialization
    glViewport(0, 0, WIDTH, HEIGHT);
    glClearColor(0f, 0f, 0f, 1f);

    model = new Model(vertexData, colorData, indexData);
    try {
        testTexture = Loader.loadTexture("res/images/png/image02 (1).png", "PNG");
    } catch (IOException e) {
        e.printStackTrace();
        System.exit(1);
    }
    model.setTexture(testTexture, texData);


    // Shader Initialization
    HashMap<String, Integer> vboDataToBind = new HashMap<String, Integer>();
    vboDataToBind.put("in_Position", Model.ATTRIB_VERTEX);
    vboDataToBind.put("in_Color", Model.ATTRIB_COLOR);
    vboDataToBind.put("in_TextureCoord", Model.ATTRIB_TEXTURE);

    shader = new ShaderProgram("res/shaders/frag/color.frag", "res/shaders/vert/color.vert", true, true, vboDataToBind);
}

private static void render() {
    // Resize Check
    if (Display.wasResized()) {
        resize();
    }

    // Render loop
    while (!Display.isCloseRequested()) {

        glClear(GL_COLOR_BUFFER_BIT);

        shader.bind();
        model.render();
        shader.unbind();

        Display.update();
        Display.sync(SYNC_FPS);
    }

    // Dispose if out of the loop
    dispose();
}

private static void resize() {
    // Resize code goes here
}

private static void dispose() {
    model.dispose();
    shader.dispose();
    Display.destroy();
}

}

着色器程序。Java语言

package test.game.engine.rendersystem;

import java.io.IOException;
import java.util.HashMap;
import java.util.Set;

import test.engine.Loader;

import static org.lwjgl.opengl.GL20.*;

public class ShaderProgram {

String fragmentShader;
String vertexShader;

int programID, vertexShaderID, fragmentShaderID;
boolean initialized;

public ShaderProgram(String fragmentShader, String vertexShader, boolean url, boolean init, HashMap<String, Integer> vboDataToBind) {
    if (url) {
        try {
            this.fragmentShader = Loader.getStringFromTextFile(fragmentShader);
            this.vertexShader = Loader.getStringFromTextFile(vertexShader);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    } else {
        this.fragmentShader = fragmentShader;
        this.vertexShader = vertexShader;
    }

    if (init) {
        init(vboDataToBind);
        this.initialized = true;
    } else {
        this.initialized = false;
    }
}

public void init(HashMap<String, Integer> vboDataToBind) {
    if (!initialized) {
        // Initialize the shaders
        vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
        fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

        // Setting up the shader values
        glShaderSource(vertexShaderID, vertexShader);
        glShaderSource(fragmentShaderID, fragmentShader);

        // Compile the shaders
        glCompileShader(vertexShaderID);
        glCompileShader(fragmentShaderID);

        // Create the shader program and attach them
        programID = glCreateProgram();
        glAttachShader(programID, vertexShaderID);
        glAttachShader(programID, fragmentShaderID);

        // Bind any needed data
        if (!vboDataToBind.isEmpty()) {
            Set<String> keys = vboDataToBind.keySet();
            for (String key : keys) {
                bindVBOAttrib(vboDataToBind.get(key), key);
            }
        }

        // Link and validate the program
        glLinkProgram(programID);
        glValidateProgram(programID);
    }
}

public void bind() {
    glUseProgram(programID);
}

public void unbind() {
    glUseProgram(0);
}

public void dispose() {
    glDeleteProgram(programID);
    glDeleteShader(vertexShaderID);
    glDeleteShader(fragmentShaderID);
}

public void bindVBOAttrib(int attribNumber, String variableName) {
    glBindAttribLocation(programID, attribNumber, variableName);
}

public String getFragmentShader() {
    return fragmentShader;
}
public String getVertexShader() {
    return vertexShader;
}

public int getProgramID() {
    return programID;
}

public int getVertexShaderID() {
    return vertexShaderID;
}

public int getFragmentShaderID() {
    return fragmentShaderID;
}
}

顶点着色器:

#version 150 core

in vec4 in_Position;
in vec4 in_Color;
in vec2 in_TextureCoord;

out vec4 pass_Color;
out vec2 pass_TextureCoord;

void main(void) {
gl_Position = in_Position;

pass_Color = in_Color;
pass_TextureCoord = in_TextureCoord;
}

片段着色器:

#version 150 core

uniform sampler2D texture_diffuse;

in vec4 pass_Color;
in vec2 pass_TextureCoord;

out vec4 out_Color;

void main(void) {
out_Color = pass_Color;
// Override out_Color with our texture pixel
out_Color = texture(texture_diffuse, pass_TextureCoord);
}

装载机。Java语言

package test.game.engine;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;

public class Loader {

public static String getStringFromTextFile(String url) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader(new File(url)));
    String line;
    StringBuilder response = new StringBuilder();
    while ((line = reader.readLine()) != null) {
        response.append(line).append("\n");
    }
    reader.close();
    return response.toString();
}

public static Texture loadTexture(String url, String format) throws IOException {
    return TextureLoader.getTexture(format, ResourceLoader.getResourceAsStream(url));
}

}

模型Java语言

package test.game.engine.rendersystem;

import static org.lwjgl.opengl.GL30.*;
import static org.lwjgl.opengl.GL13.*;
import static org.lwjgl.opengl.GL11.*;

import org.newdawn.slick.opengl.Texture;

public class Model {

// Attribute Numbers
public static final int ATTRIB_VERTEX = 0;
public static final int ATTRIB_INDEX = 1;
public static final int ATTRIB_COLOR = 2;
public static final int ATTRIB_TEXTURE = 3;

// Dimensions
public static final int DIMEN_VERTEX = 2;
public static final int DIMEN_INDEX = 1;
public static final int DIMEN_COLOR = 4;
public static final int DIMEN_TEXTURE = 2;

int vaoID;
int vertexCount;
VBO vertexData;
VBO colorData;
VBO textureData;
IntVBO indexData;

boolean textured;
Texture texture;

public Model(float[] vertexData, float[] colorData, int[] indexData) {
    this.vertexCount = vertexData.length;
    this.vaoID = glGenVertexArrays();
    this.textured = false;

    bindVertexArray();
    this.vertexData = new VBO(ATTRIB_VERTEX, vaoID, vertexData, DIMEN_VERTEX, true);
    this.colorData = new VBO(ATTRIB_COLOR, vaoID, colorData, DIMEN_COLOR, true);
    this.indexData = new IntVBO(ATTRIB_INDEX, vaoID, indexData, DIMEN_INDEX, true);
    unbindVertexArray();
}

public boolean isTextured() {
    return textured;
}

public void setTexture(Texture texture, float[] texCoords) {
    this.textured = true;
    this.textureData = new VBO(ATTRIB_TEXTURE, vaoID, texCoords, DIMEN_TEXTURE, true);
    this.texture = texture;
}

public void unbindVertexArray() {
    glBindVertexArray(0);
}

public void bindVertexArray() {
    glBindVertexArray(vaoID);
}

public void dispose() {
    vertexData.dispose();
    colorData.dispose();
    indexData.dispose();
    glDeleteVertexArrays(vaoID);
}

public void render() {
    bindVertexArray();
    colorData.bind();
    vertexData.bind();
    if (textured) textureData.bind();
    indexData.bind();

    vertexData.enable();
    if (textured) textureData.enable();
    colorData.enable();
    indexData.enable();

    // Loading in the texture data
    if (textured) {
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture.getTextureID());
    }

    glDrawElements(GL_TRIANGLES, this.vertexCount, GL_UNSIGNED_INT, 0);

    colorData.disable();
    vertexData.disable();
    indexData.disable();
    if (textured) textureData.disable();

    vertexData.unbind();
    colorData.unbind();
    indexData.unbind();
    if (textured) textureData.disable();

    unbindVertexArray();
}
}

vbo. java

package test.game.engine.rendersystem;

import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL11.*;

import java.nio.FloatBuffer;

import org.lwjgl.BufferUtils;

import static org.lwjgl.opengl.GL15.*;

public class VBO {

public int vboID;
public int attributeNumber;
public int vaoID;
public int dataDimensions;
public float[] data;

public VBO(int attributeNumber, int vaoID, float[] data, int dimensions, boolean loadToVBO) {
    this.attributeNumber = attributeNumber;
    this.vaoID = vaoID;
    this.data = data;
    this.dataDimensions = dimensions;

    if (loadToVBO) {
        loadToVBO();
    }
}

public void loadToVBO() {
    this.vboID = glGenBuffers();
    bind();
    glBufferData(GL_ARRAY_BUFFER, storeDataInFloatBuffer(), GL_STATIC_DRAW);
    glVertexAttribPointer(attributeNumber, dataDimensions, GL_FLOAT, false, 0, 0);
    unbind();
}

public void bind() {
    glBindBuffer(GL_ARRAY_BUFFER, vboID);
}

public void unbind() {
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

public void enable() {
    glEnableVertexAttribArray(attributeNumber);
}

public void disable() {
    glDisableVertexAttribArray(attributeNumber);
}

public void dispose() {
    glDeleteBuffers(vboID);
}

private FloatBuffer storeDataInFloatBuffer() {
    FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length);
    buffer.put(data);
    buffer.flip();
    return buffer;
}

}

这是我想要渲染的图像(它是测试图像)(PNG格式)一头奶牛:

这是我得到的输出。四边形上的一头牛:

P、 我是OpenGL和低级图形API的新手。。。。如果我犯了任何新手/新手的错误,请原谅我。

共有1个答案

常甫
2023-03-14

我相信你的问题就出在这里:

public void setTexture(Texture texture, float[] texCoords) { 
this.textured = true; 
this.textureData = new VBO(ATTRIB_TEXTURE, vaoID, texCoords, DIMEN_TEXTURE, true);
this.texture = texture; 
}

当您创建初始vbo时,您绑定了VAO,然后解除了它的绑定,这允许绘图发生,但是当您添加纹理坐标时,没有VAO绑定,导致您的vbo没有绑定到任何东西。当调用渲染并且没有找到调用的纹理坐标时,因此使用默认的0; 0坐标,也就是单角像素。

 类似资料:
  • 我已经试着让这段代码工作了一段时间,但我仍然不知道我做错了什么。(LWJGL-Java) 我曾尝试在网上查看其他人的代码,但我找不到任何重大区别。事实上,我学会了将OpenGL与C结合使用,所以我的大脑可能会被它卡住,这可能就是我找不到错误的原因。 这是init(调用一次) 这是渲染函数: 着色器: 顶点: Framgent公司:

  • (这是我第二次问这个问题了。上次我得到了一个没有解决问题的答案(那里的答案提到了我试图修复这个问题时偶然留下的一点代码)。我还稍微改变了问题本身——我改变了代码的顺序,把我认为错误更高的部分放在前面,并补充说我正在使用macOS,这可能是它不起作用的原因)。 所以,我刚刚开始学习LWJGL 3,我混合使用了一些教程和示例代码来制作一些东西,应该使用VAOs和VBOs将矩形渲染到洋红屏幕上。没有错误

  • 背景信息: 我正在使用OpenGL和LWJGL 3在屏幕上绘制一些四边形。我需要知道鼠标何时在四轴上。当我将四边形渲染到屏幕上时,我使用OpenGL坐标,X和Y的范围是从-1到1,而(0,0)在屏幕的中心。当我得到我使用的鼠标位置时 这给了我从0到窗口宽度或高度的坐标,在左上角(标题栏下方)有(0,0)。然后取鼠标坐标并计算OpenGL坐标。 例如,如果我的窗口大小为(800,600),而我的鼠标

  • 最近,我决定重温一些LWJGL渲染代码,这些代码是我根据LWJGLWiki上的教程使用索引VBOs编写的。在我的台式电脑上,一切正常,但当我切换到学校笔记本电脑时,它拒绝渲染任何内容。 我有以下渲染代码: GL20.glUseProgram(pId);System.out.println(“NO Error? ” (GL11.glGetError() == GL11.GL_NO_ERROR));

  • 我正在使用LWJGL 2.8.5开发一个3D可视化应用程序。在阅读了项目主页上的第一个教程后,我还阅读了一本OpenGL书籍,进行了更深入的分析。我看到OpenGL中的典型过程是在init函数中绘制场景,然后简单地在一个循环中调用显示的更新。 但是,当我尝试使用LWJGL时,我在显示屏中得到了闪烁效果。消除闪烁的唯一方法是在显示更新周期中重绘场景。为什么会发生这种情况? 为了更好地解释我的问题,我

  • 我到处都找过了,我似乎无法让OpenGL绘制一个简单的四边形。窗口在正确的颜色背景下显示得很好,但OpenGL就是不会绘制框。我正在使用OpenGL 4.4.0-构建20.19.15.4463窗口大小为1920x1080 这是我目前拥有的代码: 在Main.java: 在实体框中: