绘制四边形时 OpenGL glColor3f(r, b, g) 改变整个地图的颜色
OpenGL glColor3f(r, b, g) while drawing Quads changes colour of whole map
我目前正在尝试制作游戏(Java、lwjgl、OpenGL),以便我可以基本了解自上而下的 RPG 游戏的工作原理(即在学习过程中)。最近,我尝试实现一个悬停在玩家精灵上方的生命条,但是当我尝试通过 Draw class 绘制它时,显示变得混乱,除了玩家之外几乎所有东西都变黑,而玩家精灵本身为传递给 Draw 方法的颜色(在 R、G、B 中)着色。
源代码:
玩家Class
package GameObjects;
import Graphics.ImageLoader;
import java.awt.Rectangle;
import java.util.ArrayList;
import static org.lwjgl.opengl.GL11.glPopMatrix;
import static org.lwjgl.opengl.GL11.glPushMatrix;
import org.newdawn.slick.opengl.Texture;
import rpgmain.*;
/**
*
* @author Samsung
*/
public class Player extends GameObject{
private float velX, velY;
private int curHealth, maxHealth;
private Texture tex;
public Player(float x, float y, ObjectId id) {
super(x, y, id);
velX = velY = 0;
curHealth = maxHealth = 100;
tex = ImageLoader.loadTexture("Player", "png");
}
protected void update(ArrayList<GameObject> objects) {
x += velX;
y += velY;
Collisions(objects);
}
protected void render() {
Draw.rect(x, y, 32, 32, tex);
dispHealth();
}
public void Collisions(ArrayList<GameObject> objects) {
for(GameObject obj : objects) {
if(obj.getId() == ObjectId.WaterTile) {
if(Collision.checkCollision(getBoundsTop(), obj.getBounds())) {
velX = velY = 0;
y = obj.getY() - 32;
}
if(Collision.checkCollision(getBoundsBottom(), obj.getBounds())) {
velX = velY = 0;
y = obj.getY() + 32;
}
if(Collision.checkCollision(getBoundsLeft(), obj.getBounds())) {
velX = velY = 0;
x = obj.getX() + 32;
}
if(Collision.checkCollision(getBoundsRight(), obj.getBounds())) {
velX = velY = 0;
x = obj.getX() - 32;
}
}
}
}
public void dispHealth() {
Draw.rect(x, y + 34, 10, 5, 1F, 0F, 0F); //THIS CODE TINTS THE PLAYER RED
}
public void setVelX(float velX) {
this.velX = velX;
}
public void setVelY(float velY) {
this.velY = velY;
}
public Rectangle getBounds() {
return new Rectangle((int)x, (int) y, 32, 32);
}
public Rectangle getBoundsTop() {
return new Rectangle((int)x + 7, (int) y + 26, 16, 6);
}
public Rectangle getBoundsBottom() {
return new Rectangle((int)x + 7, (int) y, 16, 6);
}
public Rectangle getBoundsLeft() {
return new Rectangle((int)x + 4, (int) y, 1, 32);
}
public Rectangle getBoundsRight() {
return new Rectangle((int)x + 31, (int) y, 1, 32);
}
public Rectangle getBoundsCentre() {
return new Rectangle((int)x + 20, (int) y, 4, 32);
}
}
绘制Class
package rpgmain;
import static org.lwjgl.opengl.GL11.*;
import org.newdawn.slick.opengl.*;
/**
*
* @author Samsung
*/
public class Draw {
public static void rect(float x, float y, float width, float height, Texture tex) {
glTranslatef(x, y, 0);
//glColor3f(1F, 1F, 1F);
glClearColor(0.7f, 0.7f, 0.7f, 1.0f);
tex.bind();
glBegin(GL_QUADS); //Specifies to the program where the drawing code begins. just to keep stuff neat. GL_QUADS specifies the type of shape you're going to be drawing.
{
//PNG format for images
glTexCoord2f(0,1); glVertex2f(0, 0); //Specify the vertices. 0, 0 is on BOTTOM LEFT CORNER OF SCREEN.
glTexCoord2f(0,0); glVertex2f(0, height); //2f specifies the number of args we're taking(2) and the type (float)
glTexCoord2f(1,0); glVertex2f(width, height);
glTexCoord2f(1,1); glVertex2f(width, 0);
}
glEnd();
}
public static void rect(float x, float y, float width, float height, Texture tex, float r, float g, float b) {
glTranslatef(x, y, 0);
glColor3f(r, g, b);
tex.bind();
glBegin(GL_QUADS); //Specifies to the program where the drawing code begins. just to keep stuff neat. GL_QUADS specifies the type of shape you're going to be drawing.
{
glTexCoord2f(0,0); glVertex2f(0, 0); //Specify the vertices. 0, 0 is on BOTTOM LEFT CORNER OF SCREEN.
glTexCoord2f(0,1); glVertex2f(0, height); //2f specifies the number of args we're taking(2) and the type (float)
glTexCoord2f(1,1); glVertex2f(width, height);
glTexCoord2f(1,0); glVertex2f(width, 0);
}
glEnd();
}
public static void rect(float x, float y, float width, float height, float r, float g, float b) {
glTranslatef(x, y, 0);
glColor3f(r, g, b); //Problem seems to be here
glBegin(GL_QUADS); //Specifies to the program where the drawing code begins. just to keep stuff neat. GL_QUADS specifies the type of shape you're going to be drawing.
{
glVertex2f(0, 0); //Specify the vertices. 0, 0 is on BOTTOM LEFT CORNER OF SCREEN.
glVertex2f(0, height); //2f specifies the number of args we're taking(2) and the type (float)
glVertex2f(width, height);
glVertex2f(width, 0);
}
glEnd();
}
}
我不知道是否也包括其他 classes,但我想我也会包括 GameObject class。
游戏对象Class
package rpgmain;
import java.awt.Rectangle;
import java.util.ArrayList;
/**
*
* @author Samsung
*/
public abstract class GameObject {
protected float x, y;
ObjectId id;
public GameObject(float x, float y, ObjectId id) {
this.x = x;
this.y = y;
this.id = id;
}
protected abstract void update(ArrayList<GameObject> objects);
protected abstract void render();
public abstract Rectangle getBounds();
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
public ObjectId getId() {
return id;
}
}
我明白了。我的代码有两个主要问题,在 Draw class.
中
- GL_TEXTURE_2D
每次我开始绘制一个普通的非纹理矩形时,我都会使用 glDisable(GL_Texture_2D) 禁用它,并在完成后启用它,并在纹理绘制方法中执行相反的操作(即在开始绘制之前启用,完成后禁用).这导致健康栏实际出现。
- glColor3f(r, g, b);
这是问题的实际问题。矩形最终为显示器上的每个纹理着色,因为我不知道 glColor3f 会影响您绘制的每个顶点。因此,为了解决这个问题,在绘制带纹理的 QUAD 之前,我首先将其颜色设置为白色(使用 glColor4f(1f, 1f, 1f, 1f);),然后一切都完美呈现。
变化:
public static void rect(float x, float y, float width, float height, Texture tex) {
glEnable(GL_TEXTURE_2D);
glTranslatef(x, y, 0);
glColor4f(1f, 1f, 1f, 1f); //NEEDS to be white before drawing, else stuff will tint.
tex.bind();
glBegin(GL_QUADS); //Specifies to the program where the drawing code begins. just to keep stuff neat. GL_QUADS specifies the type of shape you're going to be drawing.
{
//PNG format for images
glTexCoord2f(0,1); glVertex2f(0, 0); //Specify the vertices. 0, 0 is on BOTTOM LEFT CORNER OF SCREEN.
glTexCoord2f(0,0); glVertex2f(0, height); //2f specifies the number of args we're taking(2) and the type (float)
glTexCoord2f(1,0); glVertex2f(width, height);
glTexCoord2f(1,1); glVertex2f(width, 0);
}
glEnd();
glDisable(GL_TEXTURE_2D);
}
我目前正在尝试制作游戏(Java、lwjgl、OpenGL),以便我可以基本了解自上而下的 RPG 游戏的工作原理(即在学习过程中)。最近,我尝试实现一个悬停在玩家精灵上方的生命条,但是当我尝试通过 Draw class 绘制它时,显示变得混乱,除了玩家之外几乎所有东西都变黑,而玩家精灵本身为传递给 Draw 方法的颜色(在 R、G、B 中)着色。
源代码:
玩家Class
package GameObjects;
import Graphics.ImageLoader;
import java.awt.Rectangle;
import java.util.ArrayList;
import static org.lwjgl.opengl.GL11.glPopMatrix;
import static org.lwjgl.opengl.GL11.glPushMatrix;
import org.newdawn.slick.opengl.Texture;
import rpgmain.*;
/**
*
* @author Samsung
*/
public class Player extends GameObject{
private float velX, velY;
private int curHealth, maxHealth;
private Texture tex;
public Player(float x, float y, ObjectId id) {
super(x, y, id);
velX = velY = 0;
curHealth = maxHealth = 100;
tex = ImageLoader.loadTexture("Player", "png");
}
protected void update(ArrayList<GameObject> objects) {
x += velX;
y += velY;
Collisions(objects);
}
protected void render() {
Draw.rect(x, y, 32, 32, tex);
dispHealth();
}
public void Collisions(ArrayList<GameObject> objects) {
for(GameObject obj : objects) {
if(obj.getId() == ObjectId.WaterTile) {
if(Collision.checkCollision(getBoundsTop(), obj.getBounds())) {
velX = velY = 0;
y = obj.getY() - 32;
}
if(Collision.checkCollision(getBoundsBottom(), obj.getBounds())) {
velX = velY = 0;
y = obj.getY() + 32;
}
if(Collision.checkCollision(getBoundsLeft(), obj.getBounds())) {
velX = velY = 0;
x = obj.getX() + 32;
}
if(Collision.checkCollision(getBoundsRight(), obj.getBounds())) {
velX = velY = 0;
x = obj.getX() - 32;
}
}
}
}
public void dispHealth() {
Draw.rect(x, y + 34, 10, 5, 1F, 0F, 0F); //THIS CODE TINTS THE PLAYER RED
}
public void setVelX(float velX) {
this.velX = velX;
}
public void setVelY(float velY) {
this.velY = velY;
}
public Rectangle getBounds() {
return new Rectangle((int)x, (int) y, 32, 32);
}
public Rectangle getBoundsTop() {
return new Rectangle((int)x + 7, (int) y + 26, 16, 6);
}
public Rectangle getBoundsBottom() {
return new Rectangle((int)x + 7, (int) y, 16, 6);
}
public Rectangle getBoundsLeft() {
return new Rectangle((int)x + 4, (int) y, 1, 32);
}
public Rectangle getBoundsRight() {
return new Rectangle((int)x + 31, (int) y, 1, 32);
}
public Rectangle getBoundsCentre() {
return new Rectangle((int)x + 20, (int) y, 4, 32);
}
}
绘制Class
package rpgmain;
import static org.lwjgl.opengl.GL11.*;
import org.newdawn.slick.opengl.*;
/**
*
* @author Samsung
*/
public class Draw {
public static void rect(float x, float y, float width, float height, Texture tex) {
glTranslatef(x, y, 0);
//glColor3f(1F, 1F, 1F);
glClearColor(0.7f, 0.7f, 0.7f, 1.0f);
tex.bind();
glBegin(GL_QUADS); //Specifies to the program where the drawing code begins. just to keep stuff neat. GL_QUADS specifies the type of shape you're going to be drawing.
{
//PNG format for images
glTexCoord2f(0,1); glVertex2f(0, 0); //Specify the vertices. 0, 0 is on BOTTOM LEFT CORNER OF SCREEN.
glTexCoord2f(0,0); glVertex2f(0, height); //2f specifies the number of args we're taking(2) and the type (float)
glTexCoord2f(1,0); glVertex2f(width, height);
glTexCoord2f(1,1); glVertex2f(width, 0);
}
glEnd();
}
public static void rect(float x, float y, float width, float height, Texture tex, float r, float g, float b) {
glTranslatef(x, y, 0);
glColor3f(r, g, b);
tex.bind();
glBegin(GL_QUADS); //Specifies to the program where the drawing code begins. just to keep stuff neat. GL_QUADS specifies the type of shape you're going to be drawing.
{
glTexCoord2f(0,0); glVertex2f(0, 0); //Specify the vertices. 0, 0 is on BOTTOM LEFT CORNER OF SCREEN.
glTexCoord2f(0,1); glVertex2f(0, height); //2f specifies the number of args we're taking(2) and the type (float)
glTexCoord2f(1,1); glVertex2f(width, height);
glTexCoord2f(1,0); glVertex2f(width, 0);
}
glEnd();
}
public static void rect(float x, float y, float width, float height, float r, float g, float b) {
glTranslatef(x, y, 0);
glColor3f(r, g, b); //Problem seems to be here
glBegin(GL_QUADS); //Specifies to the program where the drawing code begins. just to keep stuff neat. GL_QUADS specifies the type of shape you're going to be drawing.
{
glVertex2f(0, 0); //Specify the vertices. 0, 0 is on BOTTOM LEFT CORNER OF SCREEN.
glVertex2f(0, height); //2f specifies the number of args we're taking(2) and the type (float)
glVertex2f(width, height);
glVertex2f(width, 0);
}
glEnd();
}
}
我不知道是否也包括其他 classes,但我想我也会包括 GameObject class。
游戏对象Class
package rpgmain;
import java.awt.Rectangle;
import java.util.ArrayList;
/**
*
* @author Samsung
*/
public abstract class GameObject {
protected float x, y;
ObjectId id;
public GameObject(float x, float y, ObjectId id) {
this.x = x;
this.y = y;
this.id = id;
}
protected abstract void update(ArrayList<GameObject> objects);
protected abstract void render();
public abstract Rectangle getBounds();
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
public ObjectId getId() {
return id;
}
}
我明白了。我的代码有两个主要问题,在 Draw class.
中- GL_TEXTURE_2D 每次我开始绘制一个普通的非纹理矩形时,我都会使用 glDisable(GL_Texture_2D) 禁用它,并在完成后启用它,并在纹理绘制方法中执行相反的操作(即在开始绘制之前启用,完成后禁用).这导致健康栏实际出现。
- glColor3f(r, g, b); 这是问题的实际问题。矩形最终为显示器上的每个纹理着色,因为我不知道 glColor3f 会影响您绘制的每个顶点。因此,为了解决这个问题,在绘制带纹理的 QUAD 之前,我首先将其颜色设置为白色(使用 glColor4f(1f, 1f, 1f, 1f);),然后一切都完美呈现。
变化:
public static void rect(float x, float y, float width, float height, Texture tex) {
glEnable(GL_TEXTURE_2D);
glTranslatef(x, y, 0);
glColor4f(1f, 1f, 1f, 1f); //NEEDS to be white before drawing, else stuff will tint.
tex.bind();
glBegin(GL_QUADS); //Specifies to the program where the drawing code begins. just to keep stuff neat. GL_QUADS specifies the type of shape you're going to be drawing.
{
//PNG format for images
glTexCoord2f(0,1); glVertex2f(0, 0); //Specify the vertices. 0, 0 is on BOTTOM LEFT CORNER OF SCREEN.
glTexCoord2f(0,0); glVertex2f(0, height); //2f specifies the number of args we're taking(2) and the type (float)
glTexCoord2f(1,0); glVertex2f(width, height);
glTexCoord2f(1,1); glVertex2f(width, 0);
}
glEnd();
glDisable(GL_TEXTURE_2D);
}