IM使用Java和Lwjgl作为Opengl接口。
我参与了基于C ++的this Tutorial,第一部分工作。第二部分,纹理,我无法实现。我现在在网上搜索了2天,但没有什么比这更好的了。
运行此程序会创建一个窗口,我可以看到浅蓝色背景,仅此而已。
我在游戏圈中获得此行的无效值错误:
GL20.glUniform1i(GL20.glGetUniformLocation(shaderProgramID, "tex"), GL13.GL_TEXTURE0);
继承我的完整代码:
package de.skysoldier.lwjgltest;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Hashtable;
import javax.imageio.ImageIO;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.util.glu.GLU;
public class Main {
private int shaderProgramID;
private int vertexArrayObjectID;
private int vertexBufferObjectID;
private int textureID;
private float vertices[];
public Main(){
initDisplay();
initTexture();
initShaders();
initGl();
startGameLoop();
}
private void initDisplay(){
try{
Display.setDisplayMode(new DisplayMode(800, 600));
Display.create();
}
catch(Exception e){
e.printStackTrace();
}
}
private void initTexture(){
ColorModel RGBA8_COLOR_MODEL = new ComponentColorModel(
ColorSpace.getInstance(ColorSpace.CS_sRGB),
new int[] { 8, 8, 8, 8 }, true, false,
ComponentColorModel.TRANSLUCENT, DataBuffer.TYPE_BYTE);
BufferedImage source = null;
try{
source = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pic.png"));
}
catch(Exception e){
}
IntBuffer textureBuffer = ByteBuffer.allocateDirect(4).asIntBuffer();
GL11.glGenTextures(textureBuffer);
WritableRaster raster;
BufferedImage textureImage;
int textureWidth = 2;
int textureHeight = 2;
while (textureWidth < source.getWidth())
textureWidth *= 2;
while (textureHeight < source.getHeight())
textureHeight *= 2;
textureID = textureBuffer.get();
raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, textureWidth, textureHeight, 4, null);
textureImage = new BufferedImage(RGBA8_COLOR_MODEL, raster, false, new Hashtable<String, Object>());
textureImage.getGraphics().drawImage(source, 0, 0, null);
byte[] data = (byte[]) textureImage.getRaster().getDataElements(0, 0,
textureImage.getWidth(), textureImage.getHeight(), null);
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(textureImage
.getColorModel().getPixelSize()
/ 8
* textureImage.getWidth()
* textureImage.getHeight());
byteBuffer.put(data);
byteBuffer.rewind();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, textureWidth,
textureHeight, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE,
byteBuffer);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
}
private void initShaders(){
String vertexShaderCode = readFile("test.vert");
String fragmentShaderCode = readFile("test.frag");
int vertexShaderID = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
GL20.glShaderSource(vertexShaderID, vertexShaderCode);
GL20.glCompileShader(vertexShaderID);
int fragmentShaderID = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
GL20.glShaderSource(fragmentShaderID, fragmentShaderCode);
GL20.glCompileShader(fragmentShaderID);
shaderProgramID = GL20.glCreateProgram();
GL20.glAttachShader(shaderProgramID, vertexShaderID);
GL20.glAttachShader(shaderProgramID, fragmentShaderID);
GL20.glLinkProgram(shaderProgramID);
int compileStatus = GL20.glGetShaderi(vertexShaderID, GL20.GL_COMPILE_STATUS);
if (compileStatus == GL11.GL_FALSE) {
int infoLogLength = GL20.glGetShaderi(vertexShaderID, GL20.GL_INFO_LOG_LENGTH);
String infoLog = GL20.glGetShaderInfoLog(vertexShaderID, infoLogLength);
throw new RuntimeException(infoLog);
}
}
private void initGl(){
vertices = new float[]{
// X Y Z U V
0.0f, 0.8f, 0.0f, 0.5f, 1.0f,
-0.8f,-0.8f, 0.0f, 0.0f, 0.0f,
0.8f,-0.8f, 0.0f, 1.0f, 0.0f,
};
FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
verticesBuffer.put(vertices);
verticesBuffer.flip();
vertexArrayObjectID = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vertexArrayObjectID);
vertexBufferObjectID = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vertexBufferObjectID);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(GL20.glGetAttribLocation(shaderProgramID, "vert"), 3, GL11.GL_FLOAT, false, Float.SIZE / 8, 0);
GL20.glEnableVertexAttribArray(GL20.glGetAttribLocation(shaderProgramID, "vertTexCoord"));
GL20.glVertexAttribPointer(GL20.glGetAttribLocation(shaderProgramID, "vertTexCoord"), 2, GL11.GL_FLOAT, true, Float.SIZE / 8, Float.SIZE / 8);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);
}
private void startGameLoop(){
while(!Display.isCloseRequested()){
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GL11.glClearColor(0.4f, 0.6f, 0.9f, 1);
GL20.glEnableVertexAttribArray(0);
GL30.glBindVertexArray(vertexArrayObjectID);
GL20.glUseProgram(shaderProgramID);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
GL20.glUniform1i(GL20.glGetUniformLocation(shaderProgramID, "tex"), GL13.GL_TEXTURE0);
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, vertices.length);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
Display.sync(60);
Display.update();
}
destroy();
}
private void destroy(){
GL20.glDisableVertexAttribArray(0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL15.glDeleteBuffers(vertexBufferObjectID);
GL30.glBindVertexArray(0);
GL30.glDeleteVertexArrays(vertexArrayObjectID);
Display.destroy();
}
public String readFile(String fileName){
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getClassLoader().getResourceAsStream(fileName)));
String content = "";
String line;
while((line = reader.readLine()) != null){
content += line + "\n";
}
return content;
}
catch(Exception e){
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
new Main();
}
}
以下是着色器:
片段
#version 150
uniform sampler2D tex;
in vec2 fragTexCoord;
out vec4 finalColor;
void main(void){
finalColor = texture(tex, fragTexCoord);
}
顶点
#version 120
attribute vec3 vert;
attribute vec2 vertTexCoord;
varying vec2 fragTexCoord;
void main() {
fragTexCoord = vertTexCoord;
gl_Position = vec4(vert, 1);
}
有人知道这个错误在哪里?
答案 0 :(得分:1)
GL20.glUniform1i(GL20.glGetUniformLocation(shaderProgramID, "tex"), GL13.GL_TEXTURE0);
纹理单位索引是制服,而不是GL枚举值。
尝试使用0
代替GL13.GL_TEXTURE0
。