Jump to content
  • Advertisement

First Person Shooters and Similar Games on Mobile Platform

Recommended Posts

Posted (edited)

I've been considering making a small mobile game that would essentially be a turn based FPS experience on a mobile platform. I went turn based since I realized that FPS on a mobile platform doesn't really work perfectly. But I'm curious though: have people gotten an FPS-like experience to work on the mobile platform? If so, what sort of mechanics did they use and how were the controls modified and/or implemented to successfully create these experiences?

And another question: are FPS-like experiences popular in the mobile space? I'm not very well versed in mobile gaming, and am making a game on the mobile platform for fun but also do want to create a fun experience. 

Thanks in advance for your help!

(Also mods, feel free to move this if I'm in the wrong forum)

Edited by deltaKshatriya

Share this post


Link to post
Share on other sites
Advertisement

I've seen quite a few on Android, Modern Combat and NOVA both have a number of games in their series, but I've always found the controls awkward.  Typically what I've seen is a virtual stick on one side for movement, then drag a finger across the screen to look and aim.

The other popular style of mobile FPS is the on rails shooter where you just have to aim and shoot.  Some of these have a stick, some you just tap on the target.

I think your idea of a turn based FPS would be an interesting take.  I love seeing things that are different, so I say it would be worth looking into.

 

 

Share this post


Link to post
Share on other sites

Phones tend to be more casual and play sessions tend to be shorter and more easily interrupted, which makes FPS a less common fit.  There are some FPS games and some games where longer gameplay is possible, but they're less common. As you mention, control is more difficult.

While it is more RPG than FPS, there have been many games with an overhead camera that have proven extremely popular on the platform. Infinity blade was incredibly popular, and these days Fortnite (and to a lesser extent, PUBG) tops of the charts. Lots of combat that plays well on the devices.

Historically the best mobile games are easily approachable and easily interrupted.  The ever-popular Angry Birds is a great example, a single action takes about 5 seconds. Many card games, puzzle games, and trivia games follow the same pattern of being easily interruptible from moment to moment. If you browse through the top ten games at any time over the last decade, nearly all of them have followed the same pattern; they're games you can pick up and set down at a moment's notice. FPS games occasionally make that list, but they're relatively uncommon as they require significant time and attention from the player, in addition to concerns over battery life and device temperature.

Share this post


Link to post
Share on other sites

A few months ago I wouldn't have thought mobile FPS was a big market... But now PUBG mobile has something like 20M installs and 3c ARPU, and Fortnite Mobile has something like 4M installs and $1 ARPU (and both are on the way up, still - e.g. Fortnite hasn't even launched on Android yet!) 

Share this post


Link to post
Share on other sites
On 5/12/2018 at 9:54 PM, frob said:

Historically the best mobile games are easily approachable and easily interrupted.  The ever-popular Angry Birds is a great example, a single action takes about 5 seconds. Many card games, puzzle games, and trivia games follow the same pattern of being easily interruptible from moment to moment. If you browse through the top ten games at any time over the last decade, nearly all of them have followed the same pattern; they're games you can pick up and set down at a moment's notice. FPS games occasionally make that list, but they're relatively uncommon as they require significant time and attention from the player, in addition to concerns over battery life and device temperature.

I was thinking that the turn based aspect to the FPS game would make it something easy to put down actually. So it wouldn't be a straight up FPS, but rather you take turns, so in theory, it'd compensate for the 'put down' factor. Also, the controls I was gonna fix with a fire mode and a movement mode which you switch in and out of in order to make the whole translation from console/PC to mobile easier. Not sure if it'll work or not but it's worth a shot.

On 5/13/2018 at 2:27 AM, Hodgman said:

A few months ago I wouldn't have thought mobile FPS was a big market... But now PUBG mobile has something like 20M installs and 3c ARPU, and Fortnite Mobile has something like 4M installs and $1 ARPU (and both are on the way up, still - e.g. Fortnite hasn't even launched on Android yet!) 

I didn't know that FPS is doing well on mobile. Are they just traditional FPS games or have they switched up the control schemes? The control scheme implementation seems the biggest hurdle to a successful FPS game.

Share this post


Link to post
Share on other sites

There are aspects of FPS and turn based games that make them feel like they should be mutually exclusive. Turn based games, for instance, really require teams of players, other wise the pace is a little too short, and you need the team tactical element to make up for that. Similarly, an fps gives you a limited viewport, which mitigates the range of tactical decisions.

One idea that I thought could work is if you worked integrated the fps role as part of a team. As an example:

Imagine playing the role of a long range sniper. You have, through your scope, a view of the battleground (say an enemy compound). You can see everything, the enemy soldiers, the objective, and your own team positioning themselves at the compound entry points.

The turns alternate between the sniper (you) and every one else (who is AI controlled). In this game, your turn would be looking over the battleground and choosing one target to eliminate. Once your shot has been taken, the game moves forward one step. Your team infiltrates one time unit, and the enemy responds. This would be in realtime, rather than turn based. So you act, everyone else acts.

You could even expand it with a tactical planning phase, where you set waypoints for your team on go-codes (like the original rainbow six games). 

As a gross over simplification. You shoot one guard, your team infiltrates the first room, and encounters a group of enemies, the game pauses. You shoot one enemy, your team opens fire and the enemy reacts, the game pauses... and so on.

You could also incorporate some semi-fixed movement in to the game. So, instead of taking a shot this turn, you opt to move from your current position (rooftop A) to another position (rooftop B).

I think that could work pretty well...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
  • Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By mapmip
      Hi, I am fresh to database design, recently trying building my mobile multiplayer game, it will be something like pokemonGo.
      I have experience on MySQL, and I know some NoSQL engines like redis.
      I saw some existing game projects which store their data on both SQL database and noSQL database.
      Could anyone give some advice that what kind of data should store in SQL and what kind of data is better to be in noSQL.
      It would be nice if giving some real scenario examples.
      My understanding is data like user profile, purchase transactions should be in SQL.
      Field map information, enemy status can be NoSQL.  
    • By Final Flames
      Hi everyone I am newbie got some ideas , but don't know how the whole things work out .
       I want to learn how things work with a developer from start to finish.
      So ideally looking to team up with android developer to complete some simple fun games.
      So either reply me here or mail at palani650@gmail.com 
    • By Dr. Michael Garbade
      Are you considering developing a mobile game? If you want to be successful, you should avoid making the most common mistakes. Trying to build a game without figuring out the right approach is a recipe for disaster.
      There are experienced developers like MyIsaak from Sweden, an expert in C# and Unity game development who frequently livestreams his Diablo III Board game development process.
      The more you learn from professionals like him, who have gone through the processes, the faster you can avoid making the common game development mistakes.

      Here are the top 5 game developments mistakes to avoid.
      1. Ignoring the target group
      Creating a game without properly studying your target group is a huge barrier that will keep it from being downloaded and played.
      Who are you building the game for? What are their main interests? What activities do they like participating in? Can the target group afford the gaming app? Does your target audience use iOS or Android operating system?
      Seeking answers to the above questions and others can assist in correctly identifying your target group. Consequently, you can design its functionalities around their preferences.
      Just like an ice cream vendor is likely to set up shop at the beach during summer, you should focus on consumers whose behaviors are likely to motivate them to play your game.
      For example, if you want to create a gun shooting game, you can target college-educated men in their 20s and 30s, while targeting other demographic groups secondarily.
      2. Failure to study the competitors
      To create a successful game that will increase positive reviews and retention, you should analyze the strengths and weaknesses of your competitors.
      Studying your competition will allow you to understand your capabilities to match or surpass the consumer demand for your mobile or web-based game.
      If you fail to do it, you will miss the opportunity to fill the actual needs in the gaming industry and correct the mistakes made by the developers in your niche.
      You should ask questions like “What is their target audience?” “How many downloads do their gaming app receive per month?” “What resources do they have?”.
      Answering such questions will give you a good idea of the abilities of your competition, the feasibility of competing with them, and the kind of strategies to adopt to out-compete them.
      Importantly, instead of copying the strategies of your competitors, develop a game that is unique and provides an added value to users.
      3.  Design failure
      When building a mobile or a web-based game, it’s essential that you employ a unique art style and visually appealing design—without any unnecessary sophistication. People are attracted to games based on the user interface design and intuitiveness.
      So, instead of spending a lot of time trying to write elegant and complicated lines of code, take your time to provide a better design.
      No one will download a game because its code is beautiful. People download games to play them. And, the design of the game plays a critical part in assisting them to make the download decision.
      4. Trying to do everything
      If you try to code, develop 3D models, create animations, do voice-overs—all by yourself—then you are likely to create an unsuccessful game.
      The secret to succeeding is to complete tasks that align with your core competencies and outsource the rest of the work. Learn how to divide your work to other experts and save yourself the headaches.
      You should also avoid trying to reinvent the wheel. Instead of trying to do everything by yourself, go for robust tools available out there that can make your life easier.
      Trying to build something that is already provided in the open source community will consume a lot of your development time and make you feel frustrated.
      Furthermore, do not be the beta tester of your own game. If you request someone else to do the beta testing, you’ll get useful outside perspective that will assist in discovering some hidden issues.
      5. Having unrealistic expectations
      Unrealistic expectations are very dangerous because they set your game development career up for failure. Do not put your expectations so high such that you force somethings to work your way.
      For example, dreaming too big can make you include too many rewards in your game. As much as rewards are pivotal for improving engagement and keeping users motivated, gamers will not take you seriously if you incorporate rewards in every little achievement they make.
      Instead, you should select specific rewards for specific checkpoints; this way, the players will feel that they’ve made major milestones.
      Conclusion
      The mistakes discussed in this article have made several game developers to be unsuccessful in their careers. So, be cautious and keep your head high so that you don’t fall into the same trap.
      The best way to avoid making the common mistakes is through learning how to build games from the experts.
      Who knows? You could develop the next big game in the industry.
    • By Stormnoob
      Hello everybody! Who is not difficult to evaluate / download my games)
      Play Market - https://play.google.com/store/apps/developer?id=Storm+Arts
      Thanks in advance!?
    • By Psychopathetica
      Not long ago, I create a nice OBJ loader that loads 3D Studio Max files. Only problem is, is that although it works and works great, I wasn't using Vertex Buffers. Now that I applied Vertex Buffers, it seems to only use the first color of the texture and spread it all across the poiygon. I examined my code over and over again, and the Vertex Buffer code is correct. But when I comment out all of my vertex buffer code, it works as intended. I practically given up on fixing it on my own, so hopefully you guys will be able to figure out what is wrong.
      public static final int BYTES_PER_FLOAT = 4; public static final int POSITION_COMPONENT_COUNT_3D = 4; public static final int COLOR_COMPONENT_COUNT = 4; public static final int TEXTURE_COORDINATES_COMPONENT_COUNT = 2; public static final int NORMAL_COMPONENT_COUNT = 3; public static final int POSITION_COMPONENT_STRIDE_2D = POSITION_COMPONENT_COUNT_2D * BYTES_PER_FLOAT; public static final int POSITION_COMPONENT_STRIDE_3D = POSITION_COMPONENT_COUNT_3D * BYTES_PER_FLOAT; public static final int COLOR_COMPONENT_STRIDE = COLOR_COMPONENT_COUNT * BYTES_PER_FLOAT; public static final int TEXTURE_COORDINATE_COMPONENT_STRIDE = TEXTURE_COORDINATES_COMPONENT_COUNT * BYTES_PER_FLOAT; public static final int NORMAL_COMPONENT_STRIDE = NORMAL_COMPONENT_COUNT * BYTES_PER_FLOAT; int loadFile() { ArrayList<Vertex3D> tempVertexArrayList = new ArrayList<Vertex3D>(); ArrayList<TextureCoord2D> tempTextureCoordArrayList = new ArrayList<TextureCoord2D>(); ArrayList<Vector3D> tempNormalArrayList = new ArrayList<Vector3D>(); ArrayList<Face3D> tempFaceArrayList = new ArrayList<Face3D>(); StringBuilder body = new StringBuilder(); try { InputStream inputStream = context.getResources().openRawResource(resourceID); InputStreamReader inputStreamReader = new InputStreamReader(inputStream); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String nextLine; String subString; String[] stringArray; String[] stringArray2; int[] indexNumberList = new int[3]; int[] textureCoordNumberList = new int[3]; int[] normalNumberList = new int[3]; int i = 0; int j = 0; int k = 0; try { while ((nextLine = bufferedReader.readLine()) != null) { if (nextLine.startsWith("v ")) { subString = nextLine.substring(1).trim(); stringArray = subString.split(" "); try { tempVertexArrayList.add(new Vertex3D(Float.parseFloat(stringArray[0]), Float.parseFloat(stringArray[1]), Float.parseFloat(stringArray[2]), 1f)); } catch(NumberFormatException e){ Log.d(TAG, "Error: Invalid number format in loading vertex list"); return 0; } String x = String.valueOf(tempVertexArrayList.get(i).x); String y = String.valueOf(tempVertexArrayList.get(i).y); String z = String.valueOf(tempVertexArrayList.get(i).z); //Log.d(TAG, "vertex " + String.valueOf(i) + ": " + x + ", " + y + ", " + z); i++; } if (nextLine.startsWith("vn ")) { subString = nextLine.substring(2).trim(); stringArray = subString.split(" "); try { if(reverseNormals){ tempNormalArrayList.add(new Vector3D(-Float.parseFloat(stringArray[0]), -Float.parseFloat(stringArray[1]), -Float.parseFloat(stringArray[2]))); } else{ tempNormalArrayList.add(new Vector3D(Float.parseFloat(stringArray[0]), Float.parseFloat(stringArray[1]), Float.parseFloat(stringArray[2]))); } } catch(NumberFormatException e){ Log.d(TAG, "Error: Invalid number format in loading normal list"); return 0; } String nx = String.valueOf(tempNormalArrayList.get(j).x); String ny = String.valueOf(tempNormalArrayList.get(j).y); String nz = String.valueOf(tempNormalArrayList.get(j).z); //Log.d(TAG, "normal " + String.valueOf(j) + ": " + nx + ", " + ny + ", " + nz); j++; } if (nextLine.startsWith("vt ")) { subString = nextLine.substring(2).trim(); stringArray = subString.split(" "); try { tempTextureCoordArrayList.add(new TextureCoord2D(Float.parseFloat(stringArray[0]), Float.parseFloat(stringArray[1]))); } catch(NumberFormatException e){ Log.d(TAG, "Error: Invalid number format in loading texture coordinate list"); return 0; } String tu = String.valueOf(tempTextureCoordArrayList.get(k).tu); String tv = String.valueOf(tempTextureCoordArrayList.get(k).tv); //Log.d(TAG, "texture coord " + String.valueOf(k) + ": " + tu + ", " + tv); k++; } if (nextLine.startsWith("f ")) { subString = nextLine.substring(1).trim(); stringArray = subString.split(" "); for (int index = 0; index <= 2; index++) { stringArray2 = stringArray[index].split("/"); try { indexNumberList[index] = Integer.parseInt(stringArray2[0]) - 1; if(indexNumberList[index] < 0){ Log.d(TAG, "Error: indexNumberList[] is less than zero"); return 0; } } catch(NumberFormatException e){ Log.d(TAG, "Error: Invalid number format in loading indexNumberList[]"); return 0; } try{ textureCoordNumberList[index] = Integer.parseInt(stringArray2[1]) - 1; if(textureCoordNumberList[index] < 0){ Log.d(TAG, "Error: textureCoordNumberList[] is less than zero"); return 0; } } catch(NumberFormatException e){ Log.d(TAG, "Error: Invalid number format in loading textureCoordNumberList[]"); return 0; } try{ normalNumberList[index] = Integer.parseInt(stringArray2[2]) - 1; if(normalNumberList[index] < 0){ Log.d(TAG, "Error: normalNumberList[] is less than zero"); return 0; } } catch(NumberFormatException e){ Log.d(TAG, "Error: Invalid number format in loading normalNumberList[]"); return 0; } } tempFaceArrayList.add(new Face3D(indexNumberList[0], textureCoordNumberList[0], normalNumberList[0], indexNumberList[1], textureCoordNumberList[1], normalNumberList[1], indexNumberList[2], textureCoordNumberList[2], normalNumberList[2])); } body.append(nextLine); body.append('\n'); } //Now that everything has successfully loaded, you can now populate the public variables. if(tempVertexArrayList != null && tempVertexArrayList.size() != 0) vertexArrayList.addAll(tempVertexArrayList); if(tempTextureCoordArrayList != null && tempTextureCoordArrayList.size() != 0) textureCoordArrayList.addAll(tempTextureCoordArrayList); if(tempNormalArrayList != null && tempNormalArrayList.size() != 0) normalArrayList.addAll(tempNormalArrayList); if(tempFaceArrayList != null && tempFaceArrayList.size() != 0) faceArrayList.addAll(tempFaceArrayList); vertexList = new float[faceArrayList.size() * POSITION_COMPONENT_COUNT_3D * NUMBER_OF_SIDES_PER_FACE]; indexList = new short[faceArrayList.size() * NUMBER_OF_SIDES_PER_FACE]; colorList = new float[faceArrayList.size() * COLOR_COMPONENT_COUNT * NUMBER_OF_SIDES_PER_FACE]; textureCoordList = new float[faceArrayList.size() * TEXTURE_COORDINATES_COMPONENT_COUNT * NUMBER_OF_SIDES_PER_FACE]; normalList = new float[faceArrayList.size() * NORMAL_COMPONENT_COUNT * NUMBER_OF_SIDES_PER_FACE]; int nextFace = 0; int step = POSITION_COMPONENT_COUNT_3D * NUMBER_OF_SIDES_PER_FACE; for (int currentVertex = 0; currentVertex < vertexList.length; currentVertex += step){ vertexList[currentVertex + 0] = vertexArrayList.get(faceArrayList.get(nextFace).indexNumberList.get(0)).x; vertexList[currentVertex + 1] = vertexArrayList.get(faceArrayList.get(nextFace).indexNumberList.get(0)).y; vertexList[currentVertex + 2] = vertexArrayList.get(faceArrayList.get(nextFace).indexNumberList.get(0)).z; vertexList[currentVertex + 3] = vertexArrayList.get(faceArrayList.get(nextFace).indexNumberList.get(0)).w; vertexList[currentVertex + 4] = vertexArrayList.get(faceArrayList.get(nextFace).indexNumberList.get(1)).x; vertexList[currentVertex + 5] = vertexArrayList.get(faceArrayList.get(nextFace).indexNumberList.get(1)).y; vertexList[currentVertex + 6] = vertexArrayList.get(faceArrayList.get(nextFace).indexNumberList.get(1)).z; vertexList[currentVertex + 7] = vertexArrayList.get(faceArrayList.get(nextFace).indexNumberList.get(1)).w; vertexList[currentVertex + 8] = vertexArrayList.get(faceArrayList.get(nextFace).indexNumberList.get(2)).x; vertexList[currentVertex + 9] = vertexArrayList.get(faceArrayList.get(nextFace).indexNumberList.get(2)).y; vertexList[currentVertex + 10] = vertexArrayList.get(faceArrayList.get(nextFace).indexNumberList.get(2)).z; vertexList[currentVertex + 11] = vertexArrayList.get(faceArrayList.get(nextFace).indexNumberList.get(2)).w; nextFace++; } numberOfVertices = vertexList.length / POSITION_COMPONENT_COUNT_3D; nextFace = 0; for (int currentIndex = 0; currentIndex < indexList.length; currentIndex += NUMBER_OF_SIDES_PER_FACE){ indexList[currentIndex + 0] = faceArrayList.get(nextFace).indexNumberList.get(0).shortValue(); indexList[currentIndex + 1] = faceArrayList.get(nextFace).indexNumberList.get(1).shortValue(); indexList[currentIndex + 2] = faceArrayList.get(nextFace).indexNumberList.get(2).shortValue(); } step = COLOR_COMPONENT_COUNT * NUMBER_OF_SIDES_PER_FACE; for (int currentVertex = 0; currentVertex < colorList.length; currentVertex += step){ colorList[currentVertex + 0] = red; colorList[currentVertex + 1] = green; colorList[currentVertex + 2] = blue; colorList[currentVertex + 3] = alpha; colorList[currentVertex + 4] = red; colorList[currentVertex + 5] = green; colorList[currentVertex + 6] = blue; colorList[currentVertex + 7] = alpha; colorList[currentVertex + 8] = red; colorList[currentVertex + 9] = green; colorList[currentVertex + 10] = blue; colorList[currentVertex + 11] = alpha; } nextFace = 0; step = TEXTURE_COORDINATES_COMPONENT_COUNT * NUMBER_OF_SIDES_PER_FACE; for (int currentVertex = 0; currentVertex < textureCoordList.length; currentVertex += step){ textureCoordList[currentVertex + 0] = textureCoordArrayList.get(faceArrayList.get(nextFace).textureCoordNumberList.get(0)).tu * mult; textureCoordList[currentVertex + 1] = textureCoordArrayList.get(faceArrayList.get(nextFace).textureCoordNumberList.get(0)).tv * mult; textureCoordList[currentVertex + 2] = textureCoordArrayList.get(faceArrayList.get(nextFace).textureCoordNumberList.get(1)).tu * mult; textureCoordList[currentVertex + 3] = textureCoordArrayList.get(faceArrayList.get(nextFace).textureCoordNumberList.get(1)).tv * mult; textureCoordList[currentVertex + 4] = textureCoordArrayList.get(faceArrayList.get(nextFace).textureCoordNumberList.get(2)).tu * mult; textureCoordList[currentVertex + 5] = textureCoordArrayList.get(faceArrayList.get(nextFace).textureCoordNumberList.get(2)).tv * mult; nextFace++; } nextFace = 0; step = NORMAL_COMPONENT_COUNT * NUMBER_OF_SIDES_PER_FACE; for (int currentVertex = 0; currentVertex < normalList.length; currentVertex += step){ normalList[currentVertex + 0] = normalArrayList.get(faceArrayList.get(nextFace).normalNumberList.get(0)).x; normalList[currentVertex + 1] = normalArrayList.get(faceArrayList.get(nextFace).normalNumberList.get(0)).y; normalList[currentVertex + 2] = normalArrayList.get(faceArrayList.get(nextFace).normalNumberList.get(0)).z; normalList[currentVertex + 3] = normalArrayList.get(faceArrayList.get(nextFace).normalNumberList.get(1)).x; normalList[currentVertex + 4] = normalArrayList.get(faceArrayList.get(nextFace).normalNumberList.get(1)).y; normalList[currentVertex + 5] = normalArrayList.get(faceArrayList.get(nextFace).normalNumberList.get(1)).z; normalList[currentVertex + 6] = normalArrayList.get(faceArrayList.get(nextFace).normalNumberList.get(2)).x; normalList[currentVertex + 7] = normalArrayList.get(faceArrayList.get(nextFace).normalNumberList.get(2)).y; normalList[currentVertex + 8] = normalArrayList.get(faceArrayList.get(nextFace).normalNumberList.get(2)).z; nextFace++; } vertexBuffer = ByteBuffer.allocateDirect(vertexList.length * BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer(); indexBuffer = ByteBuffer.allocateDirect(indexList.length * BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asShortBuffer(); colorBuffer = ByteBuffer.allocateDirect(colorList.length * BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer(); textureCoordBuffer = ByteBuffer.allocateDirect(textureCoordList.length * BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer(); normalBuffer = ByteBuffer.allocateDirect(normalList.length * BYTES_PER_FLOAT).order(ByteOrder.nativeOrder()).asFloatBuffer(); vertexBuffer.put(vertexList).position(0); indexBuffer.put(indexList).position(0); colorBuffer.put(colorList).position(0); textureCoordBuffer.put(textureCoordList).position(0); normalBuffer.put(normalList).position(0); createVertexBuffer(); uMVPMatrixHandle = glGetUniformLocation(program, U_MVPMATRIX); uMVMatrixHandle = glGetUniformLocation(program, U_MVMATRIX); uTextureUnitHandle = glGetUniformLocation(program, U_TEXTURE_UNIT); aPositionHandle = glGetAttribLocation(program, A_POSITION); aColorHandle = glGetAttribLocation(program, A_COLOR); aTextureCoordinateHandle = glGetAttribLocation(program, A_TEXTURE_COORDINATES); aNormalHandle = glGetAttribLocation(program, A_NORMAL); glEnableVertexAttribArray(aPositionHandle); glEnableVertexAttribArray(aColorHandle); glEnableVertexAttribArray(aTextureCoordinateHandle); glEnableVertexAttribArray(aNormalHandle); glActiveTexture(GL_TEXTURE0); glUniform1i(uTextureUnitHandle, 0); } catch(IOException e){ } } catch (Resources.NotFoundException nfe){ throw new RuntimeException("Resource not found: " + resourceID, nfe); } return 1; } public void draw(){ glEnable(GL_DEPTH_TEST); bindData(); glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject[0]); glDrawArrays(GL_TRIANGLES, 0, faceArrayList.size() * NUMBER_OF_SIDES_PER_FACE); glBindBuffer(GL_ARRAY_BUFFER, 0); } public void bindData(){ int offset = 0; glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject[0]); glVertexAttribPointer(aPositionHandle, POSITION_COMPONENT_COUNT_3D, GL_FLOAT, false, POSITION_COMPONENT_STRIDE_3D, offset); offset += POSITION_COMPONENT_COUNT_3D; glVertexAttribPointer(aColorHandle, COLOR_COMPONENT_COUNT, GL_FLOAT, false, COLOR_COMPONENT_STRIDE, numberOfVertices * offset * BYTES_PER_FLOAT); offset += COLOR_COMPONENT_COUNT; glVertexAttribPointer(aTextureCoordinateHandle, TEXTURE_COORDINATES_COMPONENT_COUNT, GL_FLOAT, false, TEXTURE_COORDINATE_COMPONENT_STRIDE, numberOfVertices * offset * BYTES_PER_FLOAT); offset += TEXTURE_COORDINATES_COMPONENT_COUNT; glVertexAttribPointer(aNormalHandle, NORMAL_COMPONENT_COUNT, GL_FLOAT, false, NORMAL_COMPONENT_STRIDE, numberOfVertices * offset * BYTES_PER_FLOAT); glBindBuffer(GL_ARRAY_BUFFER, 0); ///////////////////////////////////////////////////// /* vertexBuffer.position(0); glVertexAttribPointer(aPositionHandle, POSITION_COMPONENT_COUNT_3D, GL_FLOAT, false, POSITION_COMPONENT_STRIDE_3D, vertexBuffer); colorBuffer.position(0); glVertexAttribPointer(aColorHandle, COLOR_COMPONENT_COUNT, GL_FLOAT, false, COLOR_COMPONENT_STRIDE, colorBuffer); textureCoordBuffer.position(0); glVertexAttribPointer(aTextureCoordinateHandle, TEXTURE_COORDINATES_COMPONENT_COUNT, GL_FLOAT, false, TEXTURE_COORDINATE_COMPONENT_STRIDE, textureCoordBuffer); normalBuffer.position(0); glVertexAttribPointer(aNormalHandle, NORMAL_COMPONENT_COUNT, GL_FLOAT, false, NORMAL_COMPONENT_STRIDE, normalBuffer); */ } public void createVertexBuffer(){ glGenBuffers(1, vertexBufferObject, 0); glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject[0]); glBufferData(GL_ARRAY_BUFFER,numberOfVertices * (POSITION_COMPONENT_COUNT_3D + COLOR_COMPONENT_COUNT + TEXTURE_COORDINATES_COMPONENT_COUNT + NORMAL_COMPONENT_COUNT) * BYTES_PER_FLOAT, null, GL_STATIC_DRAW); int offset = 0; glBufferSubData(GL_ARRAY_BUFFER, offset, numberOfVertices * POSITION_COMPONENT_COUNT_3D * BYTES_PER_FLOAT, vertexBuffer); offset += POSITION_COMPONENT_COUNT_3D; glBufferSubData(GL_ARRAY_BUFFER, numberOfVertices * offset * BYTES_PER_FLOAT, numberOfVertices * COLOR_COMPONENT_COUNT * BYTES_PER_FLOAT, colorBuffer); offset += COLOR_COMPONENT_COUNT; glBufferSubData(GL_ARRAY_BUFFER, numberOfVertices * offset * BYTES_PER_FLOAT, numberOfVertices * TEXTURE_COORDINATES_COMPONENT_COUNT * BYTES_PER_FLOAT, textureCoordBuffer); offset += TEXTURE_COORDINATES_COMPONENT_COUNT; glBufferSubData(GL_ARRAY_BUFFER, numberOfVertices * offset * BYTES_PER_FLOAT, numberOfVertices * NORMAL_COMPONENT_COUNT * BYTES_PER_FLOAT, normalBuffer); glBindBuffer(GL_ARRAY_BUFFER, 0); }  
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!