过去几天我一直在尝试将纹理缩放到Quad(OpenGL 3)......
但由于某种原因,我只得到渲染到四边形的图像的左上角像素,我使用Slick-Utils来加载和绑定纹理....
以下是代码:
MainGame.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();
}
}
ShaderProgram.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;
}
Fragment Shader:
#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);
}
Loader.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));
}
}
Model.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.S我是OpenGL和低级图形API的新手....如果我做了任何新手/ noob错误,请原谅我。
答案 0 :(得分:0)
我相信你的问题在于:
public void setTexture(Texture texture, float[] texCoords) {
this.textured = true;
this.textureData = new VBO(ATTRIB_TEXTURE, vaoID, texCoords, DIMEN_TEXTURE, true);
this.texture = texture;
}
当您创建初始vbos时,您绑定了VAO然后解除绑定它允许绘图发生,但是当您添加纹理坐标时,没有绑定VAO导致您的vbo绑定到任何内容。然后调用渲染并找到没有任何内容的纹理坐标,因此使用默认的0; 0坐标,也就是单角像素。